mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 03:57:18 -04:00
Restructure registerfile muxes
Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
parent
2e77b891d5
commit
1e9343a91c
6 changed files with 76 additions and 129 deletions
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2017-2020 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>
|
||||
*/
|
||||
|
||||
module register_bank
|
||||
|
||||
import cva5_config::*;
|
||||
import riscv_types::*;
|
||||
import cva5_types::*;
|
||||
|
||||
#(
|
||||
parameter NUM_READ_PORTS = 2
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
|
||||
//Writeback
|
||||
input phys_addr_t write_addr,
|
||||
input logic [31:0] new_data,
|
||||
input logic commit,
|
||||
|
||||
//Issue
|
||||
input phys_addr_t read_addr [NUM_READ_PORTS],
|
||||
input logic read_en,
|
||||
output logic [31:0] data [NUM_READ_PORTS]
|
||||
);
|
||||
|
||||
(* ramstyle = "MLAB, no_rw_check", ram_style = "distributed" *) logic [31:0] register_file_bank [64];
|
||||
////////////////////////////////////////////////////
|
||||
//Implementation
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Register File
|
||||
//Assign zero to r0 and initialize all registers to zero for simulation
|
||||
initial register_file_bank = '{default: 0};
|
||||
always_ff @ (posedge clk) begin
|
||||
if (commit)
|
||||
register_file_bank[write_addr] <= new_data;
|
||||
end
|
||||
|
||||
generate for (genvar i = 0; i < NUM_READ_PORTS; i++)
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst | (~|read_addr[i] & read_en))
|
||||
data[i] <= 0;
|
||||
else if (read_en)
|
||||
data[i] <= register_file_bank[read_addr[i]];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
//write_to_zero_reg_assertion:
|
||||
// assert property (@(posedge clk) disable iff (rst) !(commit & write_addr == 0))
|
||||
// else $error("Write to zero reg occured!");
|
||||
|
||||
endmodule
|
|
@ -48,11 +48,13 @@ module register_file
|
|||
//Writeback
|
||||
input wb_packet_t commit [CONFIG.NUM_WB_GROUPS]
|
||||
);
|
||||
typedef logic [31:0] rs_data_set_t [REGFILE_READ_PORTS];
|
||||
rs_data_set_t rs_data_set [CONFIG.NUM_WB_GROUPS];
|
||||
typedef logic [31:0] rs_data_t [REGFILE_READ_PORTS];
|
||||
rs_data_t regfile_rs_data [CONFIG.NUM_WB_GROUPS];
|
||||
rs_data_t regfile_rs_data_r;
|
||||
rs_data_t commit_rs_data [CONFIG.NUM_WB_GROUPS];
|
||||
logic bypass [REGFILE_READ_PORTS];
|
||||
|
||||
logic decode_inuse [REGFILE_READ_PORTS];
|
||||
logic decode_inuse_r [REGFILE_READ_PORTS];
|
||||
|
||||
phys_addr_t inuse_read_addr [REGFILE_READ_PORTS*2];
|
||||
logic inuse [REGFILE_READ_PORTS*2];
|
||||
|
@ -97,52 +99,69 @@ module register_file
|
|||
.read_addr (inuse_read_addr),
|
||||
.in_use (inuse)
|
||||
);
|
||||
always_ff @ (posedge clk) begin
|
||||
if (decode_advance)
|
||||
decode_inuse_r <= decode_inuse;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Register Banks
|
||||
//Implemented in seperate module as there is not universal tool support for inferring
|
||||
//arrays of memory blocks.
|
||||
//LUTRAM implementation
|
||||
//Read in decode stage, writeback groups muxed and output registered per regfile read port
|
||||
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,
|
||||
.write_addr(commit[i].phys_addr),
|
||||
.new_data(commit[i].data),
|
||||
.commit(commit[i].valid & ~gc.writeback_supress),
|
||||
.read_addr(decode_phys_rs_addr),
|
||||
.read_en(decode_advance),
|
||||
.data(rs_data_set[i])
|
||||
);
|
||||
lutram_1w_mr #(.WIDTH(32), .DEPTH(64), .NUM_READ_PORTS(REGFILE_READ_PORTS))
|
||||
register_file_bank (
|
||||
.clk,
|
||||
.waddr(commit[i].phys_addr),
|
||||
.raddr(decode_phys_rs_addr),
|
||||
.ram_write(commit[i].valid & ~gc.writeback_supress),
|
||||
.new_ram_data(commit[i].data),
|
||||
.ram_data_out(regfile_rs_data[i])
|
||||
);
|
||||
end endgenerate
|
||||
|
||||
generate for (genvar i = 0; i < REGFILE_READ_PORTS; i++) begin : register_file_ff_gen
|
||||
always_ff @ (posedge clk) begin
|
||||
if ((~|decode_phys_rs_addr[i] & decode_advance))
|
||||
regfile_rs_data_r[i] <= '0;
|
||||
else if (decode_advance)
|
||||
regfile_rs_data_r[i] <= regfile_rs_data[decode_rs_wb_group[i]][i];
|
||||
end
|
||||
end endgenerate
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Register File Muxing
|
||||
logic bypass [REGFILE_READ_PORTS];
|
||||
|
||||
rs_data_set_t bypass_set [CONFIG.NUM_WB_GROUPS];
|
||||
wb_packet_t commit_r [REGFILE_READ_PORTS][CONFIG.NUM_WB_GROUPS];
|
||||
|
||||
//Bypass registers
|
||||
//(per wb group and per read port)
|
||||
always_ff @ (posedge clk) begin
|
||||
for (int i = 0; i < REGFILE_READ_PORTS; i++) begin
|
||||
if (decode_advance | rf_issue.inuse[i]) begin
|
||||
bypass <= decode_advance ? decode_inuse : decode_inuse_r;
|
||||
commit_r[i] <= commit;
|
||||
end
|
||||
end
|
||||
for (int i = 0; i < CONFIG.NUM_WB_GROUPS; i++)
|
||||
for (int j = 0; j < REGFILE_READ_PORTS; j++)
|
||||
if (decode_advance | rf_issue.inuse[j])
|
||||
commit_rs_data[i][j] <= commit[i].data;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Register File Muxing
|
||||
//Output mux per read port: bypass wb_group registers with registerfile data a
|
||||
localparam MUX_W = $clog2(CONFIG.NUM_WB_GROUPS+1);
|
||||
|
||||
typedef logic [31:0] issue_data_mux_t [2**MUX_W];
|
||||
issue_data_mux_t issue_data_mux [REGFILE_READ_PORTS];
|
||||
logic [MUX_W-1:0] issue_sel [REGFILE_READ_PORTS];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
for (int i = 0; i < REGFILE_READ_PORTS; i++)
|
||||
if (decode_advance)
|
||||
issue_sel[i] <= decode_inuse[i] ? decode_rs_wb_group[i] : (MUX_W)'(2**MUX_W-1);
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
for (int i = 0; i < REGFILE_READ_PORTS; i++) begin
|
||||
issue_data_mux[i] = '{default: 'x};
|
||||
issue_data_mux[i][2**MUX_W-1] = regfile_rs_data_r[i];
|
||||
for (int j = 0; j < CONFIG.NUM_WB_GROUPS; j++) begin
|
||||
bypass_set[j][i] = bypass[i] ? commit_r[i][j].data : rs_data_set[j][i];
|
||||
issue_data_mux[i][j] = commit_rs_data[j][i];
|
||||
end
|
||||
rf_issue.data[i] = bypass_set[rf_issue.rs_wb_group[i]][i];
|
||||
end
|
||||
end
|
||||
|
||||
always_comb for (int i = 0; i < REGFILE_READ_PORTS; i++)
|
||||
rf_issue.data[i] = issue_data_mux[i][issue_sel[i]];
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
|
|
|
@ -135,8 +135,8 @@ module cva5_sim
|
|||
H : 32'h87FFFFFF
|
||||
},
|
||||
ICACHE : '{
|
||||
LINES : 512,
|
||||
LINE_W : 4,
|
||||
LINES : 256,
|
||||
LINE_W : 8,
|
||||
WAYS : 2,
|
||||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 0,
|
||||
|
@ -155,9 +155,9 @@ module cva5_sim
|
|||
H : 32'h8FFFFFFF
|
||||
},
|
||||
DCACHE : '{
|
||||
LINES : 1024,
|
||||
LINE_W : 4,
|
||||
WAYS : 1,
|
||||
LINES : 256,
|
||||
LINE_W : 8,
|
||||
WAYS : 2,
|
||||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 1,
|
||||
NON_CACHEABLE : '{
|
||||
|
@ -458,13 +458,15 @@ module cva5_sim
|
|||
genvar i, j;
|
||||
generate for (i = 0; i < 32; i++) begin : gen_reg_file_sim
|
||||
for (j = 0; j < NEXYS_CONFIG.NUM_WB_GROUPS; j++) begin
|
||||
if (FPGA_VENDOR == XILINX)
|
||||
if (FPGA_VENDOR == XILINX) begin
|
||||
assign translation[i] = cpu.renamer_block.spec_table_ram.xilinx_gen.ram[i];
|
||||
else if (FPGA_VENDOR == INTEL)
|
||||
assign sim_registers_unamed_groups[j][i] =
|
||||
cpu.register_file_block.register_file_gen[j].register_file_bank.xilinx_gen.ram[translation[i].phys_addr];
|
||||
end else if (FPGA_VENDOR == INTEL) begin
|
||||
assign translation[i] = cpu.renamer_block.spec_table_ram.intel_gen.lutrams[0].write_port.ram[i];
|
||||
|
||||
assign sim_registers_unamed_groups[j][i] =
|
||||
cpu.register_file_block.register_file_gen[j].reg_group.register_file_bank[translation[i].phys_addr];
|
||||
assign sim_registers_unamed_groups[j][i] =
|
||||
cpu.register_file_block.register_file_gen[j].register_file_bank.intel_gen.lutrams[0].write_port.ram[translation[i].phys_addr];
|
||||
end
|
||||
end
|
||||
assign sim_registers_unamed[31-i] = sim_registers_unamed_groups[translation[i].wb_group][i];
|
||||
end
|
||||
|
|
|
@ -109,8 +109,8 @@ module nexys_wrapper
|
|||
H : 32'h87FFFFFF
|
||||
},
|
||||
ICACHE : '{
|
||||
LINES : 512,
|
||||
LINE_W : 4,
|
||||
LINES : 256,
|
||||
LINE_W : 8,
|
||||
WAYS : 2,
|
||||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 0,
|
||||
|
@ -129,9 +129,9 @@ module nexys_wrapper
|
|||
H : 32'h8FFFFFFF
|
||||
},
|
||||
DCACHE : '{
|
||||
LINES : 1024,
|
||||
LINE_W : 4,
|
||||
WAYS : 1,
|
||||
LINES : 256,
|
||||
LINE_W : 8,
|
||||
WAYS : 2,
|
||||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 1,
|
||||
NON_CACHEABLE : '{
|
||||
|
|
|
@ -595,13 +595,15 @@ module cva5_sim
|
|||
genvar i, j;
|
||||
generate for (i = 0; i < 32; i++) begin : gen_reg_file_sim
|
||||
for (j = 0; j < EXAMPLE_CONFIG.NUM_WB_GROUPS; j++) begin
|
||||
if (FPGA_VENDOR == XILINX)
|
||||
if (FPGA_VENDOR == XILINX) begin
|
||||
assign translation[i] = cpu.renamer_block.spec_table_ram.xilinx_gen.ram[i];
|
||||
else if (FPGA_VENDOR == INTEL)
|
||||
assign sim_registers_unamed_groups[j][i] =
|
||||
cpu.register_file_block.register_file_gen[j].register_file_bank.xilinx_gen.ram[translation[i].phys_addr];
|
||||
end else if (FPGA_VENDOR == INTEL) begin
|
||||
assign translation[i] = cpu.renamer_block.spec_table_ram.intel_gen.lutrams[0].write_port.ram[i];
|
||||
|
||||
assign sim_registers_unamed_groups[j][i] =
|
||||
cpu.register_file_block.register_file_gen[j].reg_group.register_file_bank[translation[i].phys_addr];
|
||||
assign sim_registers_unamed_groups[j][i] =
|
||||
cpu.register_file_block.register_file_gen[j].register_file_bank.intel_gen.lutrams[0].write_port.ram[translation[i].phys_addr];
|
||||
end
|
||||
end
|
||||
assign sim_registers_unamed[31-i] = sim_registers_unamed_groups[translation[i].wb_group][i];
|
||||
end
|
||||
|
|
|
@ -77,7 +77,6 @@ core/decode_and_issue.sv
|
|||
|
||||
core/register_free_list.sv
|
||||
core/renamer.sv
|
||||
core/register_bank.sv
|
||||
core/register_file.sv
|
||||
core/writeback.sv
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue