URL
https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk
Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc
[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_processor/] [mor1kx-5.0/] [rtl/] [verilog/] [mor1kx_rf_espresso.v] - Rev 48
Compare with Previous | Blame | View Log
/* **************************************************************************** This Source Code Form is subject to the terms of the Open Hardware Description License, v. 1.0. If a copy of the OHDL was not distributed with this file, You can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt Description: Register file for espresso pipeline We get addresses for A and B read directly in from the instruction bus Copyright (C) 2012 Authors Author(s): Julius Baxter <juliusbaxter@gmail.com> ***************************************************************************** */ `include "mor1kx-defines.v" module mor1kx_rf_espresso (/*AUTOARG*/ // Outputs rfa_o, rfb_o, // Inputs clk, rst, rfd_adr_i, rfa_adr_i, rfb_adr_i, rf_we_i, rf_re_i, result_i ); parameter OPTION_RF_ADDR_WIDTH = 5; parameter OPTION_RF_WORDS = 32; parameter OPTION_OPERAND_WIDTH = 32; input clk, rst; // GPR addresses // These two directly from insn bus input [OPTION_RF_ADDR_WIDTH-1:0] rfd_adr_i; input [OPTION_RF_ADDR_WIDTH-1:0] rfa_adr_i; // This one from the decode stage input [OPTION_RF_ADDR_WIDTH-1:0] rfb_adr_i; // WE strobe from control stage input rf_we_i; // Read enable strobe input rf_re_i; input [OPTION_OPERAND_WIDTH-1:0] result_i; output [OPTION_OPERAND_WIDTH-1:0] rfa_o; output [OPTION_OPERAND_WIDTH-1:0] rfb_o; wire [OPTION_OPERAND_WIDTH-1:0] rfa_o_mux; wire [OPTION_OPERAND_WIDTH-1:0] rfb_o_mux; wire [OPTION_OPERAND_WIDTH-1:0] rfa_ram_o; wire [OPTION_OPERAND_WIDTH-1:0] rfb_ram_o; reg [OPTION_OPERAND_WIDTH-1:0] result_last; reg [OPTION_RF_ADDR_WIDTH-1:0] rfd_last; reg [OPTION_RF_ADDR_WIDTH-1:0] rfd_r; reg [OPTION_RF_ADDR_WIDTH-1:0] rfa_r; reg [OPTION_RF_ADDR_WIDTH-1:0] rfb_r; wire rfa_o_use_last; wire rfb_o_use_last; reg rfa_o_using_last; reg rfb_o_using_last; wire rfa_rden; wire rfb_rden; wire rf_wren; // Read enables to make sure the last write-while-read propagates through // once the use_last signal goes away (we might rely on the value remaining // what it was, but the last registered result might get written again) so // this forces a read to get that value out. wire rfa_rden_for_last; wire rfb_rden_for_last; // Avoid read-write // Use when this instruction actually will write to its destination // register. assign rfa_o_use_last = (rfd_last == rfa_r); assign rfb_o_use_last = (rfd_last == rfb_r); assign rfa_o = rfa_o_use_last ? result_last : rfa_ram_o; assign rfb_o = rfb_o_use_last ? result_last : rfb_ram_o; assign rfa_rden_for_last = (rfa_o_use_last & !rf_re_i); assign rfb_rden_for_last = (rfb_o_use_last & !rf_re_i); assign rfa_rden = rf_re_i | rfa_rden_for_last; assign rfb_rden = rf_re_i | rfb_rden_for_last; assign rf_wren = rf_we_i; always @(posedge clk `OR_ASYNC_RST) if (rst) begin rfa_r <= 0; rfb_r <= 0; rfd_r <= 0; end else if (rf_re_i) begin rfa_r <= rfa_adr_i; rfb_r <= rfb_adr_i; rfd_r <= rfd_adr_i; end always @(posedge clk `OR_ASYNC_RST) if (rst) rfd_last <= 0; else if (rf_wren) rfd_last <= rfd_adr_i; always @(posedge clk `OR_ASYNC_RST) if (rst) result_last <= 0; else if (rf_wren) result_last <= result_i; always @(posedge clk `OR_ASYNC_RST) if (rst) begin rfa_o_using_last <= 0; rfb_o_using_last <= 0; end else begin if (!rfa_o_using_last) rfa_o_using_last <= rfa_o_use_last & !rfa_rden; else if (rfa_rden) rfa_o_using_last <= 0; if (!rfb_o_using_last) rfb_o_using_last <= rfb_o_use_last & !rfb_rden; else if (rfb_rden) rfb_o_using_last <= 0; end mor1kx_simple_dpram_sclk #( .ADDR_WIDTH (OPTION_RF_ADDR_WIDTH), .DATA_WIDTH (OPTION_OPERAND_WIDTH), .ENABLE_BYPASS (0) ) rfa ( .clk (clk), .dout (rfa_ram_o), .raddr (rfa_adr_i), .re (rfa_rden), .waddr (rfd_adr_i), .we (rf_wren), .din (result_i) ); mor1kx_simple_dpram_sclk #( .ADDR_WIDTH (OPTION_RF_ADDR_WIDTH), .DATA_WIDTH (OPTION_OPERAND_WIDTH), .ENABLE_BYPASS (0) ) rfb ( .clk (clk), .dout (rfb_ram_o), .raddr (rfb_adr_i), .re (rfb_rden), .waddr (rfd_adr_i), .we (rf_wren), .din (result_i) ); endmodule // mor1kx_execute_alu