mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 12:07:53 -04:00
Adds support for more than 2 regfile read ports
Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
parent
8008679a7a
commit
2339ae182c
3 changed files with 17 additions and 125 deletions
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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,
|
||||
|
|
|
@ -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)),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue