Restructure registerfile muxes

Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
Eric Matthews 2023-01-20 16:26:12 -05:00
parent 2e77b891d5
commit 1e9343a91c
6 changed files with 76 additions and 129 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 : '{

View file

@ -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

View file

@ -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