diff --git a/core/cva5.sv b/core/cva5.sv index a7ead69..9550400 100755 --- a/core/cva5.sv +++ b/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 diff --git a/core/writeback.sv b/core/writeback.sv index f6a85ca..b79c9d8 100644 --- a/core/writeback.sv +++ b/core/writeback.sv @@ -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 \ No newline at end of file