mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-22 13:07:33 -04:00
Split write-back muxes into seperate instances
Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
parent
ebcddd904a
commit
b275bd9691
2 changed files with 74 additions and 83 deletions
59
core/cva5.sv
59
core/cva5.sv
|
@ -83,8 +83,13 @@ module cva5
|
|||
//Writeback Port Assignment
|
||||
//
|
||||
localparam int unsigned NUM_WB_UNITS_GROUP_1 = 1;//ALU
|
||||
localparam int unsigned ALU_UNIT_WB1_ID = 32'd0;
|
||||
|
||||
localparam int unsigned NUM_WB_UNITS_GROUP_2 = 1 + int'(CONFIG.INCLUDE_CSRS) + int'(CONFIG.INCLUDE_MUL) + int'(CONFIG.INCLUDE_DIV);//LS
|
||||
localparam int unsigned NUM_WB_UNITS = NUM_WB_UNITS_GROUP_1 + NUM_WB_UNITS_GROUP_2;
|
||||
localparam int unsigned LS_UNIT_WB2_ID = 32'd0;
|
||||
localparam int unsigned CSR_UNIT_WB2_ID = LS_UNIT_WB2_ID + int'(CONFIG.INCLUDE_CSRS);
|
||||
localparam int unsigned MUL_UNIT_WB2_ID = CSR_UNIT_WB2_ID + int'(CONFIG.INCLUDE_MUL);
|
||||
localparam int unsigned DIV_UNIT_WB2_ID = MUL_UNIT_WB2_ID + int'(CONFIG.INCLUDE_DIV);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Connecting Signals
|
||||
|
@ -119,7 +124,8 @@ module cva5
|
|||
exception_packet_t ls_exception;
|
||||
logic ls_exception_is_store;
|
||||
|
||||
unit_writeback_interface unit_wb [NUM_WB_UNITS]();
|
||||
unit_writeback_interface unit_wb1 [NUM_WB_UNITS_GROUP_1]();
|
||||
unit_writeback_interface unit_wb2 [NUM_WB_UNITS_GROUP_2]();
|
||||
|
||||
mmu_interface immu();
|
||||
mmu_interface dmmu();
|
||||
|
@ -408,7 +414,7 @@ module cva5
|
|||
.rst (rst),
|
||||
.alu_inputs (alu_inputs),
|
||||
.issue (unit_issue[UNIT_IDS.ALU]),
|
||||
.wb (unit_wb[UNIT_IDS.ALU])
|
||||
.wb (unit_wb1[ALU_UNIT_WB1_ID])
|
||||
);
|
||||
|
||||
load_store_unit #(.CONFIG(CONFIG))
|
||||
|
@ -435,7 +441,7 @@ module cva5
|
|||
.retire_port_valid(retire_port_valid),
|
||||
.exception (exception[LS_EXCEPTION]),
|
||||
.load_store_status(load_store_status),
|
||||
.wb (unit_wb[UNIT_IDS.LS])
|
||||
.wb (unit_wb2[LS_UNIT_WB2_ID])
|
||||
);
|
||||
|
||||
generate if (CONFIG.INCLUDE_S_MODE) begin : gen_dtlb_dmmu
|
||||
|
@ -473,7 +479,7 @@ module cva5
|
|||
.rst(rst),
|
||||
.csr_inputs (csr_inputs),
|
||||
.issue (unit_issue[UNIT_IDS.CSR]),
|
||||
.wb (unit_wb[UNIT_IDS.CSR]),
|
||||
.wb (unit_wb2[CSR_UNIT_WB2_ID]),
|
||||
.current_privilege(current_privilege),
|
||||
.interrupt_taken(interrupt_taken),
|
||||
.interrupt_pending(interrupt_pending),
|
||||
|
@ -525,7 +531,7 @@ module cva5
|
|||
.rst (rst),
|
||||
.mul_inputs (mul_inputs),
|
||||
.issue (unit_issue[UNIT_IDS.MUL]),
|
||||
.wb (unit_wb[UNIT_IDS.MUL])
|
||||
.wb (unit_wb2[MUL_UNIT_WB2_ID])
|
||||
);
|
||||
end endgenerate
|
||||
|
||||
|
@ -535,7 +541,7 @@ module cva5
|
|||
.rst (rst),
|
||||
.div_inputs (div_inputs),
|
||||
.issue (unit_issue[UNIT_IDS.DIV]),
|
||||
.wb (unit_wb[UNIT_IDS.DIV])
|
||||
.wb (unit_wb2[DIV_UNIT_WB2_ID])
|
||||
);
|
||||
end endgenerate
|
||||
|
||||
|
@ -543,19 +549,44 @@ module cva5
|
|||
//Writeback
|
||||
//First writeback port: ALU
|
||||
//Second writeback port: LS, CSR, [MUL], [DIV]
|
||||
localparam int unsigned NUM_UNITS_PER_PORT [CONFIG.NUM_WB_GROUPS] = '{NUM_WB_UNITS_GROUP_1, NUM_WB_UNITS_GROUP_2};
|
||||
writeback #(
|
||||
.CONFIG (CONFIG),
|
||||
.NUM_UNITS (NUM_UNITS_PER_PORT),
|
||||
.NUM_WB_UNITS (NUM_WB_UNITS)
|
||||
.NUM_WB_UNITS (NUM_WB_UNITS_GROUP_1)
|
||||
)
|
||||
writeback_block (
|
||||
writeback_block1 (
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.wb_packet (wb_packet),
|
||||
.unit_wb (unit_wb),
|
||||
.wb_snoop (wb_snoop)
|
||||
.wb_packet (wb_packet[0]),
|
||||
.unit_wb (unit_wb1)
|
||||
);
|
||||
writeback #(
|
||||
.CONFIG (CONFIG),
|
||||
.NUM_WB_UNITS (NUM_WB_UNITS_GROUP_2)
|
||||
)
|
||||
writeback_block2 (
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.wb_packet (wb_packet[1]),
|
||||
.unit_wb (unit_wb2)
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Store Forwarding Support
|
||||
//TODO: support additional writeback groups
|
||||
//currently limited to one writeback group with the
|
||||
//assumption that writeback group zero has single-cycle
|
||||
//operation
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
wb_snoop.valid <= 0;
|
||||
else
|
||||
wb_snoop.valid <= wb_packet[1].valid;
|
||||
end
|
||||
always_ff @ (posedge clk) begin
|
||||
wb_snoop.data <= wb_packet[1].data;
|
||||
wb_snoop.id <= wb_packet[1].id;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
|
|
|
@ -28,7 +28,6 @@ module writeback
|
|||
|
||||
# (
|
||||
parameter cpu_config_t CONFIG = EXAMPLE_CONFIG,
|
||||
parameter int unsigned NUM_UNITS [CONFIG.NUM_WB_GROUPS] = '{1, 4},
|
||||
parameter int unsigned NUM_WB_UNITS = 5
|
||||
)
|
||||
|
||||
|
@ -38,90 +37,51 @@ module writeback
|
|||
//Unit writeback
|
||||
unit_writeback_interface.wb unit_wb[NUM_WB_UNITS],
|
||||
//WB output
|
||||
output wb_packet_t wb_packet [CONFIG.NUM_WB_GROUPS],
|
||||
//Snoop interface (LS unit)
|
||||
output wb_packet_t wb_snoop
|
||||
output wb_packet_t wb_packet
|
||||
);
|
||||
|
||||
//Writeback
|
||||
logic [NUM_WB_UNITS-1:0] unit_ack [CONFIG.NUM_WB_GROUPS];
|
||||
logic [NUM_WB_UNITS-1:0] unit_ack;
|
||||
//aliases for write-back-interface signals
|
||||
id_t [NUM_WB_UNITS-1:0] unit_instruction_id [CONFIG.NUM_WB_GROUPS];
|
||||
phys_addr_t [NUM_WB_UNITS-1:0] unit_phys_addr [CONFIG.NUM_WB_GROUPS];
|
||||
logic [NUM_WB_UNITS-1:0] unit_done [CONFIG.NUM_WB_GROUPS];
|
||||
id_t [NUM_WB_UNITS-1:0] unit_instruction_id;
|
||||
phys_addr_t [NUM_WB_UNITS-1:0] unit_phys_addr;
|
||||
logic [NUM_WB_UNITS-1:0] unit_done;
|
||||
|
||||
typedef logic [XLEN-1:0] unit_rd_t [NUM_WB_UNITS];
|
||||
unit_rd_t unit_rd [CONFIG.NUM_WB_GROUPS];
|
||||
logic [XLEN-1:0] unit_rd [NUM_WB_UNITS];
|
||||
|
||||
localparam int unsigned LOG2_NUM_WB_UNITS = NUM_WB_UNITS == 1 ? 1 : $clog2(NUM_WB_UNITS);
|
||||
//Per-ID muxes for commit buffer
|
||||
logic [$clog2(NUM_WB_UNITS)-1:0] unit_sel [CONFIG.NUM_WB_GROUPS];
|
||||
logic [LOG2_NUM_WB_UNITS-1:0] unit_sel;
|
||||
|
||||
typedef int unsigned unit_count_t [CONFIG.NUM_WB_GROUPS];
|
||||
|
||||
function unit_count_t get_cumulative_unit_count();
|
||||
unit_count_t counts;
|
||||
int unsigned cumulative_count = 0;
|
||||
for (int i = 0; i < CONFIG.NUM_WB_GROUPS; i++) begin
|
||||
counts[i] = cumulative_count;
|
||||
cumulative_count += NUM_UNITS[i];
|
||||
end
|
||||
return counts;
|
||||
endfunction
|
||||
|
||||
localparam unit_count_t CUMULATIVE_NUM_UNITS = get_cumulative_unit_count();
|
||||
|
||||
genvar i, j;
|
||||
genvar i;
|
||||
////////////////////////////////////////////////////
|
||||
//Implementation
|
||||
//Re-assigning interface inputs to array types so that they can be dynamically indexed
|
||||
generate
|
||||
for (i = 0; i < CONFIG.NUM_WB_GROUPS; i++) begin : gen_wb_group_unpacking
|
||||
for (j = 0; j < NUM_UNITS[i]; j++) begin : gen_wb_unit_unpacking
|
||||
assign unit_instruction_id[i][j] = unit_wb[CUMULATIVE_NUM_UNITS[i] + j].id;
|
||||
assign unit_phys_addr[i][j] = unit_wb[CUMULATIVE_NUM_UNITS[i] + j].phys_addr;
|
||||
assign unit_done[i][j] = unit_wb[CUMULATIVE_NUM_UNITS[i] + j].done;
|
||||
assign unit_wb[CUMULATIVE_NUM_UNITS[i] + j].ack = unit_ack[i][j];
|
||||
assign unit_rd[i][j] = unit_wb[CUMULATIVE_NUM_UNITS[i] + j].rd;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
generate for (i = 0; i < NUM_WB_UNITS; i++) begin : gen_wb_unit_unpacking
|
||||
assign unit_instruction_id[i] = unit_wb[i].id;
|
||||
assign unit_phys_addr[i] = unit_wb[i].phys_addr;
|
||||
assign unit_done[i] = unit_wb[i].done;
|
||||
assign unit_wb[i].ack = unit_ack[i];
|
||||
assign unit_rd[i] = unit_wb[i].rd;
|
||||
end endgenerate
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Unit select for register file
|
||||
//Iterating through all commit ports:
|
||||
// Search for complete units (in fixed unit order)
|
||||
// Assign to a commit port, mask that unit and commit port
|
||||
generate for (i = 0; i < CONFIG.NUM_WB_GROUPS; i++) begin : gen_wb_mux
|
||||
priority_encoder
|
||||
#(.WIDTH(NUM_UNITS[i]))
|
||||
unit_done_encoder
|
||||
(
|
||||
.priority_vector (unit_done[i][NUM_UNITS[i]-1 : 0]),
|
||||
.encoded_result (unit_sel[i][NUM_UNITS[i] == 1 ? 0 : ($clog2(NUM_UNITS[i])-1) : 0])
|
||||
);
|
||||
assign wb_packet[i].valid = |unit_done[i];
|
||||
assign wb_packet [i].id = unit_instruction_id[i][unit_sel[i]];
|
||||
assign wb_packet [i].phys_addr = unit_phys_addr[i][unit_sel[i]];
|
||||
assign wb_packet[i].data = unit_rd[i][unit_sel[i]];
|
||||
priority_encoder #(.WIDTH(NUM_WB_UNITS))
|
||||
unit_done_encoder
|
||||
(
|
||||
.priority_vector (unit_done),
|
||||
.encoded_result (unit_sel[LOG2_NUM_WB_UNITS -1 : 0])
|
||||
);
|
||||
assign wb_packet.valid = |unit_done;
|
||||
assign wb_packet.id = unit_instruction_id[unit_sel];
|
||||
assign wb_packet.phys_addr = unit_phys_addr[unit_sel];
|
||||
assign wb_packet.data = unit_rd[unit_sel];
|
||||
|
||||
assign unit_ack[i] = NUM_WB_UNITS'(wb_packet[i].valid) << unit_sel[i];
|
||||
end endgenerate
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Store Forwarding Support
|
||||
//TODO: support additional writeback groups
|
||||
//currently limited to one writeback group with the
|
||||
//assumption that writeback group zero has single-cycle
|
||||
//operation
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
wb_snoop.valid <= 0;
|
||||
else
|
||||
wb_snoop.valid <= wb_packet[1].valid;
|
||||
end
|
||||
always_ff @ (posedge clk) begin
|
||||
wb_snoop.data <= wb_packet[1].data;
|
||||
wb_snoop.id <= wb_packet[1].id;
|
||||
end
|
||||
assign unit_ack = NUM_WB_UNITS'(wb_packet.valid) << unit_sel;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
|
@ -130,4 +90,4 @@ module writeback
|
|||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
|
||||
endmodule
|
||||
endmodule
|
Loading…
Add table
Add a link
Reference in a new issue