|
Message
From: cvs at opencores.org<cvs@o...>
Date: Wed Mar 28 23:30:27 CEST 2007
Subject: [cvs-checkins] MODIFIED: openfire2 ...
Date: 00/07/03 28:23:30 Added: openfire2/rtl bbfifo_16x8.v kcuart_rx.v kcuart_tx.v openfire_arbitrer.v openfire_cpu.v openfire_debug.v openfire_decode.v openfire_define.v openfire_execute.v openfire_fetch.v openfire_iospace.v openfire_pipeline_ctrl.v openfire_primitives.v openfire_regfile.v openfire_soc.v openfire_template_bootram.v prom_reader.v prom_reader_clock_mgmt.v prom_reader_my_lut2.v prom_reader_shift_cmp_serial.v sim_sram256kx16.v sp3_devboard.ucf sp3dk_simulator.v sram_wrapper.v uart_rx.v uart_tx.v vga_controlador.v vga_parts.v Log: Revision Changes Path 1.1 openfire2/rtl/bbfifo_16x8.v http://www.opencores.org/cvsweb.shtml/openfire2/rtl/bbfifo_16x8.v?rev=1.1&content-type=text/x-cvsweb-markup Index: bbfifo_16x8.v =================================================================== //////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2004 Xilinx, Inc. // All Rights Reserved //////////////////////////////////////////////////////////////////////////////// // ____ ____ // / /\/ / // /___/ \ / Vendor: Xilinx // \ \ \/ Version: 1.01 // \ \ Filename: bbfifo_16x8.v // / / Date Last Modified: 08/04/2004 // /___/ /\ Date Created: 10/14/2002 // \ \ / \ // \___\/\___\ // //Device: Xilinx //Purpose: // 'Bucket Brigade' FIFO // 16 deep // 8-bit data //Reference: // None //Revision History: // Rev 1.00 - kc - Start of design entry in VHDL, 10/14/2002. // Rev 1.01 - sus - Converted to verilog, 08/04/2004. // Rev 1.02 - njs - Synplicity attributes added, 09/06/2004. // Rev 1.03 - njs - defparam values corrected, 12/01/2005. //////////////////////////////////////////////////////////////////////////////// // Contact: e-mail picoblaze@x... ////////////////////////////////////////////////////////////////////////////////// // // Disclaimer: // LIMITED WARRANTY AND DISCLAIMER. These designs are // provided to you "as is". Xilinx and its licensors make and you // receive no warranties or conditions, express, implied, // statutory or otherwise, and Xilinx specifically disclaims any // implied warranties of merchantability, non-infringement, or // fitness for a particular purpose. Xilinx does not warrant that // the functions contained in these designs will meet your // requirements, or that the operation of these designs will be // uninterrupted or error free, or that defects in the Designs // will be corrected. Furthermore, Xilinx does not warrant or // make any representations regarding use or the results of the // use of the designs in terms of correctness, accuracy, // reliability, or otherwise. // // LIMITATION OF LIABILITY. In no event will Xilinx or its // licensors be liable for any loss of data, lost profits, cost // or procurement of substitute goods or services, or for any // special, incidental, consequential, or indirect damages // arising from the use or operation of the designs or // accompanying documentation, however caused and on any theory // of liability. This limitation will apply even if Xilinx // has been advised of the possibility of such damage. This // limitation shall apply not-withstanding the failure of the // essential purpose of any limited remedies herein. ////////////////////////////////////////////////////////////////////////////////// `timescale 1 ps / 1ps module bbfifo_16x8 (data_in, data_out, reset, write, read, full, half_full, data_present, clk); input [7:0] data_in; output [7:0] data_out; input reset; input write; input read; output full; output half_full; output data_present;
input clk;
////////////////////////////////////////////////////////////////////////////////////
//
// Start of BBFIFO_16x8
//
//
////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////
//
// wires used in BBFIFO_16x8
//
////////////////////////////////////////////////////////////////////////////////////
wire [3:0] pointer;
wire [3:0] next_count;
wire [3:0] half_count;
wire [2:0] count_carry;
wire pointer_zero;
wire pointer_full;
wire decode_data_present;
wire data_present_int;
wire valid_write;
////////////////////////////////////////////////////////////////////////////////////
//
// Start of BBFIFO_16x8 circuit description
//
////////////////////////////////////////////////////////////////////////////////////
// SRL16E data storage
SRL16E data_srl_0
( .D(data_in[0]),
.CE(valid_write),
.CLK(clk),
.A0(pointer[0]),
.A1(pointer[1]),
.A2(pointer[2]),
.A3(pointer[3]),
.Q(data_out[0]) );
defparam data_srl_0.INIT = 16'h0000;
SRL16E data_srl_1
( .D(data_in[1]),
.CE(valid_write),
.CLK(clk),
.A0(pointer[0]),
.A1(pointer[1]),
.A2(pointer[2]),
.A3(pointer[3]),
.Q(data_out[1]) );
defparam data_srl_1.INIT = 16'h0000;
SRL16E data_srl_2
( .D(data_in[2]),
.CE(valid_write),
.CLK(clk),
.A0(pointer[0]),
.A1(pointer[1]),
.A2(pointer[2]),
.A3(pointer[3]),
.Q(data_out[2]) );
defparam data_srl_2.INIT = 16'h0000;
SRL16E data_srl_3
( .D(data_in[3]),
.CE(valid_write),
.CLK(clk),
.A0(pointer[0]),
.A1(pointer[1]),
.A2(pointer[2]),
.A3(pointer[3]),
.Q(data_out[3]) );
defparam data_srl_3.INIT = 16'h0000;
SRL16E data_srl_4
( .D(data_in[4]),
.CE(valid_write),
.CLK(clk),
.A0(pointer[0]),
.A1(pointer[1]),
.A2(pointer[2]),
.A3(pointer[3]),
.Q(data_out[4]) );
defparam data_srl_4.INIT = 16'h0000;
SRL16E data_srl_5
( .D(data_in[5]),
.CE(valid_write),
.CLK(clk),
.A0(pointer[0]),
.A1(pointer[1]),
.A2(pointer[2]),
.A3(pointer[3]),
.Q(data_out[5]) );
defparam data_srl_5.INIT = 16'h0000;
SRL16E data_srl_6
( .D(data_in[6]),
.CE(valid_write),
.CLK(clk),
.A0(pointer[0]),
.A1(pointer[1]),
.A2(pointer[2]),
.A3(pointer[3]),
.Q(data_out[6]) );
defparam data_srl_6.INIT = 16'h0000;
SRL16E data_srl_7
( .D(data_in[7]),
.CE(valid_write),
.CLK(clk),
.A0(pointer[0]),
.A1(pointer[1]),
.A2(pointer[2]),
.A3(pointer[3]),
.Q(data_out[7]) );
defparam data_srl_7.INIT = 16'h0000;
// 4-bit counter to act as data pointer
// Counter is clock enabled by 'data_present'
// Counter will be reset when 'reset' is active
// Counter will increment when 'valid_write' is active
FDRE register_bit_0
( .D(next_count[0]),
.Q(pointer[0]),
.CE(data_present_int),
.R(reset),
.C(clk) );
LUT4 count_lut_0
( .I0(pointer[0]),
.I1(read),
.I2(pointer_zero),
.I3(write),
.O(half_count[0]) );
defparam count_lut_0.INIT = 16'h6606;
FDRE register_bit_1
( .D(next_count[1]),
.Q(pointer[1]),
.CE(data_present_int),
.R(reset),
.C(clk) );
LUT4 count_lut_1
( .I0(pointer[1]),
.I1(read),
.I2(pointer_zero),
.I3(write),
.O(half_count[1]) );
defparam count_lut_1.INIT = 16'h6606;
FDRE register_bit_2
( .D(next_count[2]),
.Q(pointer[2]),
.CE(data_present_int),
.R(reset),
.C(clk) );
LUT4 count_lut_2
( .I0(pointer[2]),
.I1(read),
.I2(pointer_zero),
.I3(write),
.O(half_count[2]) );
defparam count_lut_2.INIT = 16'h6606;
FDRE register_bit_3
( .D(next_count[3]),
.Q(pointer[3]),
.CE(data_present_int),
.R(reset),
.C(clk) );
LUT4 count_lut_3
( .I0(pointer[3]),
.I1(read),
.I2(pointer_zero),
.I3(write),
.O(half_count[3]) );
defparam count_lut_3.INIT = 16'h6606;
MUXCY count_muxcy_0
( .DI(pointer[0]),
.CI(valid_write),
.S(half_count[0]),
.O(count_carry[0]) );
XORCY count_xor_0
( .LI(half_count[0]),
.CI(valid_write),
.O(next_count[0]) );
MUXCY count_muxcy_1
( .DI(pointer[1]),
.CI(count_carry[0]),
.S(half_count[1]),
.O(count_carry[1]) );
XORCY count_xor_1
( .LI(half_count[1]),
.CI(count_carry[0]),
.O(next_count[1]) );
MUXCY count_muxcy_2
( .DI(pointer[2]),
.CI(count_carry[1]),
.S(half_count[2]),
.O(count_carry[2]) );
XORCY count_xor_2
( .LI(half_count[2]),
.CI(count_carry[1]),
.O(next_count[2]) );
XORCY count_xor
( .LI(half_count[3]),
.CI(count_carry[2]),
.O(next_count[3]) );
// Detect when pointer is zero and maximum
LUT4 zero_lut
( .I0(pointer[0]),
.I1(pointer[1]),
.I2(pointer[2]),
.I3(pointer[3]),
.O(pointer_zero ) );
defparam zero_lut.INIT = 16'h0001;
LUT4 full_lut
( .I0(pointer[0]),
.I1(pointer[1]),
.I2(pointer[2]),
.I3(pointer[3]),
.O(pointer_full ) );
defparam full_lut.INIT = 16'h8000;
// Data Present status
LUT4 dp_lut
( .I0(write),
.I1(read),
.I2(pointer_zero),
.I3(data_present_int),
.O(decode_data_present ) );
defparam dp_lut.INIT = 16'hBFA0;
FDR dp_flop
( .D(decode_data_present),
.Q(data_present_int),
.R(reset),
.C(clk) );
// Valid write wire
LUT3 valid_lut
( .I0(pointer_full),
.I1(write),
.I2(read),
.O(valid_write ) );
defparam valid_lut.INIT = 8'hC4;
// assign internal wires to outputs
assign full = pointer_full;
assign half_full = pointer[3];
assign data_present = data_present_int;
endmodule
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE BBFIFO_16x8.V
//
////////////////////////////////////////////////////////////////////////////////////
1.1 openfire2/rtl/kcuart_rx.v
http://www.opencores.org/cvsweb.shtml/openfire2/rtl/kcuart_rx.v?rev=1.1&content-type=text/x-cvsweb-markup
Index: kcuart_rx.v
===================================================================
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2004 Xilinx, Inc.
// All Rights Reserved
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version: 1.01
// \ \ Filename: kcuart_rx.v
// / / Date Last Modified: 08/04/2004
// /___/ /\ Date Created: 10/16/2002
// \ \ / \
// \___\/\___\
//
//Device: Xilinx
//Purpose:
// Constant (K) Compact UART Receiver
//Reference:
// None
//Revision History:
// Rev 1.00 - kc - Start of design entry in VHDL, 10/16/2002.
// Rev 1.01 - sus - Converted to verilog, 08/04/2004.
// Rev 1.02 - njs - Synplicity attributes added, 09/06/2004.
// Rev 1.03 - njs - defparam values corrected, 12/01/2005.
//////////////////////////////////////////////////////////////////////////////////
// Contact: e-mail picoblaze@x...
//////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// LIMITED WARRANTY AND DISCLAIMER. These designs are
// provided to you "as is". Xilinx and its licensors make and you
// receive no warranties or conditions, express, implied,
// statutory or otherwise, and Xilinx specifically disclaims any
// implied warranties of merchantability, non-infringement, or
// fitness for a particular purpose. Xilinx does not warrant that
// the functions contained in these designs will meet your
// requirements, or that the operation of these designs will be
// uninterrupted or error free, or that defects in the Designs
// will be corrected. Furthermore, Xilinx does not warrant or
// make any representations regarding use or the results of the
// use of the designs in terms of correctness, accuracy,
// reliability, or otherwise.
//
// LIMITATION OF LIABILITY. In no event will Xilinx or its
// licensors be liable for any loss of data, lost profits, cost
// or procurement of substitute goods or services, or for any
// special, incidental, consequential, or indirect damages
// arising from the use or operation of the designs or
// accompanying documentation, however caused and on any theory
// of liability. This limitation will apply even if Xilinx
// has been advised of the possibility of such damage. This
// limitation shall apply not-withstanding the failure of the
// essential purpose of any limited remedies herein.
//////////////////////////////////////////////////////////////////////////////////
`timescale 1 ps / 1ps
module kcuart_rx
(serial_in,
data_out,
data_strobe,
en_16_x_baud,
clk);
input serial_in;
output [7:0] data_out;
output data_strobe;
input en_16_x_baud;
input clk;
////////////////////////////////////////////////////////////////////////////////////
//
// Start of KCUART_RX
//
//
////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////
//
// wires used in KCUART_RX
//
////////////////////////////////////////////////////////////////////////////////////
//
wire sync_serial ;
wire stop_bit ;
wire [7:0] data_int ;
wire [7:0] data_delay ;
wire start_delay ;
wire start_bit ;
wire edge_delay ;
wire start_edge ;
wire decode_valid_char ;
wire valid_char ;
wire decode_purge ;
wire purge ;
wire [8:0] valid_srl_delay ;
wire [8:0] valid_reg_delay ;
wire decode_data_strobe ;
////////////////////////////////////////////////////////////////////////////////////
//
// Start of KCUART_RX circuit description
//
////////////////////////////////////////////////////////////////////////////////////
//
// Synchronise input serial data to system clock
FD sync_reg
( .D(serial_in),
.Q(sync_serial),
.C(clk) );
FD stop_reg
( .D(sync_serial),
.Q(stop_bit),
.C(clk) );
// Data delays to capture data at 16 time baud rate
// Each SRL16E is followed by a flip-flop for best timing
SRL16E delay15_srl_0
( .D(data_int[1]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(data_delay[0] ));
defparam delay15_srl_0.INIT = 16'h0000;
SRL16E delay15_srl_1
( .D(data_int[2]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(data_delay[1] ));
defparam delay15_srl_1.INIT = 16'h0000;
SRL16E delay15_srl_2
( .D(data_int[3]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(data_delay[2] ));
defparam delay15_srl_2.INIT = 16'h0000;
SRL16E delay15_srl_3
( .D(data_int[4]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(data_delay[3] ));
defparam delay15_srl_3.INIT = 16'h0000;
SRL16E delay15_srl_4
( .D(data_int[5]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(data_delay[4] ));
defparam delay15_srl_4.INIT = 16'h0000;
SRL16E delay15_srl_5
( .D(data_int[6]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(data_delay[5] ));
defparam delay15_srl_5.INIT = 16'h0000;
SRL16E delay15_srl_6
( .D(data_int[7]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(data_delay[6] ));
defparam delay15_srl_6.INIT = 16'h0000;
SRL16E delay15_srl_7
( .D(stop_bit),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(data_delay[7]) );
defparam delay15_srl_7.INIT = 16'h0000;
FDE data_reg_0
( .D(data_delay[0]),
.Q(data_int[0]),
.CE(en_16_x_baud),
.C(clk) );
FDE data_reg_1
( .D(data_delay[1]),
.Q(data_int[1]),
.CE(en_16_x_baud),
.C(clk) );
FDE data_reg_2
( .D(data_delay[2]),
.Q(data_int[2]),
.CE(en_16_x_baud),
.C(clk) );
FDE data_reg_3
( .D(data_delay[3]),
.Q(data_int[3]),
.CE(en_16_x_baud),
.C(clk) );
FDE data_reg_4
( .D(data_delay[4]),
.Q(data_int[4]),
.CE(en_16_x_baud),
.C(clk) );
FDE data_reg_5
( .D(data_delay[5]),
.Q(data_int[5]),
.CE(en_16_x_baud),
.C(clk) );
FDE data_reg_6
( .D(data_delay[6]),
.Q(data_int[6]),
.CE(en_16_x_baud),
.C(clk) );
FDE data_reg_7
( .D(data_delay[7]),
.Q(data_int[7]),
.CE(en_16_x_baud),
.C(clk) );
// Assign internal wires to outputs
assign data_out = data_int;
// Data delays to capture start bit at 16 time baud rate
SRL16E start_srl
( .D(data_int[0]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(start_delay ) );
defparam start_srl.INIT = 16'h0000;
FDE start_reg
( .D(start_delay),
.Q(start_bit),
.CE(en_16_x_baud),
.C(clk) );
// Data delays to capture start bit leading edge at 16 time baud rate
// Delay ensures data is captured at mid-bit position
SRL16E edge_srl
( .D(start_bit),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b0),
.A2(1'b1),
.A3(1'b0),
.Q(edge_delay ) );
defparam edge_srl.INIT = 16'h0000;
FDE edge_reg
( .D(edge_delay),
.Q(start_edge),
.CE(en_16_x_baud),
.C(clk) );
// Detect a valid character
LUT4 valid_lut
( .I0(purge),
.I1(stop_bit),
.I2(start_edge),
.I3(edge_delay),
.O(decode_valid_char ) );
defparam valid_lut.INIT = 16'h0040;
FDE valid_reg
( .D(decode_valid_char),
.Q(valid_char),
.CE(en_16_x_baud),
.C(clk) );
// Purge of data status
LUT3 purge_lut
( .I0(valid_reg_delay[8]),
.I1(valid_char),
.I2(purge),
.O(decode_purge ) );
defparam purge_lut.INIT = 8'h54;
FDE purge_reg
( .D(decode_purge),
.Q(purge),
.CE(en_16_x_baud),
.C(clk) );
// Delay of valid_char pulse of length equivalent to the time taken
// to purge data shift register of all data which has been used.
// Requires 9x16 + 8 delays which is achieved by packing of SRL16E with
// 16 delays and utilising the dedicated flip flop in each of 8 stages.
SRL16E valid_delay15_srl_0
( .D(valid_char),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b0),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[0] ) );
defparam valid_delay15_srl_0.INIT = 16'h0000;
SRL16E valid_delay16_srl_1
( .D(valid_reg_delay[0]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[1] ) );
defparam valid_delay16_srl_1.INIT = 16'h0000;
SRL16E valid_delay16_srl_2
( .D(valid_reg_delay[1]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[2] ) );
defparam valid_delay16_srl_2.INIT = 16'h0000;
SRL16E valid_delay16_srl_3
( .D(valid_reg_delay[2]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[3] ) );
defparam valid_delay16_srl_3.INIT = 16'h0000;
SRL16E valid_delay16_srl_4
( .D(valid_reg_delay[3]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[4] ) );
defparam valid_delay16_srl_4.INIT = 16'h0000;
SRL16E valid_delay16_srl_5
( .D(valid_reg_delay[4]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[5] ) );
defparam valid_delay16_srl_5.INIT = 16'h0000;
SRL16E valid_delay16_srl_6
( .D(valid_reg_delay[5]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[6] ) );
defparam valid_delay16_srl_6.INIT = 16'h0000;
SRL16E valid_delay16_srl_7
( .D(valid_reg_delay[6]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[7] ) );
defparam valid_delay16_srl_7.INIT = 16'h0000;
SRL16E valid_delay16_srl_8
( .D(valid_reg_delay[7]),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b1),
.A2(1'b1),
.A3(1'b1),
.Q(valid_srl_delay[8] ) );
defparam valid_delay16_srl_8.INIT = 16'h0000;
FDE valid_data_reg_0
( .D(valid_srl_delay[0]),
.Q(valid_reg_delay[0]),
.CE(en_16_x_baud),
.C(clk) );
FDE valid_data_reg_1
( .D(valid_srl_delay[1]),
.Q(valid_reg_delay[1]),
.CE(en_16_x_baud),
.C(clk) );
FDE valid_data_reg_2
( .D(valid_srl_delay[2]),
.Q(valid_reg_delay[2]),
.CE(en_16_x_baud),
.C(clk) );
FDE valid_data_reg_3
( .D(valid_srl_delay[3]),
.Q(valid_reg_delay[3]),
.CE(en_16_x_baud),
.C(clk) );
FDE valid_data_reg_4
( .D(valid_srl_delay[4]),
.Q(valid_reg_delay[4]),
.CE(en_16_x_baud),
.C(clk) );
FDE valid_data_reg_5
( .D(valid_srl_delay[5]),
.Q(valid_reg_delay[5]),
.CE(en_16_x_baud),
.C(clk) );
FDE valid_data_reg_6
( .D(valid_srl_delay[6]),
.Q(valid_reg_delay[6]),
.CE(en_16_x_baud),
.C(clk) );
FDE valid_data_reg_7
( .D(valid_srl_delay[7]),
.Q(valid_reg_delay[7]),
.CE(en_16_x_baud),
.C(clk) );
FDE valid_data_reg_8
( .D(valid_srl_delay[8]),
.Q(valid_reg_delay[8]),
.CE(en_16_x_baud),
.C(clk) );
// Form data strobe
LUT2 strobe_lut
( .I0(valid_char),
.I1(en_16_x_baud),
.O(decode_data_strobe ) );
defparam strobe_lut.INIT = 4'h8;
FD strobe_reg
( .D(decode_data_strobe),
.Q(data_strobe),
.C(clk) );
endmodule
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE KCUART_RX.V
//
////////////////////////////////////////////////////////////////////////////////////
1.1 openfire2/rtl/kcuart_tx.v
http://www.opencores.org/cvsweb.shtml/openfire2/rtl/kcuart_tx.v?rev=1.1&content-type=text/x-cvsweb-markup
Index: kcuart_tx.v
===================================================================
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2004 Xilinx, Inc.
// All Rights Reserved
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version: 1.03
// \ \ Filename: kcuart_tx.v
// / / Date Last Modified: November 2, 2004
// /___/ /\ Date Created: October 14, 2002
// \ \ / \
// \___\/\___\
//
//Device: Xilinx
//Purpose:
// Constant (K) Compact UART Transmitter
//Reference:
// None
//Revision History:
// Rev 1.00 - kc - Start of design entry in VHDL, October 14, 2002
// Rev 1.01 - sus - Converted to verilog, August 4, 2004
// Rev 1.02 - njs - Synplicity attributes added, September 6, 2004
// Rev 1.03 - njs - Fixed simulation attributes from string to hex,
// November 2, 2004
//////////////////////////////////////////////////////////////////////////////////
// Contact: e-mail picoblaze@x...
//////////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
// LIMITED WARRANTY AND DISCLAIMER. These designs are
// provided to you "as is". Xilinx and its licensors make and you
// receive no warranties or conditions, express, implied,
// statutory or otherwise, and Xilinx specifically disclaims any
// implied warranties of merchantability, non-infringement, or
// fitness for a particular purpose. Xilinx does not warrant that
// the functions contained in these designs will meet your
// requirements, or that the operation of these designs will be
// uninterrupted or error free, or that defects in the Designs
// will be corrected. Furthermore, Xilinx does not warrant or
// make any representations regarding use or the results of the
// use of the designs in terms of correctness, accuracy,
// reliability, or otherwise.
//
// LIMITATION OF LIABILITY. In no event will Xilinx or its
// licensors be liable for any loss of data, lost profits, cost
// or procurement of substitute goods or services, or for any
// special, incidental, consequential, or indirect damages
// arising from the use or operation of the designs or
// accompanying documentation, however caused and on any theory
// of liability. This limitation will apply even if Xilinx
// has been advised of the possibility of such damage. This
// limitation shall apply not-withstanding the failure of the
// essential purpose of any limited remedies herein.
//////////////////////////////////////////////////////////////////////////////////
`timescale 1 ps / 1ps
module kcuart_tx
(data_in,
send_character,
en_16_x_baud,
serial_out,
Tx_complete,
clk);
input [7:0] data_in;
input send_character;
input en_16_x_baud;
output serial_out;
output Tx_complete;
input clk;
//
////////////////////////////////////////////////////////////////////////////////////
//
// Start of KCUART_TX
//
//
////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////
//
// wires used in KCUART_TX
//
////////////////////////////////////////////////////////////////////////////////////
//
wire data_01;
wire data_23;
wire data_45;
wire data_67;
wire data_0123;
wire data_4567;
wire data_01234567;
wire [2:0] bit_select;
wire [2:0] next_count;
wire [2:0] mask_count;
wire [2:0] mask_count_carry;
wire [2:0] count_carry;
wire ready_to_start;
wire decode_Tx_start;
wire Tx_start;
wire decode_Tx_run;
wire Tx_run;
wire decode_hot_state;
wire hot_state;
wire hot_delay;
wire Tx_bit;
wire decode_Tx_stop;
wire Tx_stop;
wire decode_Tx_complete;
////////////////////////////////////////////////////////////////////////////////////
//
// Start of KCUART_TX circuit description
//
////////////////////////////////////////////////////////////////////////////////////
//
// 8 to 1 multiplexer to convert parallel data to serial
LUT4 mux1_lut
( .I0(bit_select[0]),
.I1(data_in[0]),
.I2(data_in[1]),
.I3(Tx_run),
.O(data_01) );
defparam mux1_lut.INIT = 16'hE4FF;
LUT4 mux2_lut
( .I0(bit_select[0]),
.I1(data_in[2]),
.I2(data_in[3]),
.I3(Tx_run),
.O(data_23) );
defparam mux2_lut.INIT = 16'hE4FF;
LUT4 mux3_lut
(.I0(bit_select[0]),
.I1(data_in[4]),
.I2(data_in[5]),
.I3(Tx_run),
.O(data_45) );
defparam mux3_lut.INIT = 16'hE4FF;
LUT4 mux4_lut
(.I0(bit_select[0]),
.I1(data_in[6]),
.I2(data_in[7]),
.I3(Tx_run),
.O(data_67) );
defparam mux4_lut.INIT = 16'hE4FF;
MUXF5 mux5_muxf5
( .I1(data_23),
.I0(data_01),
.S(bit_select[1]),
.O(data_0123) );
MUXF5 mux6_muxf5
( .I1(data_67),
.I0(data_45),
.S(bit_select[1]),
.O(data_4567) );
MUXF6 mux7_muxf6
( .I1(data_4567),
.I0(data_0123),
.S(bit_select[2]),
.O(data_01234567) );
// Register serial output and force start and stop bits
FDRS pipeline_serial
( .D(data_01234567),
.Q(serial_out),
.R(Tx_start),
.S(Tx_stop),
.C(clk) ) ;
// 3-bit counter
// Counter is clock enabled by en_16_x_baud
// Counter will be reset when 'Tx_start' is active
// Counter will increment when Tx_bit is active
// Tx_run must be active to count
// count_carry[2] indicates when terminal count [7] is reached and Tx_bit=1 (ie overflow)
FDRE register_bit_0
(.D(next_count[0]),
.Q(bit_select[0]),
.CE(en_16_x_baud),
.R(Tx_start),
.C(clk) );
LUT2 count_lut_0
(.I0(bit_select[0]),
.I1(Tx_run),
.O(mask_count[0]) );
defparam count_lut_0.INIT = 4'h8;
MULT_AND mask_and_0
(.I0(bit_select[0]),
.I1(Tx_run),
.LO(mask_count_carry[0]) );
MUXCY count_muxcy_0
( .DI(mask_count_carry[0]),
.CI(Tx_bit),
.S(mask_count[0]),
.O(count_carry[0]) );
XORCY count_xor_0
(.LI(mask_count[0]),
.CI(Tx_bit),
.O(next_count[0]) );
FDRE register_bit_1
(.D(next_count[1]),
.Q(bit_select[1]),
.CE(en_16_x_baud),
.R(Tx_start),
.C(clk) );
LUT2 count_lut_1
(.I0(bit_select[1]),
.I1(Tx_run),
.O(mask_count[1]) );
defparam count_lut_1.INIT = 4'h8;
MULT_AND mask_and_1
( .I0(bit_select[1]),
.I1(Tx_run),
.LO(mask_count_carry[1]) );
MUXCY count_muxcy_1
( .DI(mask_count_carry[1]),
.CI(count_carry[0]),
.S(mask_count[1]),
.O(count_carry[1]) );
XORCY count_xor_1
( .LI(mask_count[1]),
.CI(count_carry[0]),
.O(next_count[1]) );
FDRE register_bit_2
( .D(next_count[2]),
.Q(bit_select[2]),
.CE(en_16_x_baud),
.R(Tx_start),
.C(clk) );
LUT2 count_lut_2
( .I0(bit_select[2]),
.I1(Tx_run),
.O(mask_count[2]) );
defparam count_lut_2.INIT = 4'h8;
MULT_AND mask_and_2
( .I0(bit_select[2]),
.I1(Tx_run),
.LO(mask_count_carry[2]) );
MUXCY count_muxcy_2
( .DI(mask_count_carry[2]),
.CI(count_carry[1]),
.S(mask_count[2]) ,
.O(count_carry[2]) );
XORCY count_xor_2
( .LI(mask_count[2]),
.CI(count_carry[1]),
.O(next_count[2]) );
// Ready to start decode
LUT3 ready_lut
( .I0(Tx_run),
.I1(Tx_start),
.I2(send_character),
.O(ready_to_start ) );
defparam ready_lut.INIT = 8'h10;
// Start bit enable
LUT4 start_lut
( .I0(Tx_bit),
.I1(Tx_stop),
.I2(ready_to_start),
.I3(Tx_start),
.O(decode_Tx_start ) );
defparam start_lut.INIT = 16'h0190;
FDE Tx_start_reg
( .D(decode_Tx_start),
.Q(Tx_start),
.CE(en_16_x_baud),
.C(clk) );
// Run bit enable
LUT4 run_lut
( .I0(count_carry[2]),
.I1(Tx_bit),
.I2(Tx_start),
.I3(Tx_run),
.O(decode_Tx_run ) );
defparam run_lut.INIT = 16'h1540;
FDE Tx_run_reg
( .D(decode_Tx_run),
.Q(Tx_run),
.CE(en_16_x_baud),
.C(clk) );
// Bit rate enable
LUT3 hot_state_lut
( .I0(Tx_stop),
.I1(ready_to_start),
.I2(Tx_bit),
.O(decode_hot_state) );
defparam hot_state_lut.INIT = 8'h94;
FDE hot_state_reg
( .D(decode_hot_state),
.Q(hot_state),
.CE(en_16_x_baud),
.C(clk) );
SRL16E delay14_srl
( .D(hot_state),
.CE(en_16_x_baud),
.CLK(clk),
.A0(1'b1),
.A1(1'b0),
.A2(1'b1),
.A3(1'b1),
.Q(hot_delay) );
defparam delay14_srl.INIT = 16'h0000;
FDE Tx_bit_reg
( .D(hot_delay),
.Q(Tx_bit),
.CE(en_16_x_baud),
.C(clk) );
// Stop bit enable
LUT4 stop_lut
( .I0(Tx_bit),
.I1(Tx_run),
.I2(count_carry[2]),
.I3(Tx_stop),
.O(decode_Tx_stop) );
defparam stop_lut.INIT = 16'h0180;
FDE Tx_stop_reg
( .D(decode_Tx_stop),
.Q(Tx_stop),
.CE(en_16_x_baud),
.C(clk) );
// Tx_complete strobe
LUT2 complete_lut
( .I0(count_carry[2]),
.I1(en_16_x_baud),
.O(decode_Tx_complete) );
defparam complete_lut.INIT = 4'h8;
FD Tx_complete_reg
( .D(decode_Tx_complete),
.Q(Tx_complete),
.C(clk) );
endmodule
////////////////////////////////////////////////////////////////////////////////////
//
// END OF FILE KCUART_TX.V
//
////////////////////////////////////////////////////////////////////////////////////
1.1 openfire2/rtl/openfire_arbitrer.v
http://www.opencores.org/cvsweb.shtml/openfire2/rtl/openfire_arbitrer.v?rev=1.1&content-type=text/x-cvsweb-markup
Index: openfire_arbitrer.v
===================================================================
/* MODULE: openfire arbitrer
DESCRIPTION: Contains data/instruction memory decoder and arbitrer for
several peripherals
AUTHOR:
Antonio J. Anton
Anro Ingenieros (www.anro-ingenieros.com)
aj@a...
REVISION HISTORY:
Revision 1.0, 26/03/2007
Initial release
COPYRIGHT:
Copyright (c) 2007 Antonio J. Anton
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/`timescale 1ns / 1ps
`include "openfire_define.v"
module openfire_arbitrer(
`ifdef SP3SK_SRAM
sram_data2mem, sram_data2cpu,
sram_dmem_re, sram_dmem_we, sram_dmem_done,
sram_ins2cpu, sram_imem_re, sram_imem_done,
`endif
`ifdef IO_MULTICYCLE
dmem_done_io,
`endif
`ifdef ENABLE_ALIGNMENT_EXCEPTION
dmem_alignment_exception,
`endif
`ifdef SP3SK_IODEVICES
dmem_data_fromio, dmem_data_toio, dmem_we_io, dmem_re_io,
`endif
clock, reset, imem_done, dmem_done,
dmem_address, dmem_data_out, dmem_data_in, dmem_re, dmem_we,
dmem_input_sel, data_selector,
imem_address, imem_data, imem_re,
dmem_data_frombram, dmem_data_tobram, dmem_we_bram,
imem_data_frombram
);
input clock; // clock signal
input reset; // reset signal
output imem_done; // imem operation done
output dmem_done; // dmem operation done
input [31:0] dmem_address; // dmem address from cpu
output [31:0] dmem_data_out; // data-out to cpu (from arbitrer multiplexer)
input [31:0] dmem_data_in; // data-in from cpu to selected device
input dmem_re; // cpu read enable signal
input dmem_we; // cpu write enable signal
input [1:0] dmem_input_sel; // 0=byte, 1=hw, 2=word
output [3:0] data_selector; // each byte of the word (msb..lsb)
`ifdef ENABLE_ALIGNMENT_EXCEPTION
output dmem_alignment_exception; // exception on hw/word alignment
`endif
input [31:0] imem_address; // imem address from cpu
output [31:0] imem_data; // instruction to cpu
input imem_re; // instruction read enable
input [31:0] dmem_data_frombram; // data from bram
output [31:0] dmem_data_tobram; // data to bram
output dmem_we_bram; // write enable bram
input [31:0] imem_data_frombram; // instruction from bram
`ifdef SP3SK_IODEVICES
input [31:0] dmem_data_fromio; // data from iospace
output [31:0] dmem_data_toio; // data to iospace
output dmem_we_io; // write enable iospace
output dmem_re_io; // read from iospace
`endif
`ifdef SP3SK_SRAM // interface to external memory controller
output [31:0] sram_data2mem;
input [31:0] sram_data2cpu;
output sram_dmem_re;
output sram_dmem_we;
input sram_dmem_done;
input [31:0] sram_ins2cpu;
output sram_imem_re;
input sram_imem_done;
`endif
`ifdef IO_MULTICYCLE
input dmem_done_io;
`endif
// ---- read/write enable byte decoder and data selector -----
// this code generates de byte enable for a 32 bit word (4 bytes)
// based on dmem_address and dmem_input_sel (byte, hw or word)
// *** also generates unalignment exception
// *** also generates the memory to cpu data depending on the width
// of the request and the address
// *** also aligns the data from the cpu to the correct byte in the
// 32 bit word to be stored on memory
wire data_operation = dmem_re | dmem_we;
reg [3:0] data_selector;
`ifdef ENABLE_ALIGNMENT_EXCEPTION
reg dmem_alignment;
assign dmem_alignment_exception = dmem_alignment & data_operation;
`endif
wire [31:0] dmem_data2cpu; // bytes readed from device
reg [31:0] dmem_data_out;
reg [31:0] dmem_data2mem; // data 2 memory
always @(dmem_input_sel or dmem_address[1:0] or dmem_data2cpu or dmem_data_in)
begin
`ifdef ENABLE_ALIGNMENT_EXCEPTION
dmem_alignment <= 0; // default value
`endif
data_selector <= 4'b0000; // default no data selected
dmem_data_out <= 32'b0;
dmem_data2mem <= 32'bX;
case(dmem_address[1:0])
2'b00: case(dmem_input_sel)
`DM_byte : begin
data_selector <= 4'b1000;
dmem_data_out <= { dmem_data2cpu[31:24], 24'b0 };
dmem_data2mem <= { dmem_data_in[7:0], 24'bX };
end
`DM_halfword : begin
data_selector <= 4'b1100;
dmem_data_out <= { dmem_data2cpu[31:16], 16'b0 };
dmem_data2mem <= { dmem_data_in[15:0], 16'bX };
end
`DM_wholeword : begin
data_selector <= 4'b1111;
dmem_data_out <= dmem_data2cpu;
dmem_data2mem <= dmem_data_in;
end
`ifdef ENABLE_ALIGNMENT_EXCEPTION
default: dmem_alignment <= 1;
`endif
endcase
2'b01: case(dmem_input_sel)
`DM_byte : begin
data_selector <= 4'b0100;
dmem_data_out <= { dmem_data2cpu[23:16], 24'b0 };
dmem_data2mem <= { 8'bX, dmem_data_in[7:0], 16'bX };
end
`ifdef ENABLE_ALIGNMENT_EXCEPTION
default: dmem_alignment <= 1;
`endif
endcase
2'b10: case(dmem_input_sel)
`DM_byte : begin
data_selector <= 4'b0010;
dmem_data_out <= {dmem_data2cpu[15:8], 24'b0 };
dmem_data2mem <= { 16'bX, dmem_data_in[7:0], 8'bX };
end
`DM_halfword : begin
data_selector <= 4'b0011;
dmem_data_out <= {dmem_data2cpu[15:0], 16'b0 };
dmem_data2mem <= { 16'bX, dmem_data_in[15:0] };
end
`ifdef ENABLE_ALIGNMENT_EXCEPTION
default: dmem_alignment <= 1;
`endif
endcase
2'b11: case(dmem_input_sel)
`DM_byte : begin
data_selector <= 4'b0001;
dmem_data_out <= { dmem_data2cpu[7:0], 24'b0 };
dmem_data2mem <= { 24'b0, dmem_data_in[7:0] };
end
`ifdef ENABLE_ALIGNMENT_EXCEPTION
default: dmem_alignment <= 1;
`endif
endcase
endcase
`ifdef ENABLE_ALIGNMENT_EXCEPTION
//synthesis translate_off
if(dmem_alignment_exception) $display("ERROR!! Alignment exception");
//synthesis translate_on
`endif
end
// ---- data memory port chip select ----
// this logic generates the chip select based on the data address present
wire select_data_bram = (dmem_address[`DM_SIZE-1:`DM_SIZE-2] == `LOCATION_BRAM ||
dmem_address[`DM_SIZE-1:`DM_SIZE-2] == `LOCATION_BRAM_WRAP); // temporal!!!
`ifdef SP3SK_IODEVICES
wire select_data_io = dmem_address[`DM_SIZE-1:`DM_SIZE-2] == `LOCATION_IOSPACE;
`endif
`ifdef SP3SK_SRAM
wire select_data_sram = dmem_address[`DM_SIZE-1:`DM_SIZE-2] == `LOCATION_SRAM;
`endif
// ---- instruction memory port chip select ----
wire select_ins_bram = imem_address[`DM_SIZE-1:`DM_SIZE-2] == `LOCATION_BRAM;
`ifdef SP3SK_SRAM
wire select_ins_sram = imem_address[`DM_SIZE-1:`DM_SIZE-2] == `LOCATION_SRAM;
`endif
// ---- operation completed on data port ----
`ifndef IO_MULTICYCLE
wire dmem_done_io = 1; // no multicycle i/o
`endif
assign dmem_done = data_operation & ( select_data_bram // data BRAM
`ifdef SP3SK_SRAM
| (select_data_sram & sram_dmem_done) // data SRAM
`endif
`ifdef SP3SK_IODEVICES
| (select_data_io & dmem_done_io) // data IO
`endif
);
// ---- operation completed on instruction port ----
assign imem_done = /*imem_re &*/ (select_ins_bram // instruction BRAM
`ifdef SP3SK_SRAM
| (select_ins_sram & sram_imem_done) // instruction SRAM
`endif
);
// ---- data port operation enable ----
// data read BRAM always enabled
assign dmem_we_bram = dmem_we & select_data_bram; // write enable to bram
`ifdef SP3SK_IODEVICES
assign dmem_we_io = dmem_we & select_data_io;
assign dmem_re_io = dmem_re & select_data_io;
`endif
`ifdef SP3SK_SRAM
assign sram_dmem_re = dmem_re & select_data_sram; // read/write enable to sram
assign sram_dmem_we = dmem_we & select_data_sram;
`endif
// ---- instruction port operation enable ----
// instruction read BRAM always
`ifdef SP3SK_SRAM
wire sram_imem_re = select_ins_sram & imem_re;
`endif
// ----- instruction from memory to cpu multiplexer ----
`ifndef SP3SK_SRAM
assign imem_data = imem_data_frombram; // only BRAM
`else
assign imem_data = select_ins_bram ? imem_data_frombram : sram_ins2cpu; // ins2cpu mux
`endif
// ----- data from memory to cpu multiplexer ----
`ifndef SP3SK_SRAM
`ifndef SP3SK_IODEVICES
assign dmem_data2cpu = dmem_data_frombram; // only BRAM
`else
assign dmem_data2cpu = select_data_io ? dmem_data_fromio : dmem_data_frombram; // BRAM + IO
`endif
`else
`ifndef SP3SK_IODEVICES
assign dmem_data2cpu = select_data_sram ? sram_data2cpu : dmem_data_frombram; // BRAM + SRAM
`else
assign dmem_data2cpu = select_data_sram ? sram_data2cpu :
select_data_io ? dmem_data_fromio :
dmem_data_frombram;
`endif
`endif
// ---- data from cpu to all devices ----
assign dmem_data_tobram = dmem_data2mem; // data from cpu to all devices
`ifdef SP3SK_IODEVICES
assign dmem_data_toio = dmem_data2mem;
`endif
`ifdef SP3SK_SRAM
assign sram_data2mem = dmem_data2mem;
`endif
endmodule
1.1 openfire2/rtl/openfire_cpu.v
http://www.opencores.org/cvsweb.shtml/openfire2/rtl/openfire_cpu.v?rev=1.1&content-type=text/x-cvsweb-markup
Index: openfire_cpu.v
===================================================================
/* MODULE: openfire_cpu
DESCRIPTION: This is the top module for the openfire processor, instantiating
the fetch, decode, execute, pipeline_ctrl, and register file modules.
AUTHOR:
Stephen Douglas Craven
Configurable Computing Lab
Virginia Tech
scraven@v...
REVISION HISTORY:
Revision 0.2, 8/10/2005 SDC
Initial release
Revision 0.3, 12/17/2005 SDC
Fixed PC size bug
Revision 0.4 27/03/2007 Antonio J. Anton
Improved (interrupts, exceptions, msr)
Ripup of memory signals
COPYRIGHT:
Copyright (c) 2005 Stephen Douglas Craven
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. */
`include "openfire_define.v"
module openfire_cpu (
clock, reset,
`ifdef ENABLE_INTERRUPTS
interrupt,
`endif
`ifdef ENABLE_ALIGNMENT_EXCEPTION
dmem_alignment_exception,
`endif
dmem_addr, dmem_data_in, dmem_data_out, // ins/data ports
dmem_we, dmem_re, dmem_input_sel, dmem_done,
imem_addr, imem_data_in, imem_re, imem_done
);
input clock;
input reset;
input [31:0] dmem_data_in;
input [31:0] imem_data_in;
input dmem_done;
input imem_done;
`ifdef ENABLE_INTERRUPTS
input interrupt;
`endif
`ifdef ENABLE_ALIGNMENT_EXCEPTION
input dmem_alignment_exception;
`endif
output [31:0] dmem_data_out;
output [31:0] dmem_addr;
output [31:0] imem_addr;
output imem_re;
output dmem_we;
output dmem_re;
output [1:0] dmem_input_sel; //0=byte, 1=hw, 2=word
wire branch_taken;
wire [`A_SPACE+1:0] pc_branch;
wire [`A_SPACE+1:0] pc_decode;
wire [`A_SPACE+1:0] pc_exe_rf;
wire [31:0] instruction;
wire [4:0] regA_addr;
wire [4:0] regB_addr;
wire [4:0] regD_addr;
wire [31:0] immediate;
wire [2:0] alu_inputA_sel;
wire [1:0] alu_inputB_sel;
wire [1:0] alu_inputC_sel;
wire [3:0] alu_fns_sel;
wire [2:0] comparator_fns_sel;
wire we_alu_branch;
wire we_load;
wire we_store;
wire we_regfile;
wire [3:0] regfile_input_sel;
wire delay_bit;
wire [31:0] result;
wire [31:0] regA;
wire [31:0] regB;
wire [31:0] regD;
wire update_carry;
wire stall_exe;
wire stall_decode;
wire stall_fetch;
wire instr_complete;
wire flush;
wire branch_instr;
`ifdef ENABLE_MSR_BIP
wire update_msr_bip;
wire value_msr_bip;
`endif
`ifdef ENABLE_INTERRUPTS
wire int_ip;
wire int_dc;
wire set_msr_ie;
`endif
`ifdef ENABLE_EXCEPTIONS
wire reset_msr_eip;
wire insert_exception;
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
wire opcode_exception;
`endif
`ifdef ENABLE_MSR_OPCODES
wire rS_update;
`endif
openfire_fetch FETCH (
.stall(stall_fetch),
.clock(clock),
.reset(reset),
.branch_taken(branch_taken),
.pc_branch(pc_branch),
.idata(imem_data_in),
.imem_addr(imem_addr),
.imem_re(imem_re),
.pc_decode(pc_decode),
.instruction(instruction)
);
openfire_decode DECODE (
`ifdef ENABLE_MSR_BIP
.update_msr_bip(update_msr_bip),
.value_msr_bip(value_msr_bip),
`endif
`ifdef ENABLE_INTERRUPTS
.int_ip(int_ip),
.int_dc(int_dc),
.set_msr_ie(set_msr_ie),
`endif
`ifdef ENABLE_EXCEPTIONS
.reset_msr_eip(reset_msr_eip),
.insert_exception(insert_exception),
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
.opcode_exception(opcode_exception),
`endif
`ifdef ENABLE_MSR_OPCODES
.rS_update(rs_update),
`endif
.clock(clock),
.stall(stall_decode),
.reset(reset),
.pc_decode(pc_decode),
.instruction(instruction),
.regA_addr(regA_addr),
.regB_addr(regB_addr),
.regD_addr(regD_addr),
.immediate(immediate),
.pc_exe(pc_exe_rf),
.alu_inputA_sel(alu_inputA_sel),
.alu_inputB_sel(alu_inputB_sel),
.alu_inputC_sel(alu_inputC_sel),
.alu_fns_sel(alu_fns_sel),
.comparator_fns_sel(comparator_fns_sel),
.branch_instr(branch_instr),
.we_alu_branch(we_alu_branch),
.we_load(we_load),
.we_store(we_store),
.regfile_input_sel(regfile_input_sel),
.dmem_input_sel(dmem_input_sel),
.flush(flush),
.delay_bit(delay_bit),
.update_carry(update_carry)
);
openfire_execute EXECUTE (
`ifdef ENABLE_MSR_BIP
.update_msr_bip(update_msr_bip),
.value_msr_bip(value_msr_bip),
`endif
`ifdef ENABLE_INTERRUPTS
.interrupt(interrupt),
.int_ip(int_ip),
.int_dc(int_dc),
.set_msr_ie(set_msr_ie),
`endif
`ifdef ENABLE_EXCEPTIONS
.reset_msr_eip(reset_msr_eip),
.insert_exception(insert_exception),
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
.opcode_exception(opcode_exception),
`endif
`ifdef ENABLE_ALIGNMENT_EXCEPTION
.dmem_alignment_exception(dmem_alignment_exception),
`endif
`ifdef ENABLE_MSR_OPCODES
.rS_update(rs_update),
`endif
.clock(clock),
.reset(reset),
.stall(stall_exe),
.immediate(immediate),
.pc_exe(pc_exe_rf),
.alu_inputA_sel(alu_inputA_sel),
.alu_inputB_sel(alu_inputB_sel),
.alu_inputC_sel(alu_inputC_sel),
.alu_fns_sel(alu_fns_sel),
.comparator_fns_sel(comparator_fns_sel),
.we_load(we_load),
.we_store(we_store),
.update_carry(update_carry),
.regA(regA),
.regB(regB),
.regD(regD),
.alu_result(result),
.pc_branch(pc_branch),
.branch_instr(branch_instr),
.branch_taken(branch_taken),
.instr_complete(instr_complete),
.dmem_addr(dmem_addr),
.dmem_data_out(dmem_data_out),
.dmem_done(dmem_done),
.we_regfile(we_regfile),
.dmem_we(dmem_we),
.dmem_re(dmem_re)
);
openfire_regfile REGFILE (
.reset(reset),
.clock(clock),
.regA_addr(regA_addr),
.regB_addr(regB_addr),
.regD_addr(regD_addr),
.result(result),
.pc_regfile(pc_exe_rf),
.dmem_data(dmem_data_in),
.regfile_input_sel(regfile_input_sel),
.we_regfile(we_regfile),
.we_alu_branch(we_alu_branch),
.regA(regA),
.regB(regB),
.regD(regD),
.enable(~stall_exe)
);
openfire_pipeline_ctrl PIPELINE (
.clock(clock),
.reset(reset),
.flush(flush),
.imem_done(imem_done),
.imem_re(imem_re),
.branch_taken(branch_taken),
.instr_complete(instr_complete),
.delay_bit(delay_bit),
.stall_fetch(stall_fetch),
.stall_decode(stall_decode),
.stall_exe(stall_exe)
);
endmodule
1.1 openfire2/rtl/openfire_debug.v
http://www.opencores.org/cvsweb.shtml/openfire2/rtl/openfire_debug.v?rev=1.1&content-type=text/x-cvsweb-markup
Index: openfire_debug.v
===================================================================
/* MODULE: openfire_debug
DESCRIPTION: Contains opcode dissasembler and
AUTHOR:
Antonio J. Anton
Anro Ingenieros (www.anro-ingenieros.com)
aj@a...
REVISION HISTORY:
Revision 1.0, 26/03/2007
Initial release
COPYRIGHT:
Copyright (c) 2007 Antonio J. Anton
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/
//synthesis translate_off
// ------------------ opcode disassembler -----------------
// based on the kcpsm3 (picoblaze) dissasembler
`ifdef OPCODE_DISSASEMBLER
reg [31:0] pc_actual;
reg [31:0] instruction; // executing instruction
reg [31:0] instruction_decode;
reg [31:0] instruction_fetch; // fetched instruction
reg [15:0] prev_imm;
reg [1:64] op;
reg [1:32] arg1;
reg [1:32] arg2;
reg [1:80] arg3;
reg [1:0] rD, rA, rB_IMM;
initial prev_imm = 0; // initialize IMM opcode
always @(posedge clk)
begin
if(rst)
begin
instruction_fetch = `NoOp;
instruction_decode = `NoOp;
instruction = `NoOp;
end
else if(imem_done)
begin
instruction = instruction_decode;
instruction_decode = instruction_fetch;
instruction_fetch = CPU.FETCH.idata;
end
end
always @(posedge clk)
begin
if(CPU.EXECUTE.instr_complete & !CPU.EXECUTE.stall)
begin
op[1:56] = " "; // initialize dissasembled line
arg1[1:32] = " ";
arg2[1:32] = " ";
arg3[1:80] = " ";
rD = 1; // by default enable all parameters, specific
rA = 1; // opcodes will disable they
rB_IMM = 1;
pc_actual = {{(30 - `A_SPACE) {1'b0}},CPU.EXECUTE.pc_exe}; // executed PC
casez(`opcode) // decode opcode
`ADD : begin
op[1:24] = "add";
if(`IMM_bit) op[25:32] = "i";
if(`K_bit) op[33:40] = "k";
if(`C_bit) op[41:48] = "c";
end
`LOGIC_AND : begin
op[1:24] = "and";
if(`IMM_bit) op[25:32] = "i";
end
`LOGIC_ANDN : begin
op[1:32] = "andn";
if(`IMM_bit) op[33:40] = "i";
end
`BRANCH_CON : begin
rD = 0;
case(`branch_compare)
`CMP_equal : op[1:24] = "beq";
`CMP_not_equal : op[1:24] = "bne";
`CMP_lessthan : op[1:24] = "blt";
`CMP_lt_equal : op[1:24] = "ble";
`CMP_greaterthan : op[1:24] = "bgt";
`CMP_gt_equal : op[1:24] = "bge";
default: $display("error: invalid conditional branch");
endcase
if(`IMM_bit) op[25:32] = "i";
if(`D_bit_cond) op[33:40] = "d";
end
`BRANCH_UNCON: begin
rA = 0;
if(`A_bit & `L_bit & ~`D_bit_uncond) // bral = break
begin
op[1:32] = "brk"; // rA is 5'b01100 for brk
if(`IMM_bit) op[33:40] = "i";
end
else
begin // other unconditional branches
op[1:16] = "br";
if(`A_bit) op[17:24] = "a";
if(`IMM_bit) op[25:32] = "i";
if(`L_bit) op[33:40] = "l"; else rD = 0; // rD used if link
if(`D_bit_uncond) op[41:48] = "d";
end
end
`BARREL_SHIFT: $display("error: barrel shift not implemented");
`FSL : $display("error: fsl not implemented");
`FP_OP : $display("error: floating point not implemented");
`DIVIDE : $display("error: divide not implemented");
`IMMEDIATE : begin
rD = 0;
rA = 0;
op[1:24]="imm";
prev_imm = instruction[15:0]; // store previous immediate
end
`LOAD : begin
op[1:8] = "l";
case(`word_size)
2'b00: op[9:24] = "bu";
2'b01: op[9:24] = "hu";
2'b10: op[9:16] = "w";
default: $display("error: invalid load");
endcase
if(`IMM_bit) op[25:32] = "i";
end
`SPECIAL_REG : begin
if(`is_mfs) // mfs rD,rS (rmsr, rpc, etc..)
begin
op[1:24] = "mfs";
rA = 0;
rB_IMM = 2;
end
else if(`is_mts) // mts rS,rD (rS only msr)
begin
op[1:24] = "mts";
rD = 2;
rB_IMM = 0;
end
end
`MULTIPLY : begin
op[1:24] = "mul";
if(`IMM_bit) op[25:32] = "i";
end
`LOGIC_OR : begin
op[1:16] = "or";
if(`IMM_bit) op[17:24] = "i";
end
`PATTERN_CMP : $display("error: pattern compare not implemented");
`SUBTRACT : begin
if(`CMP_bit)
begin
op[1:24] = "cmp"; // compare
if(`U_bit) op[25:32] = "u";
end
else op[1:32] = "rsub";
if(`IMM_bit) op[33:40] = "i";
if(`K_bit) op[41:48] = "k";
if(`C_bit) op[49:56] = "c";
end
`RETURN : begin // default is return from subroutine
rD = 0;
op[1:32] = "rtsd"; // rD = 6'b10100, type B (imm value)
if(`BRK_bit) op[17:24] = "b";
else if(`INT_bit) op[17:24] = "i";
else if(`EXC_bit) op[17:24] = "e";
end
`STORE : begin
op[1:8] = "s";
case(`word_size)
2'b00: op[9:16] = "b";
2'b01: op[9:16] = "h";
2'b10: op[9:16] = "w";
default: $display("error: invalid store");
endcase
if(`IMM_bit) op[17:24] = "i";
end
`LOGIC_BIT : begin // is only type A: opcode rD,rA,rB
rB_IMM = 0;
if(`is_SEXT16) op[1:48] = "sext16";
else if(`is_SEXT8) op[1:40] = "sext8";
else if(`is_SRA) op[1:24] = "sra";
else if(`is_SRC) op[1:24] = "src";
else if(`is_SRL) op[1:24] = "srl";
else $display("error: invalid logical bit function");
end
`LOGIC_XOR : begin
op[1:24] = "xor";
if(`IMM_bit) op[25:32] = "i";
end
default : $display("error: invalid opcode");
endcase
if(`opcode == `IMMEDIATE) // IMM opcode only has arg3
begin
arg3[1:16] = "0x";
arg3[17:48] = hex4(prev_imm); // high 16 bits are prev_imm
end
else
begin
if(`IMM_bit)
begin
if(prev_imm == 0) prev_imm = {16 {instruction[15]}}; // sign extend immediate
arg3[1:16] = "0x";
arg3[17:48] = hex4(prev_imm); // high 16 bits are prev_imm
arg3[49:80] = hex4(instruction[15:0]); // low 16 bits are in opcode
end
else arg3[1:24] = registro(`regB_sel);
if(rD == 1) arg1[1:24] = registro(`regD_sel);
else if(rD == 2) arg1[1:32] = registro_especial(`regS_sel_msr);
arg2[1:24] = registro(`regA_sel);
end
if(rD == 0) arg1[1:32] = " "; // disable unused parameters
if(rA == 0) arg2[1:32] = " ";
if(rB_IMM == 0) arg3[1:80] = " ";
else if(rB_IMM == 2) arg3[1:32] = registro_especial(`regS_sel_msr);
if(rD && rA) arg1[25:32] = ","; // parameter separators
if(rA && rB_IMM) arg2[25:32] = ",";
if(rD && rB_IMM) arg2[25:32] = ",";
$display("%d PC[%x] OPCODE[%x] - %s", $time, pc_actual, instruction, {op, arg1, arg2, arg3} );
if(`opcode != `IMMEDIATE && prev_imm != 0) prev_imm = 0; // after the opcode that uses the IMM, prev_imm=0
end
end
function [1:8] hexcharacter ; // generates 4 bit hex string
input [3:0] nibble ;
begin
case (nibble)
4'b0000 : hexcharacter = "0" ;
4'b0001 : hexcharacter = "1" ;
4'b0010 : hexcharacter = "2" ;
4'b0011 : hexcharacter = "3" ;
4'b0100 : hexcharacter = "4" ;
4'b0101 : hexcharacter = "5" ;
4'b0110 : hexcharacter = "6" ;
4'b0111 : hexcharacter = "7" ;
4'b1000 : hexcharacter = "8" ;
4'b1001 : hexcharacter = "9" ;
4'b1010 : hexcharacter = "A" ;
4'b1011 : hexcharacter = "B" ;
4'b1100 : hexcharacter = "C" ;
4'b1101 : hexcharacter = "D" ;
4'b1110 : hexcharacter = "E" ;
4'b1111 : hexcharacter = "F" ;
endcase
end
endfunction
function [15:0] hex2; // generates 8 bit hex string
input [7:0] num;
begin
hex2[15:8] = hexcharacter(num[7:4]);
hex2[7:0] = hexcharacter(num[3:0]);
end
endfunction
function [31:0] hex4; // generates 16 bit hex string
input [15:0] num;
begin
hex4[31:16] = hex2(num[15:8]);
hex4[15:0] = hex2(num[7:0]);
end
endfunction
function [1:32] registro_especial;
input [4:0] regn;
begin
case (regn)
`rS_PC : registro_especial = "rpc ";
`rS_MSR : registro_especial = "rmsr";
default :
begin
$display("dissasembler: error: special register %x not implemented", regn);
registro_especial = "???";
end
endcase
end
endfunction
function [1:24] registro; // converts 5 bits to the register representation rXX
input [4:0] regn;
begin
case (regn)
0 : registro = "r0 ";
1 : registro = "r1 ";
2 : registro = "r2 ";
3 : registro = "r3 ";
4 : registro = "r4 ";
5 : registro = "r5 ";
6 : registro = "r6 ";
7 : registro = "r7 ";
8 : registro = "r8 ";
9 : registro = "r9 ";
10: registro = "r10";
11: registro = "r11";
12: registro = "r12";
13: registro = "r13";
14: registro = "r14";
15: registro = "r15";
16: registro = "r16";
17: registro = "r17";
18: registro = "r18";
19: registro = "r19";
20: registro = "r20";
21: registro = "r21";
22: registro = "r22";
23: registro = "r23";
24: registro = "r24";
25: registro = "r25";
26: registro = "r26";
27: registro = "r27";
28: registro = "r28";
29: registro = "r29";
30: registro = "r30";
31: registro = "r31";
endcase
end
endfunction
`endif
// -------------- memory/register dumps -------------------
// from Stephen Douglas Craven testbench
`ifdef DEBUG_SIMPLE_MEMORY_DUMP
// BREAKPOINT stops simulation and displays register contents.
// Set to unreachable address to disable.
`define BREAKPOINT 32'hc0
// Define clock counter for debugging
integer i;
reg [31:0] counter;
assign clock = clk;
assign reset = rst;
initial begin
counter = 32'b0;
for (i = 0; i >= 0; i = i + 1)
@(posedge clock) if (~reset) counter <= counter + 1;
end
// Debug Statements
always@(posedge clock)
begin
if( CPU.EXECUTE.instr_complete & !CPU.EXECUTE.stall )
begin
if(CPU.branch_taken) // Branch instructions
begin
$display("*** PC=%x: BRANCH=%x", {{(30 - `A_SPACE) {1'b0}},CPU.EXECUTE.pc_exe},
{{(30 - `A_SPACE) {1'b0}},CPU.pc_branch});
end
if (CPU.REGFILE.write_en) // Register File writes
begin
if(CPU.dmem_re)
$display("*** PC=%x: r%d=%x (leido de DMEM=0x%x)", {{(30 - `A_SPACE) {1'b0}},CPU.EXECUTE.pc_exe},
CPU.REGFILE.regD_addr, {CPU.REGFILE.input_data}, CPU.dmem_addr );
else
$display("*** PC=%x: r%d=%x", {{(30 - `A_SPACE) {1'b0}},CPU.EXECUTE.pc_exe}, CPU.REGFILE.regD_addr,
{CPU.REGFILE.input_data});
end
if (dmem_we) // Memory writes
begin
$display("*** PC=%x: addr=%x write=%x", {{(30 - `A_SPACE) {1'b0}},CPU.EXECUTE.pc_exe},
CPU.dmem_addr, dmem_data2mem);
end
if (dmem_re & !CPU.REGFILE.write_en) // Memory read
begin
$display("*** PC=%x: addr=%x read=%x", {{(30 - `A_SPACE) {1'b0}},CPU.EXECUTE.pc_exe},
CPU.dmem_addr, dmem_data2cpu);
end
end
end
// Stop at Breakpoint
//always@(posedge clock)
//begin
// if(CPU.DECODE.pc_exe == `BREAKPOINT)
// begin
// Uncomment to display register file contents at breakpoint
/* $display(" PC is %x", CPU.EXECUTE.pc_exe);
$display(" Clock Counter is %d", counter);
for(j = 0; j < 8; j = j + 1)
$display(" %d: %x %d %x %d: %x %d %x", j, CPU.REGFILE.RF_BANK0.MEM[j], j + 8,
CPU.REGFILE.RF_BANK0.MEM[j + 8],j+16, CPU.REGFILE.RF_BANK0.MEM[j+16],j+24,
CPU.REGFILE.RF_BANK0.MEM[j+24]);
*/
// $finish;
// end
//end
`endif
//synthesis translate_on
1.1 openfire2/rtl/openfire_decode.v
http://www.opencores.org/cvsweb.shtml/openfire2/rtl/openfire_decode.v?rev=1.1&content-type=text/x-cvsweb-markup
Index: openfire_decode.v
===================================================================
/* MODULE: openfire_decode
DESCRIPTION: The decode module received the instruction from the fetch module
and produces all control signals needed by the execute stage and the register
file. In the case of IMM instructions, the decode module will stall the
execute module by issuing a NoOp instruction.
The COMPARE module is used for calculating if a branch is taken and CMPU
ops if support is selected. The DECODE module commands the comparator to output
a 1 for unconditional branchs and a 0 for all other non-branch instructions (other
than CMPU)..
While FSL instructions are optionally implemented (if FSL_LINK is defined),
only one link (FSL0) is currently supported.
MISSING INSTRUCTIONS:
- special register instruction: MSRCLR, MSRSET
- all instructions requiring extra hardware, except for optional multiply: IDIV, BS
- cache-related instruction: WDC, WIC
TO DO:
- Complete instruction set
- Simplify instruction extension
AUTHOR:
Stephen Douglas Craven
Configurable Computing Lab
Virginia Tech
scraven@v...
REVISION HISTORY:
Revision 0.2, 8/10/2005 SDC
Initial release
Revision 0.3, 12/17/2005 SDC
Fixed PC size bug
Revision 0.4, 15/03/2007 SDC
Fixed CMP[U] with IMM bit
Revision 0.5 27/03/2007 Antonio J. Anton
Handling of interrupts/exceptions
MSR opcodes (mfs, mts)
COPYRIGHT:
Copyright (c) 2005 Stephen Douglas Craven
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. */
`include "openfire_define.v"
module openfire_decode(
`ifdef ENABLE_MSR_BIP
update_msr_bip, value_msr_bip,
`endif
`ifdef ENABLE_INTERRUPTS
int_ip, int_dc, set_msr_ie,
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
opcode_exception,
`endif
`ifdef ENABLE_EXCEPTIONS
reset_msr_eip, insert_exception,
`endif
`ifdef ENABLE_MSR_OPCODES
rS_update,
`endif
clock, stall, reset, // top level
pc_decode, instruction, flush, // inputs
regA_addr, regB_addr, regD_addr, immediate, // outputs
alu_inputA_sel, alu_inputB_sel, alu_inputC_sel,
alu_fns_sel, comparator_fns_sel, branch_instr,
we_alu_branch, we_load, we_store, regfile_input_sel,
dmem_input_sel, delay_bit, update_carry, pc_exe
);
// From top level -- all active high unless otherwise noted
input stall;
input reset;
input clock;
// From DECODE module
input [`A_SPACE+1:0] pc_decode;
input [31:0] instruction;
// From Pipeline Controller
input flush; // a branch was taken... flush the pipeline
output [4:0] regA_addr;
output [4:0] regB_addr;
output [4:0] regD_addr;
output [31:0] immediate;
output [`A_SPACE+1:0] pc_exe; // pc for use by EXECUTE
output [2:0] alu_inputA_sel;
output [1:0] alu_inputB_sel;
output [1:0] alu_inputC_sel;
output [3:0] alu_fns_sel;
output [2:0] comparator_fns_sel;
output we_load; // write_en for regfile on Load
output we_store; // write_en for DMEM
output we_alu_branch; // write_en for regfile on ALU / Branch instr
output [3:0] regfile_input_sel; // selects input to regfile
output [1:0] dmem_input_sel; // selects input to DMEM
output delay_bit;
output update_carry; // tells EXECUTE to update carry bit in MSR
output branch_instr; // tells EXECUTE to use comparator for branching
`ifdef ENABLE_MSR_BIP
output update_msr_bip; // handle MSR[BIP]
output value_msr_bip;
`endif
`ifdef ENABLE_INTERRUPTS
input int_ip;
output int_dc;
output set_msr_ie;
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
output opcode_exception;
input insert_exception;
`endif
`ifdef ENABLE_EXCEPTIONS
output reset_msr_eip;
`endif
`ifdef ENABLE_MSR_OPCODES
output rS_update;
`endif
// Register All Outputs
reg [31:0] immediate;
reg [`A_SPACE+1:0] pc_exe; // Prog Cnter of instr being executed
reg [2:0] alu_inputA_sel;
reg [1:0] alu_inputB_sel;
reg [1:0] alu_inputC_sel;
reg [3:0] alu_fns_sel; // selects ALU function
reg [2:0] comparator_fns_sel;
reg we_load; // reg file write enable for load operations
reg we_store;
reg we_alu_branch; // reg file write enable for ALU or branch ops
reg [3:0] regfile_input_sel;
reg [1:0] dmem_input_sel;
reg [4:0] regA_addr; // 5-bit addresses into Reg File
reg [4:0] regB_addr;
reg [4:0] regD_addr;
reg update_carry; // update the Carry bit in the status reg for ADDs
reg delay_bit; // Use delay slot in Branches
reg branch_instr;
`ifdef ENABLE_MSR_BIP
reg update_msr_bip;
reg value_msr_bip;
`endif
`ifdef ENABLE_INTERRUPTS
reg int_dc;
reg set_msr_ie;
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
reg opcode_exception;
`endif
`ifdef ENABLE_EXCEPTIONS
reg reset_msr_eip;
`endif
`ifdef ENABLE_MSR_OPCODES
reg rS_update;
`endif
// Internal registers
reg [15:0] imm; // contains imm value from IMM instr
reg imm_valid; // indicates imm value is valid (aka previous instr was IMM)
always@(posedge clock)
begin
if (reset | (flush & !stall)) // flush only if not stalled, if not we may miss the executing state
begin
if (reset)
pc_exe <= 0;
else
pc_exe <= pc_decode;
update_carry <= 0;
regA_addr <= 0;
regB_addr <= 0;
regD_addr <= 0;
immediate <= 0;
alu_inputA_sel <= 0;
alu_inputB_sel <= 0;
alu_inputC_sel <= 0;
delay_bit <= 0;
branch_instr <= 0;
// EXECUTE NoOp on Reset / Flush. NoOp is OR r0, r0, r0
alu_fns_sel <= `ALU_logic_or;
comparator_fns_sel<= 0;
we_load <= 0;
we_store <= 0;
we_alu_branch <= 0;
regfile_input_sel <= `RF_zero; // write zero to r0 on reset -- R0 always zero
dmem_input_sel <= 0;
imm <= 0;
imm_valid <= 0;
`ifdef ENABLE_MSR_BIP
update_msr_bip <= 0;
value_msr_bip <= 0;
`endif
`ifdef ENABLE_INTERRUPTS
int_dc <= 0;
set_msr_ie <= 0;
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
opcode_exception <= 0;
`endif
`ifdef ENABLE_EXCEPTIONS
reset_msr_eip <= 0;
`endif
`ifdef ENABLE_MSR_OPCODES
rS_update <= 0;
`endif
`ifdef DEBUG_DECODE
$display("DECODE RESET/FLUSH: pc_exe=%x", pc_exe);
`endif
end
else if (!stall)
begin
// defaults for most instructions
branch_instr <= 0;
pc_exe <= pc_decode;
// Delay bit is tricky as each type of branch has a different location
delay_bit <= `uncond_branch ? ((`opcode == `RETURN) ? 1 : `D_bit_uncond) : `cond_branch ? `D_bit_cond : 0;
we_load <= 0;
we_store <= 0;
update_carry <= 0;
regA_addr <= `regA_sel;
regB_addr <= `regB_sel;
regD_addr <= `regD_sel;
immediate <= imm_valid ? {imm, `imm_value} : {{16{instruction[15]}}, `imm_value}; // 32-bit datapath
we_alu_branch <= 1'b1; // most instrs write to reg file
regfile_input_sel <= `RF_alu_result;
alu_inputA_sel <= `aluA_ra;
alu_inputB_sel <= `IMM_bit ? `aluB_imm : `aluB_rb;
alu_inputC_sel <= `aluC_zero;
alu_fns_sel <= `ALU_add;
comparator_fns_sel<= 0; // Not using comparator
imm_valid <= 0;
`ifdef ENABLE_MSR_BIP
update_msr_bip <= 0;
value_msr_bip <= 0;
`endif
`ifdef ENABLE_INTERRUPTS
set_msr_ie <= 0;
int_dc <= 0;
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
opcode_exception <= 0;
`endif
`ifdef ENABLE_EXCEPTIONS
reset_msr_eip <= 0;
`endif
`ifdef ENABLE_MSR_OPCODES
rS_update <= 0;
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
// CPU asks to insert exception break: "brali r17,0x20"
if(insert_exception)
begin
branch_instr <= 1;
alu_inputA_sel <= `aluA_zero;
alu_inputB_sel <= `aluB_imm;
comparator_fns_sel <= `CMP_one; // force a branch
regfile_input_sel <= `RF_pc;
regD_addr <= `REG_RET_FROM_EXCEPTION;
immediate <= `ADDRESS_EXCEPTION_VECTOR;
$display("DECODE: Inserting OPCODE-EXCEPTION at pc_decode=0x%x, pc_exe=0x%x", pc_decode, pc_exe);
end
else
`endif
`ifdef ENABLE_INTERRUPTS
// when EXECUTE notifies "interrupt in progress", the DECODE module must insert "brali r14,0x10" when
// possible; this is not after a IMM opcode nor in a delay slot. When inserted the interrupt opcode,
// notify EXECUTE that the decode is completed
if(int_ip && !imm_valid && !delay_bit)
begin
branch_instr <= 1;
alu_inputA_sel <= `aluA_zero;
alu_inputB_sel <= `aluB_imm;
comparator_fns_sel <= `CMP_one; // force a branch
regfile_input_sel <= `RF_pc;
regD_addr <= `REG_RET_FROM_INTERRUPT;
immediate <= `ADDRESS_INTERRUPT_VECTOR;
int_dc <= 1; // notify that DECODE is completed
$display("DECODE: Inserting INTERRUPT at pc_decode=0x%x, pc_exe=0x%x", pc_decode, pc_exe);
end
else
`endif
// BIG Case statement here
// see openfire_define.v for definitions
casez (`opcode)
`ADD:
begin
alu_inputC_sel <= `C_bit ? `aluC_carry : `aluC_zero;
update_carry <= ~`K_bit;
end
`SUBTRACT:
begin
update_carry <= ~`K_bit;
if (`U_bit & `CMP_bit & !`IMM_bit) // CMPU
begin
alu_fns_sel <= `ALU_compare_uns;
comparator_fns_sel <= `CMP_dual_inputs;
end
else if (`CMP_bit & !`IMM_bit) // CMP
alu_fns_sel <= `ALU_compare;
else
alu_fns_sel <= `ALU_add;
alu_inputA_sel <= `aluA_ra_bar;
alu_inputC_sel <= `C_bit ? `aluC_carry : `aluC_one;
end
`LOGIC_OR: alu_fns_sel <= `ALU_logic_or;
`LOGIC_AND: alu_fns_sel <= `ALU_logic_and;
`LOGIC_XOR: alu_fns_sel <= `ALU_logic_xor;
`LOGIC_ANDN:
begin
alu_fns_sel <= `ALU_logic_and;
alu_inputB_sel <= `IMM_bit ? `aluB_imm_bar : `aluB_rb_bar;
end
`LOGIC_BIT:
begin
alu_inputC_sel <= `aluC_carry;
update_carry <= 1;
casez (`imm_value)
16'b1: alu_fns_sel <= `ALU_shiftR_arth;
16'b100001: alu_fns_sel <= `ALU_shiftR_c;
16'b1000001: alu_fns_sel <= `ALU_shiftR_log;
16'b1100000: alu_fns_sel <= `ALU_sex8;
16'b1100001: alu_fns_sel <= `ALU_sex16;
endcase
end
`BRANCH_UNCON: // Handles BREAKs as well
begin
branch_instr <= 1;
alu_inputA_sel <= `A_bit ? `aluA_zero : `aluA_pc;
alu_inputB_sel <= `IMM_bit ? `aluB_imm : `aluB_rb;
comparator_fns_sel <= `CMP_one; // force a branch
regfile_input_sel <= `RF_pc;
`ifdef ENABLE_MSR_BIP
update_msr_bip <= ~`D_bit_uncond & `A_bit & `L_bit; // is br[i]al --> break
value_msr_bip <= 1; // BREAK --> MSR[BIP] <= 1
`endif
end
`BRANCH_CON:
begin
branch_instr <= 1;
alu_inputA_sel <= `aluA_pc;
comparator_fns_sel<= `branch_compare;
we_alu_branch <= 1'b0;
end
`ifdef ENABLE_MSR_OPCODES
`SPECIAL_REG: // Handle mfs, mts
begin
if(`is_mfs) // mfs rD,rS --> move rS to ALU input A
begin
casez(`regS_sel_msr) // select corresponding ALU input based on rS
`rS_PC : alu_inputA_sel <= `aluA_pc;
`rS_MSR : alu_inputA_sel <= `aluA_msr;
default: $display("mfs: invalid rS=%x", `regS_sel_msr);
endcase
end
else if(`is_mts) // mts rS,rD (rS is only MSR). Ask EXE to update MSR from rA
rS_update <= 1;
end
`endif
`IMMEDIATE:
begin
we_alu_branch <= 1'b0; // have EXE do nothing
imm_valid <= 1;
imm <= `imm_value;
end
`RETURN: // ignores MSR, exceptions, and interrupts
begin
branch_instr <= 1;
alu_inputB_sel <= `aluB_imm;
comparator_fns_sel<= `CMP_one; // force a branch
we_alu_branch <= 1'b0;
`ifdef ENABLE_MSR_BIP
update_msr_bip <= `BRK_bit; // return from break?
value_msr_bip <= 0; // rtbd? MSR[BIP] <= 0
`endif
`ifdef ENABLE_INTERRUPTS
set_msr_ie <= `INT_bit; // MSR[IE] <= 1 if return from interrupt
`ifdef DEBUG_DECODE
`ifdef ENABLE_EXCEPTIONS
reset_msr_eip <= `EXC_bit; // MSR[EIP] <= 0 if return from exception
`endif
$display("DECODE: RETURN FROM INTERRUPT -- pc_exe=%x", pc_exe);
`endif
`endif
end
`LOAD:
begin
we_alu_branch <= 1'b0;
we_load <= 1'b1;
dmem_input_sel <= `word_size;
regfile_input_sel <= `word_size;
end
`STORE:
begin
we_alu_branch <= 1'b0;
we_store <= 1'b1;
dmem_input_sel <= `word_size;
end
`ifdef FSL_LINK
`FSL:
$display("ERROR! FSL not implemented");
`endif
`ifdef MUL
`MULTIPLY:
begin
alu_fns_sel <= `ALU_multiply;
// 32-bit mult takes several cycles -- do not write to Reg File until complete
we_alu_branch <= 1'b0;
end
`endif
default:
begin
$display("ERROR! Malformed OpCode! 0x%x", `opcode);
`ifdef ENABLE_OPCODE_EXCEPTION
opcode_exception <= 1; // notify EXECUTE that we are in "opcode exception"
`endif
end
endcase
`ifdef DEBUG_DECODE
$display("DECODE: pc_exe=%x, instruction=%x", pc_exe, instruction);
`endif
end
end // end of always@
endmodule
1.1 openfire2/rtl/openfire_define.v
http://www.opencores.org/cvsweb.shtml/openfire2/rtl/openfire_define.v?rev=1.1&content-type=text/x-cvsweb-markup
Index: openfire_define.v
===================================================================
/* MODULE: openfire_define
DESCRIPTION: Contains define statements used for readability.
AUTHOR:
Stephen Douglas Craven
Configurable Computing Lab
Virginia Tech
scraven@v...
REVISION HISTORY:
Revision 0.2, 8/10/2005 SDC
Initial release
Revision 0.3, 26/03/2007 Antonio J. Antón
New tags added for Core/SOC/Peripherals
COPYRIGHT:
Copyright (c) 2005 Stephen Douglas Craven
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. */
`timescale 1ns/100ps
/************* USER MODIFIED SOC OPTIONS ****************/
`define CLK_25MHZ // system clock
`define IO_SIZE 4 // up to 16 IO addresses
// IO memory address (use <<2 at program level)
`define ADDR_SP3_IO 0 // 7SEG + LEDS + SWITCHES + PUSHBUTTONS
`define ADDR_UARTS 1 // uart1/2 status register
`define ADDR_UART1 2 // uart 1 tx/rx
`define ADDR_UART2 3 // uart 2 tx/rx
`define ADDR_PROM 4 // prom control/status/data
`define ADDR_TIMER1 5 // control / set / current
`define ADDR_INT 6 // interrupt enable
`define BAUD_COUNT 13 // 26=115200 at 50mhz, 324=9600 at 50mhz, 13=115200 at 25mhz
`define PROM_SYNC_PATTERN 32'h8F9FAFBF // bit pattern to detect start of file
`define SP3SK_IODEVICES // enables peripherals on SP3SK
`ifdef SP3SK_IODEVICES
`define SP3SK_USERIO // enable GPIO in SP3SK board
`define UART1_ENABLE // enable UART #1
//`define UART2_ENABLE // enable UART #2
`define SP3SK_PROM_DATA // enable user data at the end of FPGA PROM
`define TIMER1_GENERATOR // enable TIMER generator (31 bit + 1 restart/stop bit)
//`define IO_MULTICYCLE // enable multicycle i/o operations
`endif
`define SP3SK_SRAM // enable external 1Mx32 SRAM in SP3SK
`define SP3SK_VGA // enable VGA in SP3SK
`define LOCATION_BRAM 2'b00 // boot ram 0x0000_0000->0x0000_1FFF (8 Kbytes)
`define LOCATION_SRAM 2'b01 // external SRAM 0x0400_0000->0x040F_FFFF (1 Mbyte)
`define LOCATION_BRAM_WRAP 2'b11 // temporary wrap end address space with bootram
`define LOCATION_IOSPACE 2'b10 // 0x08xx_xx<00yy><zz00> yyzz=i/o address
`define LOCATION_VRAM 18'h3_8800 // video ram starts at 0x040E_2000 (end of SRAM)
`define SRAM_BASE_ADDRESS { {32 - `A_SPACE{0}, `LOCATION_SRAM, {`A_SPACE-2{0}} }
`define IO_BASE_ADDRESS { {32 - `A_SPACE{0}, `LOCATION_IOSPACE, {`A_SPACE-2{0}} }
`define VIDEO_BASE_ADDRESS { {32 - `A_SPACE{0}, `LOCATION_SRAM, `LOCATION_VRAM }
/***********************************
* User-modified Processor Options *
***********************************/
// enable opcode dissasembler in simulador
`define OPCODE_DISSASEMBLER
`define DEBUG_SIMPLE_MEMORY_DUMP
//`define DEBUG_FETCH
//`define DEBUG_DECODE
//`define DEBUG_EXECUTE
`define DEBUG_FILE_SRAM "..\\sw\\sample2\\sample.rom" // ROM file to be loaded at SRAM base
`define MAX_SIMULATION_SRAM 4096 // in 32 bit words
`define ENABLE_INTERRUPTS // enable interrupt handling & MSR[IE] bit
//`define ENABLE_MSR_BIP // enables MSR[BIP] processing
`define ENABLE_MSR_OPCODES // opcodes to manage MS registers (mfs, msrclr, msrset, mts)
//`define ENABLE_EXCEPTIONS // enable exception handling & MSR[EIP] bit
`ifdef ENABLE_EXCEPTIONS
//`define ENABLE_ALIGNMENT_EXCEPTION // generates exception on memory read/write unalignment
//`define ENABLE_OPCODE_EXCEPTION // generates exception on invalid opcode
`endif
//`define FSL_LINK
// Optional CMPU instruction requires a 32-bit comparator
// To enable CMPU support, leave only one of the following two options uncommented
// To disable CMPU support (for faster, smaller core) comment out both options
//`define FAST_CMP // use fast, but larger comparator for CMPU instr
`define CMP // include comparator for CMPU instr
// Specify address space size
// If using a unified memory (data and instr in same memory) both memory sizes must be the same
`define IM_SIZE 28 // width of instruction memory space; 12 => 2^12 words = 16kB
`define DM_SIZE 28 // width of data memory space; 12 => 2^12 words = 16kB
// Specify addressible space -- easiest just to set to max of IM_SIZE and DM_SIZE
`define A_SPACE 28 // width of addressible space, used for PC (must be =< D_WIDTH)
// Optional HW multiplier uses 3 Xilinx Block MULTS for 32-bit multiply
`define MUL // include HW multiplier
//`define DIV // include HW divider **TODO**
//`define BS // include HW barrel shift **TODO**
// End User-modified Processor Options
// Sets define statements for datapath -- DO NOT TOUCH ANYTHING BELOW THIS LINE (UNLESS ADDING INSTRUCTIONS)
`define NoOp 32'h8000_0000 // NoOp instruction
`define IntOp 32'hB9CC_0010 // Interrupt Opcode is: brali r14,0x10
//`define ExcptOp 32'h // Exception Opcode is: brali r17,0x20
//`define BreakOp 32'h // Break Opcode is: brali r16,0x18
`define REG_RET_FROM_INTERRUPT 14 // return address from interrupt in r14
`define ADDRESS_INTERRUPT_VECTOR 32'h10 // interrupt vector is at 0x10
`define REG_RET_FROM_BREAK 16 // return address from break in r16
`define ADDRESS_BREAK_VECTOR 32'h18 // break vector is at 0x18
`define REG_RET_FROM_EXCEPTION 17 // return address from exception in r17
`define ADDRESS_EXCEPTION_VECTOR 32'h20 // exception vector is at 0x20
// Instruction Fields
`define opcode instruction[31:26]
`define regD_sel instruction[25:21]
`define regA_sel instruction[20:16]
`define regB_sel instruction[15:11]
`define imm_value instruction[15:0]
`define branch_compare instruction[23:21]
`define word_size instruction[27:26]
`define fsl_get_put instruction[15]
//`define regS_sel_mfs instruction[13:0]
//`define regS_sel_mts instruction[2:0]
`define regS_sel_msr instruction[3:0]
// Special opcode bits
`define CMP_bit instruction[0] // differentiate CMP/CMPU instr from SUBSTRACT
`define C_bit instruction[27] // Use Carry bit
`define K_bit instruction[28] // if 1, do not update Carry bit in MSR
`define D_bit_uncond instruction[20] // Delay bit for unconditional branchs
`define D_bit_cond instruction[25] // Delay bit for conditional branchs
`define A_bit instruction[19] // Absolute addressing for branch
`define L_bit instruction[18] // Link bit, stores PC in rD for branchs
`define U_bit instruction[1] // Unsigned bit for Compare instructions
`define IMM_bit instruction[29] // IMMediate
`define uncond_branch (({instruction[31], instruction[30], instruction[28], instruction[27], instruction[26]} == 5'b10110 ) | ({instruction[31], instruction[30], instruction[28], instruction[27], instruction[26]} == 5'b10101 ))
`define cond_branch ({instruction[31], instruction[30], instruction[28], instruction[27], instruction[26]} == 5'b10111 )
`define FSL_nblock instruction[14]
`define FSL_control instruction[13]
`define BRK_bit instruction[22] // break bit for returns
`define INT_bit instruction[21] // interrupt bit
`define EXC_bit instruction[23] // exception bit
`define is_SEXT16 (instruction[6:0] == 7'b1100001) // functions for LOGICAL_BIT opcode
`define is_SEXT8 (instruction[6:0] == 7'b1100000)
`define is_SRA (instruction[6:0] == 7'b0000001)
`define is_SRC (instruction[6:0] == 7'b0100001)
`define is_SRL (instruction[6:0] == 7'b1000001)
`define is_mfs (instruction[15:14] == 3'b10)
`define msr_clrset instruction[16] //1=clr, 0=set
`define is_mts (instruction[15:14] == 2'b11)
// Instructions
`define ADD 6'b00???0 // 00ikc0 add[i][k][c]
`define LOGIC_AND 6'b10?001 // 10i001 and[i]
`define LOGIC_ANDN 6'b10?011 // 10i011 andn[i]
`define BRANCH_CON 6'b10?111 // 10i111 d b<cond>[i][d]
`define BRANCH_UNCON 6'b10?110 // 10i110 <rD> dal br[a][i][l][d] Break is actually BRAL
`define BREAK 6'b10?110 // brk=bral
`define BARREL_SHIFT 6'b01?001 // 01i001 <rD><rA><rB> st bs<l|r><l|a>[i] s=1/0=left/right, t=1/0=arithmetic/logical
`define COMPARE 6'b000101 // same as SUBSTRACT with opcode[0]=1
`define FSL 6'b011011 // 011011 <rd> 00000 <g|p>nc....<fslN 3bits> n=0 block, c=control [n][c]get/[n][c]put
`define FP_OP 6'b010110 // floating point instructions
`define DIVIDE 6'b01?010 // 01i010 <rd> <rA> <rB> bit[30]=1=unsigned idiv[u]
`define IMMEDIATE 6'b101100 // 101100 imm
`define LOAD 6'b11?0?? // 11i0wh wh=00: lbu[i], wh=01: lhu[i], wh=10: lw[i]
`define SPECIAL_REG 6'b100101 // **todo**
`define MULTIPLY 6'b01?000 // 01i000 mul[i]
`define LOGIC_OR 6'b10?000 // 10i000 or[i]
`define PATTERN_CMP 6'b100000 // **todo**
`define SUBTRACT 6'b00???1 // 00ikc1 rsub[i][k][c]
`define RETURN 6'b101101 // 101101 10ebi <rA> rt<e|b|i|s>d (ebi=0 --> s)
`define STORE 6'b11?1?? // 11i1wh wh=00: sb[i], wh=01: sh[i], wh=10: sl[i]
`define LOGIC_BIT 6'b100100 // 100100 and 7 lower bits sext16,sext8,sra,src,srl,wdc, wic
`define LOGIC_XOR 6'b10?010 // 10i010 xor[i]
// ALU Functions
`define ALU_add 4'd0
`define ALU_compare_uns 4'd1 // CMPU (unsigned Compare)
`define ALU_logic_or 4'd2
`define ALU_logic_and 4'd3
`define ALU_logic_xor 4'd4
`define ALU_sex8 4'd5
`define ALU_sex16 4'd6
`define ALU_shiftR_arth 4'd7
`define ALU_shiftR_log 4'd8
`define ALU_shiftR_c 4'd9
`define ALU_compare 4'd10 // CMP
`define ALU_multiply 4'd11
`define ALU_divide 4'd12 // **TODO**
`define ALU_barrel 4'd13 // **TODO**
// ALU inputs
`define aluA_ra 3'd0 // size increased to acommodate further inputs
`define aluA_ra_bar 3'd1 // from special registers
`define aluA_pc 3'd2
`define aluA_zero 3'd3
`define aluA_msr 3'd4
`define aluB_rb 2'd0
`define aluB_imm 2'd1
`define aluB_rb_bar 2'd2
`define aluB_imm_bar 2'd3
`define aluC_zero 2'd0
`define aluC_one 2'd1
`define aluC_carry 2'd2
// Comparator Functions
`define CMP_equal 3'd0
`define CMP_not_equal 3'd1
`define CMP_lessthan 3'd2
`define CMP_lt_equal 3'd3
`define CMP_greaterthan 3'd4
`define CMP_gt_equal 3'd5
`define CMP_one 3'd6
`define CMP_dual_inputs 3'd7 // compare regA and regB for CMPU instr
// RegFile Input Select (width increased)
`define RF_dmem_byte 4'd0 // same as `word_size
`define RF_dmem_halfword 4'd1 // same as `word_size
`define RF_dmem_wholeword 4'd2 // same as `word_size
`define RF_alu_result 4'd3
`define RF_pc 4'd4
`define RF_zero 4'd5
`define RF_fsl 4'd6
`define RF_msr 4'd7
`define RF_ear 4'd8 //todo
`define RF_esr 4'd9 //todo
`define RF_btr 4'd10 //todo
// DMEM Input Select
`define DM_byte 2'd0
`define DM_halfword 2'd1
`define DM_wholeword 2'd2
// MSR bits
`define MSR_BL_Ena 0 // bus lock enable
`define MSR_IE 1 // interrupt enable
`define MSR_C 2 // carry
`define MSR_BIP 3 // break in progress
`define MSR_FSL_Err 4 // FSL error
`define MSR_IC_Ena 5 // Instruction Cache
`define MSR_DZ 6 // Division by Zero
`define MSR_DC_Ena 7 // Data Cache
`define MSR_E_Ena 8 // Exception enable
`define MSR_EIP 9 // Exception in progress
`define MSR_PVR 10 // Procesor Version Register exists
// MSR registers
`define rS_PC 4'h0
`define rS_MSR 4'h1
`define rS_EAR 4'h3
`define rS_ESR 4'h5
`define rS_BTR 4'hB
1.1 openfire2/rtl/openfire_execute.v
http://www.opencores.org/cvsweb.shtml/openfire2/rtl/openfire_execute.v?rev=1.1&content-type=text/x-cvsweb-markup
Index: openfire_execute.v
===================================================================
/* MODULE: openfire_execute
DESCRIPTION: The execute module instantiates the alu and comparator and
updates the Machine Status Register (MSR). This module produces a status
signal, instr_complete, when the currently executing instruction is finished.
TO DO:
- Add interrupt handling
- Add exception handling
- Complete MSR
- Add all other special registers: EAR, ESR, ESS
- Add OPB interface
AUTHOR:
Stephen Douglas Craven
Configurable Computing Lab
Virginia Tech
scraven@v...
REVISION HISTORY:
Revision 0.2, 8/10/2005 SDC
Initial release
Revision 0.3, 12/17/2005 SDC
Fixed PC size bug and CMP bug for case when both rA and rB are negative.
Revision 0.4 27/03/2007 Antonio J. Anton
Memory handshaking protocol
Removed memory read/write alignment code
Interrupt handling
Exception handling
MSR register handling
COPYRIGHT:
Copyright (c) 2005 Stephen Douglas Craven
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
`include "openfire_define.v"
module openfire_execute (
`ifdef ENABLE_MSR_BIP
update_msr_bip, value_msr_bip,
`endif
`ifdef ENABLE_INTERRUPTS
interrupt, int_ip, int_dc, set_msr_ie,
`endif
`ifdef ENABLE_MSR_OPCODES
rS_update,
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
opcode_exception,
`endif
`ifdef ENABLE_EXCEPTIONS
reset_msr_eip,
`endif
`ifdef ENABLE_ALIGNMENT_EXCEPTION
dmem_alignment_exception,
`endif
clock, reset, stall, // top level
immediate, pc_exe, alu_inputA_sel, alu_inputB_sel, // inputs
alu_inputC_sel, alu_fns_sel, comparator_fns_sel,
we_load, we_store, regA,
regB, regD, update_carry, branch_instr,
alu_result, pc_branch, branch_taken, // outputs
we_regfile, dmem_addr,
dmem_data_out, instr_complete, dmem_done,
dmem_we, dmem_re
);
// From top level -- all active high unless otherwise noted
input stall;
input reset;
input clock;
// From DECODE module
input [31:0] immediate;
input [`A_SPACE+1:0] pc_exe; // pc for use by EXECUTE
input [2:0] alu_inputA_sel;
input [1:0] alu_inputB_sel;
input [1:0] alu_inputC_sel;
input [3:0] alu_fns_sel;
input [2:0] comparator_fns_sel;
input we_load; // write_en for regfile on Load
input we_store; // we on DMEM on Store
input update_carry;
input branch_instr;
input dmem_done;
output dmem_re;
output dmem_we;
`ifdef ENABLE_MSR_BIP
input update_msr_bip;
input value_msr_bip;
`endif
`ifdef ENABLE_INTERRUPTS
input interrupt;
output int_ip;
input int_dc;
input set_msr_ie;
`endif
`ifdef ENABLE_MSR_OPCODES
input rS_update;
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
input opcode_exception;
`endif
`ifdef ENABLE_EXCEPTIONS
input reset_msr_eip;
output insert_exception;
`endif
`ifdef ENABLE_ALIGNMENT_EXCEPTION
input dmem_alignment_exception;
`endif
// From REGFILE
input [31:0] regA;
input [31:0] regB;
input [31:0] regD;
output [31:0] alu_result;
output [`A_SPACE+1:0] pc_branch;
output branch_taken;
output we_regfile; // we for load and alu
output [31:0] dmem_addr;
output [31:0] dmem_data_out;
output instr_complete; // status of execution, active high
// register all outputs EXCEPT:
// - branch_taken and pc_branch -- registered in FETCH
// - alu_result -- REGFILE registers
// - dmem_addr -- DMEM registers
// - instr_complete -- needed before rise of clock by PIPLINE_CTRL
assign dmem_data_out = regD;
// internal registers
reg [31:0] MSR; // **TODO** Working: C, BIP, IE
reg [31:0] alu_a_input;
reg [31:0] alu_b_input;
reg alu_c_input;
reg MSB_signed_compare;
wire alu_multicycle_instr;
wire alu_multicycle_instr_complete;
wire multicycle_instr;
wire multicycle_instr_complete;
wire c_out;
wire compare_out;
wire [31:0] alu_out_internal;
wire [31:0] extended_pc; // PC with leading zeros addded
`ifdef ENABLE_EXCEPTIONS
reg insert_exception; // to ask DECODE to insert "brali r17,0x20"
wire exception = // 1 if any exception happened
`ifdef ENABLE_ALIGNMENT_EXCEPTION
dmem_alignment_exception |
`endif
`ifdef ENABLE_OPCODE_EXCEPTION
opcode_exception |
`endif
0;
`endif
`ifdef ENABLE_INTERRUPTS
// this code is to signal an interrupt when interrupts are enabled (MSR[IE]=1)
reg int_requested;
always @(interrupt or MSR[`MSR_IE]) // if interrupt == 1, then raise a request for
begin // clear the request based on clear_interrupt
if(interrupt && MSR[`MSR_IE]) int_requested <= 1;
else if(!MSR[`MSR_IE]) int_requested <= 0;
end
reg int_ip; // interrupt in progress
wire can_interrupt = // cpu can be interrupted if...
`ifdef ENABLE_EXCEPTION
~MSR[`MSR_EIP] & // no Exception in Progress
`endif
`ifdef ENABLE_MSR_BIP
~MSR[`MSR_BIP] & ( // no Break in Progress
`endif
~int_ip | set_msr_ie // not interrupt in progress
`ifdef ENABLE_MSR_BIP // and interrupts are enabled
)
`endif
;
`endif
assign branch_taken = branch_instr ? compare_out : 0;
assign pc_branch = alu_out_internal[`A_SPACE+1:0]; // ALU calculates next instr address
// instr_complete is always high EXCEPT for optional MUL (alu_multicycle_instr)
// all other instructions currently implemented are single-cycle execution except
// load / store that are multicycle (controlled by dmem_done)
// also re/we enable are only valid if EXECUTE is not stalled
assign dmem_we = we_store & ~stall;
assign dmem_re = we_load & ~stall;
assign memory_instr = we_load | we_store;
assign memory_instr_complete = memory_instr & dmem_done;
assign multicycle_instr = memory_instr | alu_multicycle_instr;
assign multicycle_instr_complete = memory_instr_complete | alu_multicycle_instr_complete;
assign instr_complete = ~multicycle_instr | multicycle_instr_complete;
assign we_regfile = (we_load & dmem_done) | alu_multicycle_instr_complete;
// for CMP/CMPU
// use comparator output for CMPU
// use ALU output for CMP -- signed comparison result is a function of input signs and o |