Split write-back muxes into seperate instances

Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
Eric Matthews 2023-01-19 15:16:38 -05:00
parent ebcddd904a
commit b275bd9691
2 changed files with 74 additions and 83 deletions

View file

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

View file

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