Adds support for more than 2 regfile read ports

Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
Eric Matthews 2022-11-14 11:38:15 -05:00
parent 8008679a7a
commit 2339ae182c
3 changed files with 17 additions and 125 deletions

View file

@ -1,109 +0,0 @@
/*
* Copyright © 2019 Eric Matthews, Lesley Shannon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial code developed under the supervision of Dr. Lesley Shannon,
* Reconfigurable Computing Lab, Simon Fraser University.
*
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
import cva5_config::*;
import cva5_types::*;
module reg_inuse (
input logic clk,
input logic rst,
input logic clr,
input logic [4:0] rs1_addr,
input logic [4:0] rs2_addr,
input logic [4:0] issued_rd_addr,
input logic [4:0] retired_rd_addr,
input logic issued,
input logic retired,
output logic rs1_inuse,
output logic rs2_inuse
);
////////////////////////////////////////////////////
//Memory organized as 2 sets of dual-ported memories
logic bankA [32];
logic bankB [32];
logic [4:0] w_clear;
logic [4:0] wb_rd_addr_muxed;
logic wb_collision;
////////////////////////////////////////////////////
//Implementation
//////////////////////////////////////////
//Initialize to all inuse (0,1) for simulation,
//will be cleared by GC after reset in hardware
// synthesis translate_off
initial bankA = '{default: 0};
initial bankB = '{default: 0};
// synthesis translate_on
//After reset, clear is held for at least 32 cycles to reset memory block
assign wb_rd_addr_muxed = clr ? w_clear : retired_rd_addr;
//reset is for simulation purposes only, not needed for actual design
always_ff @ (posedge clk) begin
if (rst)
w_clear <= 0;
else
w_clear <= w_clear + 5'(clr);
end
assign wb_collision = retired && (issued_rd_addr == retired_rd_addr);
always_ff @ (posedge clk) begin
if (issued)
bankA[issued_rd_addr] <= wb_collision ? ~bankA[wb_rd_addr_muxed] : ~bankB[issued_rd_addr];
end
always_ff @ (posedge clk) begin
if (retired | clr)
bankB[wb_rd_addr_muxed] <= bankA[wb_rd_addr_muxed];
end
assign rs1_inuse = bankA[rs1_addr] ^ bankB[rs1_addr];
assign rs2_inuse = bankA[rs2_addr] ^ bankB[rs2_addr];
////////////////////////////////////////////////////
//End of Implementation
////////////////////////////////////////////////////
////////////////////////////////////////////////////
//Assertions
////////////////////////////////////////////////////
//Simulation Only
// synthesis translate_off
logic sim_inuse [32];
always_comb begin
foreach (sim_inuse[i])
sim_inuse[i] = bankA[i] ^ bankB[i];
end
// synthesis translate_on
endmodule

View file

@ -54,7 +54,8 @@ module register_file
logic decode_inuse [REGFILE_READ_PORTS];
logic decode_inuse_r [REGFILE_READ_PORTS];
genvar i;
phys_addr_t inuse_read_addr [REGFILE_READ_PORTS*2];
logic inuse [REGFILE_READ_PORTS*2];
////////////////////////////////////////////////////
//Implementation
@ -62,7 +63,14 @@ module register_file
//Phys register inuse
//toggle ports: decode advance, single-cycle/fetch_flush, multi-cycle commit
//read ports: rs-decode, rs-issue
always_comb begin
for (int i = 0; i < REGFILE_READ_PORTS; i++) begin
inuse_read_addr[i] = decode_phys_rs_addr[i];
inuse_read_addr[i+REGFILE_READ_PORTS] = rf_issue.phys_rs_addr[i];
decode_inuse[i] = inuse[i];
rf_issue.inuse[i] = inuse[i+REGFILE_READ_PORTS];
end
end
toggle_memory_set # (
.DEPTH (64),
.NUM_WRITE_PORTS (3),
@ -84,18 +92,8 @@ module register_file
rf_issue.phys_rd_addr,
commit[1].phys_addr
}),
.read_addr ('{
decode_phys_rs_addr[RS1],
decode_phys_rs_addr[RS2],
rf_issue.phys_rs_addr[RS1],
rf_issue.phys_rs_addr[RS2]
}),
.in_use ('{
decode_inuse[RS1],
decode_inuse[RS2],
rf_issue.inuse[RS1],
rf_issue.inuse[RS2]
})
.read_addr (inuse_read_addr),
.in_use (inuse)
);
always_ff @ (posedge clk) begin
if (decode_advance)
@ -105,7 +103,7 @@ module register_file
//Register Banks
//Implemented in seperate module as there is not universal tool support for inferring
//arrays of memory blocks.
generate for (i = 0; i < CONFIG.NUM_WB_GROUPS; i++) begin : register_file_gen
generate for (genvar i = 0; i < CONFIG.NUM_WB_GROUPS; i++) begin : register_file_gen
register_bank #(.NUM_READ_PORTS(REGFILE_READ_PORTS))
reg_group (
.clk, .rst,

View file

@ -168,7 +168,10 @@ module renamer
assign spec_table_next = spec_table_next_mux[spec_table_sel];
assign spec_table_read_addr[0] = spec_table_write_index;
assign spec_table_read_addr[1:REGFILE_READ_PORTS] = '{decode.rs_addr[RS1], decode.rs_addr[RS2]};
always_comb begin
for (int i = 0; i < REGFILE_READ_PORTS; i++)
spec_table_read_addr[i+1] = decode.rs_addr[i];
end
lutram_1w_mr #(
.WIDTH($bits(spec_table_t)),