LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Find Resources
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Cvs-checkins > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: cvs at opencores.org<cvs@o...>
    Date: Wed Mar 28 23:30:27 CEST 2007
    Subject: [cvs-checkins] MODIFIED: openfire2 ...
    Top
    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