diff --git a/core/alu_unit.sv b/core/alu_unit.sv index c560d7e..2921c1f 100755 --- a/core/alu_unit.sv +++ b/core/alu_unit.sv @@ -1,5 +1,5 @@ /* - * Copyright © 2017 Eric Matthews, Lesley Shannon + * 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. @@ -27,9 +27,10 @@ import taiga_types::*; module alu_unit( input logic clk, input logic rst, + input logic single_cycle_issue_possible, unit_issue_interface.unit issue, input alu_inputs_t alu_inputs, - output unit_writeback_t wb + unit_writeback_interface.unit wb ); logic[XLEN:0] add_sub_result; @@ -77,10 +78,10 @@ module alu_unit( //////////////////////////////////////////////////// //Output - assign issue.ready = 1; + assign issue.ready = single_cycle_issue_possible;//single_cycle_issue_possible; assign wb.rd = result; assign wb.done = issue.new_request; - assign wb.id = issue.instruction_id; + assign wb.id = issue.id; //////////////////////////////////////////////////// //Assertions diff --git a/core/branch_unit.sv b/core/branch_unit.sv index c4f669f..15915a1 100755 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -65,6 +65,7 @@ module branch_unit( logic [31:0] pc_ex; logic instruction_is_completing; + logic jal_jalr_ex; //////////////////////////////////////////////////// //Implementation //Only stall condition is if the following instruction is not valid for pc comparisons. @@ -108,17 +109,18 @@ module branch_unit( new_pc_ex[31:1] <= new_pc[31:1]; new_pc_ex[0] <= new_pc[0] & ~branch_inputs.jalr; id_ex <= issue.id; + jal_jalr_ex <= branch_inputs.jal | branch_inputs.jalr; end end //////////////////////////////////////////////////// //Exception support - instruction_id_t jmp_instruction_id; + id_t jmp_id; generate if (ENABLE_M_MODE) begin always_ff @(posedge clk) begin if (instruction_is_completing | ~branch_issued_r) - jmp_instruction_id <= issue.instruction_id; + jmp_id <= issue.id; end assign potential_branch_exception = new_pc[1] & issue.new_request; @@ -126,16 +128,15 @@ module branch_unit( assign br_exception.valid = new_pc_ex[1] & branch_taken_ex & branch_issued_r; assign br_exception.code = INST_ADDR_MISSALIGNED; - assign br_exception.pc = pc_ex; assign br_exception.tval = new_pc_ex; - assign br_exception.id = jmp_instruction_id; + assign br_exception.id = jmp_id; end endgenerate //////////////////////////////////////////////////// //ID Management - assign branch_complete = instruction_is_completing | br_exception.valid; + assign branch_complete = (instruction_is_completing & ~jal_jalr_ex); assign branch_id = id_ex; //////////////////////////////////////////////////// diff --git a/core/csr_regs.sv b/core/csr_regs.sv index 207086b..186e9e4 100755 --- a/core/csr_regs.sv +++ b/core/csr_regs.sv @@ -40,6 +40,7 @@ module csr_regs output exception_packet_t csr_exception, output logic [1:0] current_privilege, input logic gc_supress_writeback, + input logic [31:0] exception_pc, //Decode input logic instruction_issued_no_rd, @@ -382,7 +383,7 @@ generate if (ENABLE_M_MODE) begin always_ff @(posedge clk) begin mepc[1:0] <= '0; if (mwrite_decoder[MEPC[7:0]] | gc_exception.valid) - mepc[XLEN-1:2] <= gc_exception.valid ? gc_exception.pc[XLEN-1:2] : updated_csr[XLEN-1:2]; + mepc[XLEN-1:2] <= gc_exception.valid ? exception_pc[XLEN-1:2] : updated_csr[XLEN-1:2]; end assign csr_mepc = mepc; diff --git a/core/decode_and_issue.sv b/core/decode_and_issue.sv index bc7ad59..6bde868 100755 --- a/core/decode_and_issue.sv +++ b/core/decode_and_issue.sv @@ -35,7 +35,6 @@ module decode_and_issue ( input logic [31:0] decode_pc, input logic [31:0] decode_instruction, - tracking_interface.decode ti, register_file_issue_interface.issue rf_issue, output alu_inputs_t alu_inputs, @@ -57,7 +56,6 @@ module decode_and_issue ( output id_t issue_id, output logic issue_stage_valid, output logic id_issued, - output logic dummy_id_complete, output logic instruction_issued_no_rd, output logic instruction_issued_with_rd, output logic illegal_instruction, @@ -189,26 +187,7 @@ module decode_and_issue ( end end assign rf_issue.instruction_issued = instruction_issued_with_rd & (|rd_addr_issue_stage); - assign rf_issue.id = ti.issue_id; - - //////////////////////////////////////////////////// - //Tracking Interface - //CSR results are passed through the load/store output - always_comb begin - unit_needed_for_id_gen = unit_needed[NUM_WB_UNITS-1:0]; - unit_needed_for_id_gen[LS_UNIT_WB_ID] |= (unit_needed[GC_UNIT_ID] & is_csr); - end - one_hot_to_integer #(NUM_WB_UNITS) unit_id_gen (.*, .one_hot(unit_needed_for_id_gen), .int_out(unit_needed_for_id_gen_int)); - - always_ff @(posedge clk) begin - if (issue_stage_ready) begin - ti.inflight_packet.is_store <= is_store; - ti.issue_unit_id <= unit_needed_for_id_gen_int; - ti.exception_possible <= opcode_trim inside {LOAD_T, STORE_T, AMO_T}; - ti.inflight_packet.rd_addr <= rd_addr; - end - end - assign ti.issued = instruction_issued & (uses_rd_issue_stage | unit_needed_issue_stage[LS_UNIT_WB_ID]); + assign rf_issue.id = issue_id; //////////////////////////////////////////////////// //Unit Determination @@ -239,14 +218,15 @@ module decode_and_issue ( //////////////////////////////////////////////////// //Issue Determination - assign issue_valid = issue_stage_valid & ti.id_available & ~gc_issue_hold & ~gc_fetch_flush; + assign issue_valid = issue_stage_valid & ~gc_issue_hold & ~gc_fetch_flush; assign operands_ready = ~rf_issue.rs1_conflict & ~rf_issue.rs2_conflict; //All units share the same operand ready logic except load-store which has an internal forwarding path always_comb begin unit_operands_ready = {NUM_UNITS{operands_ready}}; - unit_operands_ready[LS_UNIT_WB_ID] = ~rf_issue.rs1_conflict; + unit_operands_ready[LS_UNIT_WB_ID] = ~rf_issue.rs1_conflict & ~rf_issue.rs2_conflict; + unit_operands_ready[BRANCH_UNIT_ID] &= unit_ready[ALU_UNIT_WB_ID]; end assign issue_ready = unit_needed_issue_stage & unit_ready; @@ -257,7 +237,6 @@ module decode_and_issue ( assign instruction_issued_with_rd = instruction_issued & uses_rd_issue_stage; assign id_issued = instruction_issued; - assign dummy_id_complete = instruction_issued & ~unit_needed_issue_stage[BRANCH_UNIT_ID]; //////////////////////////////////////////////////// //ALU unit inputs logic [XLEN-1:0] alu_rs1_data; @@ -401,10 +380,9 @@ module decode_and_issue ( assign ls_inputs.load = is_load_r; assign ls_inputs.store = is_store_r; assign ls_inputs.fn3 = amo_op ? LS_W_fn3 : fn3_issue_stage; - assign ls_inputs.pc = pc_issue_stage; assign ls_inputs.rs1 = rf_issue.rs1_data; assign ls_inputs.rs2 = rf_issue.rs2_data; - assign ls_inputs.forwarded_store = rf_issue.rs2_conflict; + assign ls_inputs.forwarded_store = 0;//rf_issue.rs2_conflict; assign ls_inputs.store_forward_id = rf_issue.rs2_id; //////////////////////////////////////////////////// @@ -558,9 +536,8 @@ module decode_and_issue ( //////////////////////////////////////////////////// //Unit EX signals generate for (i = 0; i < NUM_UNITS; i++) begin - assign unit_issue[i].possible_issue = unit_needed_issue_stage[i] & unit_operands_ready[i] & issue_stage_valid & ti.id_available & ~gc_issue_hold; + assign unit_issue[i].possible_issue = unit_needed_issue_stage[i] & unit_operands_ready[i] & issue_stage_valid & ~gc_issue_hold; assign unit_issue[i].new_request = issue[i]; - assign unit_issue[i].instruction_id = ti.issue_id; assign unit_issue[i].id = issue_id; always_ff @(posedge clk) begin unit_issue[i].new_request_r <= issue[i]; @@ -583,7 +560,7 @@ module decode_and_issue ( //Illegal instruction if the instruction is invalid, but could otherwise be issued - assign illegal_instruction = illegal_instruction_pattern_r & issue_stage_valid & ti.id_available & ~gc_issue_hold & ~gc_fetch_flush; + assign illegal_instruction = illegal_instruction_pattern_r & issue_stage_valid & ~gc_issue_hold & ~gc_fetch_flush; end endgenerate //////////////////////////////////////////////////// //End of Implementation @@ -597,7 +574,7 @@ module decode_and_issue ( generate if (ENABLE_TRACE_INTERFACE) begin assign tr_operand_stall = |(unit_needed_issue_stage & unit_ready) & issue_valid & ~|(unit_operands_ready & issue_ready); assign tr_unit_stall = ~|(unit_needed_issue_stage & unit_ready) & issue_valid & |(unit_operands_ready & issue_ready); - assign tr_no_id_stall = |(unit_needed_issue_stage & unit_ready) & (issue_stage_valid & ~ti.id_available & ~gc_issue_hold & ~gc_fetch_flush) & |(unit_operands_ready & issue_ready); + assign tr_no_id_stall = 0; assign tr_no_instruction_stall = ~issue_stage_valid | gc_fetch_flush; assign tr_other_stall = issue_stage_valid & ~instruction_issued & ~(tr_operand_stall | tr_unit_stall | tr_no_id_stall | tr_no_instruction_stall); assign tr_branch_operand_stall = tr_operand_stall & unit_needed_issue_stage[BRANCH_UNIT_ID]; diff --git a/core/div_unit.sv b/core/div_unit.sv index 8f266ce..a778871 100755 --- a/core/div_unit.sv +++ b/core/div_unit.sv @@ -33,7 +33,7 @@ module div_unit input div_inputs_t div_inputs, unit_issue_interface.unit issue, - output unit_writeback_t wb + unit_writeback_interface.unit wb ); logic signed_divop; @@ -53,7 +53,7 @@ module div_unit logic negate_quotient; logic negate_remainder; logic reuse_result; - instruction_id_t instruction_id; + id_t id; } div_fifo_inputs_t; div_fifo_inputs_t fifo_inputs; @@ -94,18 +94,18 @@ module div_unit assign fifo_inputs.negate_quotient = negate_quotient; assign fifo_inputs.negate_remainder = negate_remainder; assign fifo_inputs.reuse_result = div_inputs.reuse_result; - assign fifo_inputs.instruction_id = issue.instruction_id; + assign fifo_inputs.id = issue.id; //////////////////////////////////////////////////// //Input FIFO - taiga_fifo #(.DATA_WIDTH($bits(div_fifo_inputs_t)), .FIFO_DEPTH(MAX_INFLIGHT_COUNT)) + taiga_fifo #(.DATA_WIDTH($bits(div_fifo_inputs_t)), .FIFO_DEPTH(MAX_IDS)) div_input_fifo (.fifo(input_fifo), .*); assign input_fifo.data_in = fifo_inputs; assign input_fifo.push = issue.possible_issue; assign input_fifo.supress_push = gc_fetch_flush; assign issue.ready = 1; //As FIFO depth is the same as MAX_INFLIGHT_COUNT - assign input_fifo.pop = div_done; + assign input_fifo.pop = wb.done & wb.ack; assign div_op = input_fifo.data_out; //////////////////////////////////////////////////// @@ -117,7 +117,7 @@ module div_unit set_clr_reg_with_rst #(.SET_OVER_CLR(1), .WIDTH(1), .RST_VALUE('0)) in_progress_m ( .clk, .rst, .set(div_core.start), - .clr(div_core.done), + .clr(wb.ack), .result(in_progress) ); @@ -129,10 +129,18 @@ module div_unit //////////////////////////////////////////////////// //Output + logic done_r; assign negate_result = div_op.remainder_op ? div_op.negate_remainder : (~div_core.divisor_is_zero & div_op.negate_quotient); assign wb.rd = negate_if (div_op.remainder_op ? div_core.remainder : ({32{div_core.divisor_is_zero}} | div_core.quotient), negate_result); - assign wb.done = div_done; - assign wb.id = div_op.instruction_id; + + always_ff @ (posedge clk) begin + if (wb.ack) + done_r <= 0; + else if (div_done) + done_r <= 1; + end + assign wb.done = div_done | done_r; + assign wb.id = div_op.id; //////////////////////////////////////////////////// //Assertions diff --git a/core/gc_unit.sv b/core/gc_unit.sv index d28ea41..91cc7e6 100644 --- a/core/gc_unit.sv +++ b/core/gc_unit.sv @@ -46,7 +46,6 @@ module gc_unit( //Load Store Unit input exception_packet_t ls_exception, - input logic ls_exception_valid, //TLBs output logic tlb_on, @@ -57,13 +56,17 @@ module gc_unit( mmu_interface.csr dmmu, //ID Management - output logic system_op_complete, - output id_t system_op_id, + output logic system_op_or_exception_complete, + output id_t system_op_or_exception_id, + + //Exception + output id_t exception_id, + input logic [31:0] exception_pc, //WB input logic instruction_retired, input logic instruction_queue_empty, - input instruction_id_t oldest_id, + input logic writeback_is_idle, //unit_writeback_interface.unit gc_wb, //External @@ -77,14 +80,13 @@ module gc_unit( output logic gc_fetch_pc_override, output logic gc_supress_writeback, - output logic ls_exception_ack, - output logic [31:0] gc_fetch_pc, //Write-back to Load-Store Unit output logic[31:0] csr_rd, - output instruction_id_t csr_id, - output logic csr_done + output id_t csr_id, + output logic csr_done, + input logic ls_is_idle ); //Largest depth for TLBs @@ -139,7 +141,7 @@ module gc_unit( // *If in-order mode and inflight queue empty, disable zero cycle write-back (eg. ALU) //*Hold fetch during potential fetch exception, when fetch buffer drained, if no other exceptions trigger exception - typedef enum {RST_STATE, IDLE_STATE, TLB_CLEAR_STATE, IQ_DRAIN, IQ_DISCARD} gc_state; + typedef enum {RST_STATE, IDLE_STATE, TLB_CLEAR_STATE, IQ_DRAIN} gc_state; gc_state state; gc_state next_state; gc_state prev_state; @@ -175,10 +177,7 @@ module gc_unit( logic processing_csr; logic csr_ready_to_complete; logic csr_ready_to_complete_r; - instruction_id_t instruction_id; - - instruction_id_t exception_id; - instruction_id_t exception_id_r; + id_t instruction_id; //implementation //////////////////////////////////////////////////// @@ -190,8 +189,10 @@ module gc_unit( //////////////////////////////////////////////////// //ID Management - assign system_op_complete = issue.new_request & (gc_inputs.is_fence | gc_inputs.is_i_fence); - assign system_op_id = issue.id; + assign system_op_or_exception_complete = + (issue.new_request & (gc_inputs.is_fence | gc_inputs.is_i_fence)) | + gc_exception.valid; + assign system_op_or_exception_id = issue.new_request ? issue.id : exception_id; //Instruction decode assign opcode = stage1.instruction[6:0]; @@ -205,15 +206,11 @@ module gc_unit( assign gc_fetch_flush = branch_flush | gc_fetch_pc_override; always_ff @ (posedge clk) begin - gc_issue_hold <= issue.new_request || processing_csr || (next_state inside {TLB_CLEAR_STATE, IQ_DRAIN, IQ_DISCARD}) || potential_branch_exception; + gc_issue_hold <= issue.new_request || processing_csr || (next_state inside {TLB_CLEAR_STATE, IQ_DRAIN}) || potential_branch_exception; end always_ff @ (posedge clk) begin - gc_issue_flush <= (next_state == IQ_DISCARD); - end - - always_ff @ (posedge clk) begin - gc_supress_writeback <= next_state inside {TLB_CLEAR_STATE, IQ_DISCARD} ? 1 : 0; + gc_supress_writeback <= next_state inside {TLB_CLEAR_STATE} ? 1 : 0; end //////////////////////////////////////////////////// @@ -238,12 +235,11 @@ module gc_unit( RST_STATE : next_state = IDLE_STATE; IDLE_STATE : begin if (ls_exception.valid | (branch_exception_is_jump & potential_branch_exception)) begin - next_state = (exception_id == oldest_id) ? IQ_DISCARD : IQ_DRAIN; + next_state = IQ_DRAIN; end end TLB_CLEAR_STATE : if (tlb_clear_done) next_state = IDLE_STATE; - IQ_DRAIN : if (exception_id_r == oldest_id) next_state = IQ_DISCARD; - IQ_DISCARD : if (instruction_queue_empty) next_state = IDLE_STATE; + IQ_DRAIN : next_state = IDLE_STATE; default : next_state = RST_STATE; endcase end @@ -259,7 +255,6 @@ module gc_unit( end //////////////////////////////////////////////////// //Exception handling - logic processing_ls_exception; //The type of call instruction is depedent on the current privilege level always_comb begin @@ -271,43 +266,27 @@ module gc_unit( endcase end - always_ff @(posedge clk) begin - if (gc_exception.valid) - processing_ls_exception <= ls_exception.valid; - end - - assign ls_exception_ack = processing_ls_exception && (prev_state inside {IDLE_STATE, IQ_DRAIN}) && (state == IQ_DISCARD); - assign exception_id = potential_branch_exception ? br_exception.id : - (ls_exception.valid ? ls_exception.id : issue.instruction_id); - - always_ff @(posedge clk) begin - if (gc_exception.valid) - exception_id_r <= exception_id; - end + (ls_exception.valid ? ls_exception.id : issue.id); //TODO: check if possible to convert to unique if, verify potential for overlap always_comb begin + //PC sourced from instruction metadata table if (br_exception.valid) begin gc_exception.code = br_exception.code; - gc_exception.pc = br_exception.pc; gc_exception.tval = br_exception.tval; end else if (illegal_instruction) begin gc_exception.code = ILLEGAL_INST; - gc_exception.pc = gc_inputs.pc; gc_exception.tval = gc_inputs.instruction;//optional, can be zero instead end else if (ls_exception.valid) begin gc_exception.code = ls_exception.code; - gc_exception.pc = ls_exception.pc; gc_exception.tval = ls_exception.tval; end else if (gc_inputs.is_ecall) begin gc_exception.code = ecall_code; - gc_exception.pc = gc_inputs.pc; gc_exception.tval = '0; end else begin gc_exception.code = BREAK; - gc_exception.pc = gc_inputs.pc; gc_exception.tval = '0; end end @@ -352,12 +331,12 @@ module gc_unit( .result(processing_csr) ); - assign csr_ready_to_complete = processing_csr && (oldest_id == instruction_id); + assign csr_ready_to_complete = processing_csr & ls_is_idle & writeback_is_idle; always_ff @(posedge clk) begin csr_ready_to_complete_r <= csr_ready_to_complete; csr_id <= instruction_id; if (issue.new_request) begin - instruction_id <= issue.instruction_id; + instruction_id <= issue.id; end end diff --git a/core/id_inuse.sv b/core/id_inuse.sv index f50e661..eaaeb91 100644 --- a/core/id_inuse.sv +++ b/core/id_inuse.sv @@ -29,8 +29,8 @@ module id_inuse ( input logic [4:0] rs1_addr, input logic [4:0] rs2_addr, input logic [4:0] issued_rd_addr, - input instruction_id_t issue_id, - input instruction_id_t retired_id, + input id_t issue_id, + input id_t retired_id, input logic issued, input logic retired, output logic rs1_inuse, diff --git a/core/id_management.sv b/core/id_management.sv index a01fcf7..3a4ee50 100644 --- a/core/id_management.sv +++ b/core/id_management.sv @@ -58,8 +58,8 @@ module id_management input logic branch_complete, input id_t branch_id, - input logic system_op_complete, - input id_t system_op_id, + input logic system_op_or_exception_complete, + input id_t system_op_or_exception_id, input logic instruction_retired, input id_t retired_id @@ -75,10 +75,9 @@ module id_management logic decoded_toggle_mem [MAX_IDS]; logic decoded_issued_toggle_mem [MAX_IDS]; logic issued_toggle_mem [MAX_IDS]; - logic dummy_toggle_mem [MAX_IDS]; logic branch_complete_toggle_mem [MAX_IDS]; logic store_complete_toggle_mem [MAX_IDS]; - logic system_op_complete_toggle_mem [MAX_IDS]; + logic system_op_or_exception_complete_toggle_mem [MAX_IDS]; logic retired_toggle_mem [MAX_IDS]; //////////////////////////////////////////////////// @@ -146,12 +145,6 @@ module id_management issued_toggle_mem[issue_id] <= ~issued_toggle_mem[issue_id]; end - initial dummy_toggle_mem = '{default: 0}; - always_ff @ (posedge clk) begin - if (dummy_id_complete) - dummy_toggle_mem[issue_id] <= ~dummy_toggle_mem[issue_id]; - end - initial branch_complete_toggle_mem = '{default: 0}; always_ff @ (posedge clk) begin if (branch_complete) @@ -164,10 +157,10 @@ module id_management store_complete_toggle_mem[store_id] <= ~store_complete_toggle_mem[store_id]; end - initial system_op_complete_toggle_mem = '{default: 0}; + initial system_op_or_exception_complete_toggle_mem = '{default: 0}; always_ff @ (posedge clk) begin - if (system_op_complete) - system_op_complete_toggle_mem[system_op_id] <= ~system_op_complete_toggle_mem[system_op_id]; + if (system_op_or_exception_complete) + system_op_or_exception_complete_toggle_mem[system_op_or_exception_id] <= ~system_op_or_exception_complete_toggle_mem[system_op_or_exception_id]; end initial retired_toggle_mem = '{default: 0}; @@ -183,11 +176,9 @@ module id_management assign id_not_inflight = ~(issued_toggle_mem[pc_id_i] ^ branch_complete_toggle_mem[pc_id_i] ^ - dummy_toggle_mem[pc_id_i] - );// ^ - //store_complete_toggle_mem[pc_id_i] ^ - //system_op_complete_toggle_mem[pc_id_i] ^ - //retired_toggle_mem[pc_id_i]); + store_complete_toggle_mem[pc_id_i] ^ + system_op_or_exception_complete_toggle_mem[pc_id_i] ^ + retired_toggle_mem[pc_id_i]); always_ff @ (posedge clk) begin if (rst) diff --git a/core/id_tracking.sv b/core/id_tracking.sv index f2d456c..6a6e4c6 100644 --- a/core/id_tracking.sv +++ b/core/id_tracking.sv @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Eric Matthews, Lesley Shannon + * Copyright © 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. @@ -20,49 +20,67 @@ * Eric Matthews */ -import taiga_config::*; -import taiga_types::*; module id_tracking - ( + import taiga_config::*; + import taiga_types::*; + ( input logic clk, input logic rst, - input logic issued, - input logic retired, + + input logic gc_fetch_flush, + + + //ID issuing + output id_t next_id, output logic id_available, - output instruction_id_t oldest_id, - output instruction_id_t next_id, - output logic empty - ); + input id_assigned, + + // m + + //Decode ID + input id_t decode_id, + input decode_issued, + output decode_id_valid, + + //Issue stage + input id_t issue_id, + input instruction_issued, + + ); ////////////////////////////////////////// - localparam LOG2_MAX_INFLIGHT_COUNT = $clog2(MAX_INFLIGHT_COUNT); - logic [LOG2_MAX_INFLIGHT_COUNT:0] inflight_count; + localparam LOG2_MAX_IDS = $clog2(MAX_IDS); + + fifo_interface #(.DATA_WIDTH($bits(id_t))) fetched_ids(); //////////////////////////////////////////////////// //Implementation - always_ff @ (posedge clk) begin - if (rst) - oldest_id <= 0; - else - oldest_id <= oldest_id + LOG2_MAX_INFLIGHT_COUNT'(retired); - end always_ff @ (posedge clk) begin if (rst) next_id <= 0; else - next_id <= next_id + LOG2_MAX_INFLIGHT_COUNT'(issued); + next_id <= next_id + LOG2_MAX_IDS'(id_assigned); end - //Upper bit is id_available + assign fetched_ids.push = id_assigned; + assign fetched_ids.pop = decode_issued; + assign fetched_ids.data_in = next_id; + + assign decode_id = fetched_ids.data_out; + assign decode_id_valid = fetched_ids.valid; + + taiga_fifo #(.DATA_WIDTH($bits(id_t)), .FIFO_DEPTH(MAX_IDS)) + fetched_ids_fifo (.fifo(fetched_ids), .rst(rst | gc_fetch_flush), .*); + + + + always_ff @ (posedge clk) begin if (rst) - inflight_count <= '1; + id_available <= 0; else - inflight_count <= inflight_count + (LOG2_MAX_INFLIGHT_COUNT+1)'(retired) - (LOG2_MAX_INFLIGHT_COUNT+1)'(issued); + id_available <= end - assign empty = &inflight_count;//all ones - assign id_available = inflight_count[LOG2_MAX_INFLIGHT_COUNT]; - //////////////////////////////////////////////////// //End of Implementation //////////////////////////////////////////////////// @@ -70,7 +88,6 @@ module id_tracking //////////////////////////////////////////////////// //Assertions always_ff @ (posedge clk) begin - assert (rst | !(~rst & ~id_available & issued)) else $error("Issued without valid ID!"); - assert (rst | !(~rst & empty & (retired & ~issued))) else $error("Retired without any instruction inflight!"); + assert (rst | !(~rst & ~id_available & id_assigned)) else $error("Issued without valid ID!"); end endmodule diff --git a/core/instruction_metadata.sv b/core/instruction_metadata.sv index c93801c..b581844 100644 --- a/core/instruction_metadata.sv +++ b/core/instruction_metadata.sv @@ -38,7 +38,6 @@ module instruction_metadata input logic fetch_complete, input logic [31:0] fetch_instruction, - //Decode ID input id_t decode_id, output logic [31:0] decode_pc, @@ -47,18 +46,22 @@ module instruction_metadata //Branch Predictor input branch_metadata_t branch_metadata_if, input id_t branch_id, - output branch_metadata_t branch_metadata_ex + output branch_metadata_t branch_metadata_ex, + + //Writeback/Register File + input id_t retired_id, + output logic [4:0] retired_rd_addr, //Exception - //input id_t exception_id, - //output logic [31:0] exception_pc, - //output logic [31:0] exception_instruction + input id_t exception_id, + output logic [31:0] exception_pc ); ////////////////////////////////////////// logic [31:0] pc_table [MAX_IDS]; logic [31:0] instruction_table [MAX_IDS]; logic [$bits(branch_metadata_t)-1:0] branch_metadata_table [MAX_IDS]; + logic [31:0] rd_table [MAX_IDS]; //////////////////////////////////////////////////// //Implementation @@ -80,6 +83,12 @@ module instruction_metadata instruction_table[fetch_id] <= fetch_instruction; end + //rd table + // always_ff @ (posedge clk) begin + // if (instruction_retired) + // rd_table[id_retired] <= retired_rd; + // end + //////////////////////////////////////////////////// //Outputs @@ -90,11 +99,13 @@ module instruction_metadata //Branch Predictor assign branch_metadata_ex = branch_metadata_table[branch_id]; + //Register File + assign retired_rd_addr = instruction_table[retired_id][11:7]; + //Exception Support - // generate if (ENABLE_M_MODE) begin - // assign exception_pc = pc_table[exception_id]; - // assign exception_instruction = instruction_table[exception_id]; - // end endgenerate + generate if (ENABLE_M_MODE) begin + assign exception_pc = pc_table[exception_id]; + end endgenerate //////////////////////////////////////////////////// //End of Implementation diff --git a/core/interfaces.sv b/core/interfaces.sv index 7275f86..4c91bf1 100755 --- a/core/interfaces.sv +++ b/core/interfaces.sv @@ -53,13 +53,29 @@ interface unit_issue_interface; logic possible_issue; logic new_request; logic new_request_r; - instruction_id_t instruction_id; id_t id; logic ready; - modport decode (input ready, output possible_issue, new_request, new_request_r, instruction_id, id); - modport unit (output ready, input possible_issue, new_request, new_request_r, instruction_id, id); + modport decode (input ready, output possible_issue, new_request, new_request_r, id); + modport unit (output ready, input possible_issue, new_request, new_request_r, id); +endinterface + +interface unit_writeback_interface; + logic ack; + + id_t id; + logic done; + logic [XLEN-1:0] rd; + + modport unit ( + input ack, + output id, done, rd + ); + modport wb ( + output ack, + input id, done, rd + ); endinterface interface ras_interface; @@ -95,7 +111,7 @@ interface exception_interface; exception_code_t code; logic [31:0] pc; logic [31:0] addr; - instruction_id_t id; + id_t id; modport econtrol (output valid, code, pc, addr, id, input ack); modport unit (input valid, code, pc, addr, id, output ack); @@ -107,13 +123,13 @@ interface register_file_issue_interface; logic[XLEN-1:0] rs1_data; logic[4:0] rs2_addr; //if not used required to be zero logic[XLEN-1:0] rs2_data; - instruction_id_t id; + id_t id; logic uses_rs1; logic uses_rs2; logic rs1_conflict; logic rs2_conflict; - instruction_id_t rs2_id; + id_t rs2_id; logic instruction_issued; modport issue (output rd_addr, rs1_addr, rs2_addr, instruction_issued, id, uses_rs1, uses_rs2, input rs1_conflict, rs2_conflict, rs1_data, rs2_data, rs2_id); @@ -122,40 +138,24 @@ endinterface interface register_file_writeback_interface; - logic[4:0] rd_addr; + //Writeback data logic retiring; - logic rd_nzero; - + id_t id; logic[XLEN-1:0] rd_data; - instruction_id_t id; - - instruction_id_t rs1_id; - instruction_id_t rs2_id; + //Forwarding signals + id_t rs1_id; + id_t rs2_id; logic[XLEN-1:0] rs1_data; logic[XLEN-1:0] rs2_data; logic rs1_valid; logic rs2_valid; - modport writeback (output rd_addr, retiring, rd_nzero, rd_data, id, rs1_data, rs2_data, rs1_valid, rs2_valid, input rs1_id, rs2_id); - modport rf (input rd_addr, retiring, rd_nzero, rd_data, id, rs1_data, rs2_data, rs1_valid, rs2_valid, output rs1_id, rs2_id); + modport writeback (output retiring, rd_data, id, rs1_data, rs2_data, rs1_valid, rs2_valid, input rs1_id, rs2_id); + modport rf (input retiring, rd_data, id, rs1_data, rs2_data, rs1_valid, rs2_valid, output rs1_id, rs2_id); endinterface - -interface tracking_interface; - instruction_id_t issue_id; - logic id_available; - - inflight_instruction_packet inflight_packet; - logic issued; - logic [WB_UNITS_WIDTH-1:0] issue_unit_id; - logic exception_possible; - - modport decode (input issue_id, id_available, output inflight_packet, issued, issue_unit_id, exception_possible); - modport wb (output issue_id, id_available, input inflight_packet, issued, issue_unit_id, exception_possible); -endinterface - interface fifo_interface #(parameter DATA_WIDTH = 42);//#(parameter type data_type = logic[31:0]); logic push; logic pop; @@ -218,30 +218,30 @@ interface load_store_queue_interface; logic [3:0] be; logic [2:0] fn3; logic [31:0] data_in; - instruction_id_t id; + id_t id; logic forwarded_store; - instruction_id_t data_id; + id_t data_id; logic possible_issue; logic new_issue; logic ready; - instruction_id_t id_needed_by_store; + id_t id_needed_by_store; data_access_shared_inputs_t transaction_out; logic transaction_ready; + logic empty; logic accepted; - - modport queue (input addr, load, store, be, fn3, data_in, id, forwarded_store, data_id, possible_issue, new_issue, accepted, output ready, id_needed_by_store, transaction_out, transaction_ready); - modport ls (output addr, load, store, be, fn3, data_in, id, forwarded_store, data_id, possible_issue, new_issue, accepted, input ready, id_needed_by_store, transaction_out, transaction_ready); + modport queue (input addr, load, store, be, fn3, data_in, id, forwarded_store, data_id, possible_issue, new_issue, accepted, output ready, id_needed_by_store, transaction_out, transaction_ready, empty); + modport ls (output addr, load, store, be, fn3, data_in, id, forwarded_store, data_id, possible_issue, new_issue, accepted, input ready, id_needed_by_store, transaction_out, transaction_ready, empty); endinterface interface writeback_store_interface; - instruction_id_t id_needed_at_issue; - instruction_id_t id_needed_at_commit; - instruction_id_t commit_id; + id_t id_needed_at_issue; + id_t id_needed_at_commit; + id_t commit_id; logic commit; - logic [MAX_INFLIGHT_COUNT-1:0] hold_for_store_ids; + logic [MAX_IDS-1:0] hold_for_store_ids; logic forwarding_data_ready; logic [31:0] forwarded_data; @@ -293,15 +293,3 @@ interface unsigned_division_interface #(parameter DATA_WIDTH = 32); modport divider (output remainder, quotient, done, divisor_is_zero, input dividend, divisor, start); endinterface -//Unit sets the ID of the instruction that will provide the data -//data_valid is high when the data is valid -interface post_issue_forwarding_interface; - instruction_id_t id; - - logic [31:0] data; - logic data_valid; - - modport unit (input data, data_valid, output id); - modport wb (output data, data_valid, input id); -endinterface - diff --git a/core/load_store_queue.sv b/core/load_store_queue.sv index 4d64ded..d7a70d9 100644 --- a/core/load_store_queue.sv +++ b/core/load_store_queue.sv @@ -33,16 +33,16 @@ module load_store_queue //ID-based input buffer for Load/Store Unit input logic gc_issue_flush, load_store_queue_interface.queue lsq, - output logic [MAX_INFLIGHT_COUNT-1:0] wb_hold_for_store_ids, + output logic [MAX_IDS-1:0] wb_hold_for_store_ids, //Writeback data input logic [31:0] writeback_data, input logic writeback_valid ); - logic [MAX_INFLIGHT_COUNT-1:0] valid; - logic [$clog2(MAX_INFLIGHT_COUNT)-1:0] hold_for_store_ids [MAX_INFLIGHT_COUNT]; - logic [$clog2(MAX_INFLIGHT_COUNT)-1:0] hold_for_store_ids_r [MAX_INFLIGHT_COUNT]; - instruction_id_t oldest_id; + logic [MAX_IDS-1:0] valid; + logic [$clog2(MAX_IDS)-1:0] hold_for_store_ids [MAX_IDS]; + logic [$clog2(MAX_IDS)-1:0] hold_for_store_ids_r [MAX_IDS]; + id_t oldest_id; typedef struct packed { logic [31:0] addr; @@ -51,24 +51,24 @@ module load_store_queue //ID-based input buffer for Load/Store Unit logic [3:0] be; logic [2:0] fn3; logic [31:0] data_in; - instruction_id_t id; + id_t id; logic forwarded_store; - instruction_id_t data_id; + id_t data_id; } lsq_entry_t; lsq_entry_t new_lsq_entry; - logic [$bits(lsq_entry_t)-1:0] lsq_entries [MAX_INFLIGHT_COUNT]; + logic [$bits(lsq_entry_t)-1:0] lsq_entries [MAX_IDS]; lsq_entry_t oldest_lsq_entry; - fifo_interface #(.DATA_WIDTH($bits(instruction_id_t))) oldest_fifo (); + fifo_interface #(.DATA_WIDTH($bits(id_t))) oldest_fifo (); //////////////////////////////////////////////////// //Implementation - //Can accept an input so long as it is a load or as long as an update from writeback for an exisiting store is not in progress + //Can always buffer new requests assign lsq.ready = 1; //FIFO to store ordering of IDs - taiga_fifo #(.DATA_WIDTH($bits(instruction_id_t)), .FIFO_DEPTH(MAX_INFLIGHT_COUNT)) oldest_id_fifo ( + taiga_fifo #(.DATA_WIDTH($bits(id_t)), .FIFO_DEPTH(MAX_IDS)) oldest_id_fifo ( .clk, .rst(rst | gc_issue_flush), .fifo(oldest_fifo) ); @@ -79,6 +79,8 @@ module load_store_queue //ID-based input buffer for Load/Store Unit assign oldest_fifo.pop = lsq.accepted; assign oldest_id = oldest_fifo.data_out; + assign lsq.empty = ~oldest_fifo.valid; + //////////////////////////////////////////////////// //Request attributes and input data (LUTRAMs) always_comb begin diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 686e6e7..8236edf 100755 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -55,20 +55,15 @@ module load_store_unit ( //Writeback-Store Interface writeback_store_interface.ls wb_store, - input instruction_id_t oldest_id, - output logic load_store_exception_clear, - output instruction_id_t load_store_exception_id, - input logic potential_exception, - + //CSR support input logic[31:0] csr_rd, - input instruction_id_t csr_id, + input id_t csr_id, input logic csr_done, + output logic ls_is_idle, output exception_packet_t ls_exception, - output logic ls_exception_valid, - input logic ls_exception_ack, - output unit_writeback_t wb + unit_writeback_interface.unit wb ); localparam NUM_SUB_UNITS = USE_D_SCRATCH_MEM+USE_BUS+USE_DCACHE; @@ -108,11 +103,12 @@ module load_store_unit ( logic [NUM_SUB_UNITS-1:0] sub_unit_address_match; logic unit_stall; + logic done_r; typedef struct packed{ logic [2:0] fn3; logic [1:0] byte_addr; - instruction_id_t instruction_id; + id_t id; logic [NUM_SUB_UNITS_W-1:0] subunit_id; } load_attributes_t; load_attributes_t load_attributes_in, stage2_attr; @@ -133,12 +129,7 @@ module load_store_unit ( //////////////////////////////////////////////////// //Alignment Exception - instruction_id_t exception_id; - logic exception_is_store; - generate if (ENABLE_M_MODE) begin - assign load_store_exception_clear = issue.new_request; - assign load_store_exception_id = issue.instruction_id; always_comb begin case(ls_inputs.fn3) @@ -151,16 +142,9 @@ generate if (ENABLE_M_MODE) begin assign ls_exception.valid = unaligned_addr & issue.new_request; assign ls_exception.code = ls_inputs.store ? STORE_AMO_ADDR_MISSALIGNED : LOAD_ADDR_MISSALIGNED; - assign ls_exception.pc = ls_inputs.pc; assign ls_exception.tval = virtual_address; - assign ls_exception.id = issue.instruction_id; + assign ls_exception.id = issue.id; - always_ff @ (posedge clk) begin - if (ls_exception.valid) begin - exception_is_store <= ls_inputs.store; - exception_id <= issue.instruction_id; - end - end end endgenerate //////////////////////////////////////////////////// @@ -199,14 +183,14 @@ endgenerate assign lsq.data_in = ls_inputs.rs2; assign lsq.load = ls_inputs.load; assign lsq.store = ls_inputs.store; - assign lsq.id = issue.instruction_id; + assign lsq.id = issue.id; assign lsq.forwarded_store = ls_inputs.forwarded_store; assign lsq.data_id = ls_inputs.store_forward_id; assign lsq.possible_issue = issue.possible_issue & ~unaligned_addr; assign lsq.new_issue = issue.new_request & ~unaligned_addr; - logic [MAX_INFLIGHT_COUNT-1:0] wb_hold_for_store_ids; + logic [MAX_IDS-1:0] wb_hold_for_store_ids; load_store_queue lsq_block (.*, .writeback_valid(wb_store.forwarding_data_ready), .writeback_data(wb_store.forwarded_data)); assign shared_inputs = lsq.transaction_out; @@ -214,16 +198,9 @@ endgenerate //////////////////////////////////////////////////// //ID Management - assign store_complete = (lsq.accepted & lsq.transaction_out.store) | (ls_exception_ack & exception_is_store); - assign store_id = $clog2(MAX_IDS)'(wb_store.commit_id); + assign store_complete = lsq.accepted & lsq.transaction_out.store; + assign store_id = lsq.transaction_out.id; - //////////////////////////////////////////////////// - //Writeback-Store interface - assign wb_store.id_needed_at_issue = ls_inputs.store_forward_id; - assign wb_store.id_needed_at_commit = lsq.id_needed_by_store; - assign wb_store.commit_id = ls_exception_ack ? exception_id : lsq.transaction_out.id; - assign wb_store.commit = (lsq.accepted & lsq.transaction_out.store) | (ls_exception_ack & exception_is_store); - assign wb_store.hold_for_store_ids = wb_hold_for_store_ids; //////////////////////////////////////////////////// //Unit tracking assign current_unit = sub_unit_address_match; @@ -245,10 +222,12 @@ endgenerate //////////////////////////////////////////////////// //Primary Control Signals + assign ls_is_idle = lsq.empty & (~load_attributes.valid); + assign units_ready = &unit_ready; assign load_complete = |unit_data_valid; - assign ready_for_issue = units_ready & (~unit_switch_stall); + assign ready_for_issue = units_ready & (~unit_switch_stall) & (~done_r | wb.ack); assign issue.ready = lsq.ready; assign issue_request = lsq.accepted; @@ -259,11 +238,11 @@ endgenerate taiga_fifo #(.DATA_WIDTH($bits(load_attributes_t)), .FIFO_DEPTH(ATTRIBUTES_DEPTH)) attributes_fifo (.fifo(load_attributes), .*); assign load_attributes_in.fn3 = shared_inputs.fn3; assign load_attributes_in.byte_addr = shared_inputs.addr[1:0]; - assign load_attributes_in.instruction_id = shared_inputs.id; + assign load_attributes_in.id = shared_inputs.id; assign load_attributes.data_in = load_attributes_in; assign load_attributes.push = issue_request & shared_inputs.load; - assign load_attributes.pop = load_complete; + assign load_attributes.pop = ((done_r | load_complete) & wb.ack); assign load_attributes.supress_push = 0; assign stage2_attr = load_attributes.data_out; @@ -338,9 +317,17 @@ endgenerate //////////////////////////////////////////////////// //Output bank + always_ff @ (posedge clk) begin + if (wb.ack) + done_r <= 0; + else if (load_complete) + done_r <= 1; + end + + assign wb.rd = csr_done ? csr_rd : final_load_data; - assign wb.done = csr_done | load_complete | (ls_exception_ack & ~exception_is_store); - assign wb.id = csr_done ? csr_id : (ls_exception_ack ? exception_id : stage2_attr.instruction_id); + assign wb.done = csr_done | load_complete | done_r; + assign wb.id = csr_done ? csr_id : stage2_attr.id; //////////////////////////////////////////////////// //End of Implementation diff --git a/core/mul_unit.sv b/core/mul_unit.sv index fdd0bd0..e9a6099 100755 --- a/core/mul_unit.sv +++ b/core/mul_unit.sv @@ -30,17 +30,20 @@ module mul_unit( input mul_inputs_t mul_inputs, unit_issue_interface.unit issue, - output unit_writeback_t wb + unit_writeback_interface.unit wb ); logic signed [63:0] result; logic mulh [2]; logic done [2]; - instruction_id_t id [2]; + id_t id [2]; logic rs1_signed, rs2_signed; logic signed [32:0] rs1_ext, rs2_ext; logic signed [32:0] rs1_r, rs2_r; + + logic stage1_advance; + logic stage2_advance; //////////////////////////////////////////////////// //Implementation assign rs1_signed = mul_inputs.op[1:0] inside {MULH_fn3[1:0], MULHSU_fn3[1:0]};//MUL doesn't matter @@ -49,26 +52,36 @@ module mul_unit( assign rs1_ext = signed'({mul_inputs.rs1[31] & rs1_signed, mul_inputs.rs1}); assign rs2_ext = signed'({mul_inputs.rs2[31] & rs2_signed, mul_inputs.rs2}); + assign issue.ready = stage1_advance; + assign stage1_advance = ~done[0] | stage2_advance; + assign stage2_advance = ~done[1] | wb.ack; + //Input and output registered Multiply always_ff @ (posedge clk) begin - rs1_r <= rs1_ext; - rs2_r <= rs2_ext; - result <= 64'(rs1_r * rs2_r); + if (stage1_advance) begin + rs1_r <= rs1_ext; + rs2_r <= rs2_ext; + end + if (stage2_advance) begin + result <= 64'(rs1_r * rs2_r); + end end always_ff @ (posedge clk) begin - mulh[0] <= (mul_inputs.op[1:0] != MUL_fn3[1:0]); - id[0] <= issue.instruction_id; - done[0] <= issue.new_request; - - mulh[1] <= mulh[0]; - id[1] <= id[0]; - done[1] <= done[0]; + if (stage1_advance) begin + mulh[0] <= (mul_inputs.op[1:0] != MUL_fn3[1:0]); + id[0] <= issue.id; + done[0] <= issue.new_request; + end + if (stage2_advance) begin + mulh[1] <= mulh[0]; + id[1] <= id[0]; + done[1] <= done[0]; + end end //Issue/write-back handshaking //////////////////////////////////////////////////// - assign issue.ready = 1; assign wb.rd = mulh[1] ? result[63:32] : result[31:0]; assign wb.done = done[1]; assign wb.id = id[1]; diff --git a/core/one_hot_to_integer.sv b/core/one_hot_to_integer.sv index d681e9d..13eb361 100755 --- a/core/one_hot_to_integer.sv +++ b/core/one_hot_to_integer.sv @@ -58,8 +58,8 @@ module one_hot_to_integer //////////////////////////////////////////////////// //Assertions - always_ff @ (posedge clk) begin - assert (rst || (~rst && $onehot0(one_hot))) else $error("One-hot signal has multiple bits set!"); - end + // always_ff @ (posedge clk) begin + // assert (rst || (~rst && $onehot0(one_hot))) else $error("One-hot signal has multiple bits set!"); + //end endmodule diff --git a/core/pre_decode.sv b/core/pre_decode.sv deleted file mode 100755 index 324b5e0..0000000 --- a/core/pre_decode.sv +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright © 2017-2019 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 - */ - -import taiga_config::*; -import riscv_types::*; -import taiga_types::*; - -module pre_decode - ( - input logic clk, - input logic rst, - - //Fetch - input logic [31:0] pre_decode_instruction, - input logic [31:0] pre_decode_pc, - input branch_predictor_metadata_t branch_metadata, - input logic branch_prediction_used, - input logic [BRANCH_PREDICTOR_WAYS-1:0] bp_update_way, - input logic pre_decode_push, - - //Global Control - input logic gc_fetch_flush, - - //Decode - input logic pre_decode_pop, - output logic fb_valid, - output fetch_buffer_packet_t fb - ); - - logic buffer_reset; - - fetch_buffer_packet_t new_data; - fetch_buffer_packet_t data_in; - fetch_buffer_packet_t data_out; - fifo_interface #(.DATA_WIDTH($bits(fetch_buffer_packet_t))) fb_fifo(); - - //////////////////////////////////////////////////// - //Implementation - //FIFO - assign buffer_reset = rst | gc_fetch_flush; - assign fb_fifo.supress_push = 0;//Covered by reseting on gc_fetch_flush - - assign fb_fifo.push = pre_decode_push; - assign fb_fifo.pop = pre_decode_pop; - assign fb_fifo.data_in = data_in; - assign fb = fb_fifo.data_out; - assign fb_valid = fb_fifo.valid; - - taiga_fifo #( - .DATA_WIDTH($bits(fetch_buffer_packet_t)), - .FIFO_DEPTH(FETCH_BUFFER_DEPTH) - ) fb_fifo_block (.fifo(fb_fifo), .rst(buffer_reset), .*); - - //////////////////////////////////////////////////// - //Pre-Decode - assign data_in.instruction = pre_decode_instruction; - assign data_in.pc = pre_decode_pc; - - //////////////////////////////////////////////////// - //Branch Predictor support - assign data_in.branch_metadata = branch_metadata; - assign data_in.branch_prediction_used = branch_prediction_used; - assign data_in.bp_update_way = bp_update_way; - - //////////////////////////////////////////////////// - //Assertions - -endmodule diff --git a/core/register_file.sv b/core/register_file.sv index 7a8cf09..190f14f 100755 --- a/core/register_file.sv +++ b/core/register_file.sv @@ -33,6 +33,9 @@ module register_file( register_file_writeback_interface.rf wb, register_file_issue_interface.rf issue, + //ID Metadata + input logic [4:0] retired_rd_addr, + //Trace signals output logic tr_rs1_forwarding_needed, output logic tr_rs2_forwarding_needed, @@ -40,7 +43,7 @@ module register_file( ); (* ramstyle = "MLAB, no_rw_check" *) logic [XLEN-1:0] register [32]; - (* ramstyle = "MLAB, no_rw_check" *) instruction_id_t in_use_by [32]; + (* ramstyle = "MLAB, no_rw_check" *) id_t in_use_by [32]; logic rs1_inuse; logic rs2_inuse; @@ -57,16 +60,16 @@ module register_file( //Writeback unit does not assert wb.commit when the target register is r0 always_ff @ (posedge clk) begin - if (~gc_supress_writeback & valid_write) - register[wb.rd_addr] <= wb.rd_data; + if (~gc_supress_writeback & in_use_match) + register[retired_rd_addr] <= wb.rd_data; end - assign in_use_match = (wb.id == in_use_by[wb.rd_addr]) && valid_write; + assign in_use_match = (wb.id == in_use_by[retired_rd_addr]) && valid_write; reg_inuse inuse (.*, .clr(1'b0), .rs1_addr(issue.rs1_addr),.rs2_addr(issue.rs2_addr), .issued_rd_addr(issue.rd_addr), - .retired_rd_addr(wb.rd_addr), + .retired_rd_addr(retired_rd_addr), .issued(issue.instruction_issued), .retired(in_use_match), .rs1_inuse(rs1_inuse), @@ -82,7 +85,7 @@ module register_file( assign wb.rs2_id = in_use_by[issue.rs2_addr]; assign issue.rs2_id = wb.rs2_id; - assign valid_write = wb.rd_nzero & wb.retiring; + assign valid_write = (|retired_rd_addr) & wb.retiring; assign rs1_feedforward = rs1_inuse; assign rs2_feedforward = rs2_inuse; diff --git a/core/taiga.sv b/core/taiga.sv index cf81310..160d8b7 100755 --- a/core/taiga.sv +++ b/core/taiga.sv @@ -66,13 +66,11 @@ module taiga ( div_inputs_t div_inputs; gc_inputs_t gc_inputs; - unit_issue_interface unit_issue [NUM_UNITS-1:0](); + unit_issue_interface unit_issue [NUM_UNITS](); exception_packet_t ls_exception; - logic ls_exception_valid; - tracking_interface ti(); - unit_writeback_t unit_wb [NUM_WB_UNITS-1:0]; + unit_writeback_interface unit_wb [NUM_WB_UNITS](); register_file_writeback_interface rf_wb(); mmu_interface immu(); @@ -111,10 +109,14 @@ module taiga ( id_t store_id; logic branch_complete; id_t branch_id; - logic system_op_complete; - id_t system_op_id; + logic system_op_or_exception_complete; + id_t system_op_or_exception_id; logic instruction_retired; id_t retired_id; + logic [4:0] retired_rd_addr; + //Exception + id_t exception_id; + logic [31:0] exception_pc; //Global Control logic gc_issue_hold; @@ -122,13 +124,14 @@ module taiga ( logic gc_fetch_flush; logic gc_fetch_pc_override; logic gc_supress_writeback; - instruction_id_t oldest_id; + id_t oldest_id; logic [31:0] gc_fetch_pc; logic ls_exception_ack; logic[31:0] csr_rd; - instruction_id_t csr_id; + id_t csr_id; logic csr_done; + logic ls_is_idle; //Decode Unit and Fetch Unit logic illegal_instruction; @@ -143,9 +146,9 @@ module taiga ( //LS writeback_store_interface wb_store(); - logic load_store_exception_clear; - instruction_id_t load_store_exception_id; - logic potential_exception; + //WB + logic single_cycle_issue_possible; + logic writeback_is_idle; //Trace Interface Signals logic tr_operand_stall; @@ -180,8 +183,8 @@ module taiga ( logic tr_rs1_and_rs2_forwarding_needed; unit_id_t tr_num_instructions_completing; - instruction_id_t tr_num_instructions_in_flight; - instruction_id_t tr_num_of_instructions_pending_writeback; + id_t tr_num_instructions_in_flight; + id_t tr_num_of_instructions_pending_writeback; //////////////////////////////////////////////////// //Implementation diff --git a/core/taiga_config.sv b/core/taiga_config.sv index 75eb344..0551da2 100755 --- a/core/taiga_config.sv +++ b/core/taiga_config.sv @@ -163,11 +163,13 @@ package taiga_config; //////////////////////////////////////////////////// - //FIFO/Buffer Depths - //All parameters restricted to powers of two - parameter MAX_IDS = 16; - parameter MAX_INFLIGHT_COUNT = 4; - parameter FETCH_BUFFER_DEPTH = 4; + //ID limit + //MAX_IDS restricted to a power of 2 + parameter MAX_IDS = 32; + + //////////////////////////////////////////////////// + //Number of Writeback Buffers + parameter WRITEBACK_BUFFERS = 3; //////////////////////////////////////////////////// //Trace Options @@ -185,15 +187,19 @@ package taiga_config; //////////////////////////////////////////////////// //Write-Back Unit IDs - parameter NUM_WB_UNITS = 2 + USE_MUL + USE_DIV; - parameter NUM_UNITS = NUM_WB_UNITS + 2; + parameter NUM_MULTI_CYCLE_WB_UNITS = 1 + USE_MUL + USE_DIV;//LS + parameter NUM_SINGLE_CYCLE_WB_UNITS = 1;//ALU - parameter ALU_UNIT_WB_ID = 0; - parameter LS_UNIT_WB_ID = 1; + parameter NUM_WB_UNITS = NUM_MULTI_CYCLE_WB_UNITS + NUM_SINGLE_CYCLE_WB_UNITS; + + parameter NUM_UNITS = NUM_WB_UNITS + 2;//Branch and CSRs + + parameter LS_UNIT_WB_ID = 0; parameter DIV_UNIT_WB_ID = LS_UNIT_WB_ID + USE_DIV; - parameter MUL_UNIT_WB_ID = DIV_UNIT_WB_ID + USE_MUL; + parameter MUL_UNIT_WB_ID = DIV_UNIT_WB_ID + 1; + parameter ALU_UNIT_WB_ID = MUL_UNIT_WB_ID + USE_MUL; //Non-writeback units - parameter BRANCH_UNIT_ID = MUL_UNIT_WB_ID + 1; + parameter BRANCH_UNIT_ID = ALU_UNIT_WB_ID + 1; parameter GC_UNIT_ID = BRANCH_UNIT_ID + 1; //////////////////////////////////////////////////// diff --git a/core/taiga_types.sv b/core/taiga_types.sv index f80f492..239f869 100755 --- a/core/taiga_types.sv +++ b/core/taiga_types.sv @@ -24,12 +24,10 @@ package taiga_types; import taiga_config::*; import riscv_types::*; - localparam ID_W = $clog2(MAX_INFLIGHT_COUNT); localparam WB_UNITS_WIDTH = $clog2(NUM_WB_UNITS); typedef logic[$clog2(MAX_IDS)-1:0] id_t; - typedef logic[ID_W-1:0] instruction_id_t; typedef logic[WB_UNITS_WIDTH-1:0] unit_id_t; typedef logic[1:0] branch_predictor_metadata_t; @@ -63,24 +61,10 @@ package taiga_types; typedef struct packed{ logic valid; exception_code_t code; - logic [31:0] pc; logic [31:0] tval; - instruction_id_t id; + id_t id; } exception_packet_t; - typedef struct packed{ - logic [4:0] rd_addr; - logic is_store; - } inflight_instruction_packet; - - typedef struct packed{ - logic [31:0] instruction; - logic [31:0] pc; - branch_predictor_metadata_t branch_metadata; - logic branch_prediction_used; - logic [BRANCH_PREDICTOR_WAYS-1:0] bp_update_way; - } fetch_buffer_packet_t; - typedef struct packed{ branch_predictor_metadata_t branch_predictor_metadata; logic branch_prediction_used; @@ -88,21 +72,6 @@ package taiga_types; } branch_metadata_t; - typedef struct packed{ - logic id_assigned; - id_t pc_id; - logic [31:0] pc; - logic complete; - id_t instruction_id; - logic [31:0] instruction; - } fetch_instruction_metadata_t; - - typedef struct packed{ - instruction_id_t id; - logic done; - logic [XLEN-1:0] rd; - } unit_writeback_t; - typedef struct packed{ logic [XLEN:0] in1;//contains sign padding bit for slt operation logic [XLEN:0] in2;//contains sign padding bit for slt operation @@ -159,9 +128,7 @@ package taiga_types; logic load; logic store; logic forwarded_store; - instruction_id_t store_forward_id; - //exception support - logic [31:0] pc; + id_t store_forward_id; //amo support amo_details_t amo; } load_store_inputs_t; @@ -216,7 +183,7 @@ package taiga_types; logic [3:0] be; logic [2:0] fn3; logic [31:0] data_in; - instruction_id_t id; + id_t id; } data_access_shared_inputs_t; typedef enum { @@ -260,8 +227,8 @@ package taiga_types; //Writeback unit_id_t num_instructions_completing; - instruction_id_t num_instructions_in_flight; - instruction_id_t num_of_instructions_pending_writeback; + id_t num_instructions_in_flight; + id_t num_of_instructions_pending_writeback; } taiga_trace_events_t; typedef struct packed { diff --git a/core/write_back.sv b/core/write_back.sv index cfe20ba..4334d1b 100755 --- a/core/write_back.sv +++ b/core/write_back.sv @@ -1,5 +1,5 @@ /* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon + * 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. @@ -31,199 +31,188 @@ module write_back( input logic gc_fetch_flush, input logic instruction_issued_with_rd, - input unit_writeback_t unit_wb[NUM_WB_UNITS-1:0], + unit_writeback_interface.wb unit_wb[NUM_WB_UNITS], register_file_writeback_interface.writeback rf_wb, - tracking_interface.wb ti, + output logic instruction_retired, output id_t retired_id, - output logic instruction_queue_empty, - output instruction_id_t oldest_id, - - input logic load_store_exception_clear, - input instruction_id_t load_store_exception_id, - output logic potential_exception, - - //Writeback-Store Interface - writeback_store_interface.wb wb_store, + output logic single_cycle_issue_possible, + output logic writeback_is_idle, //Trace signals output unit_id_t tr_num_instructions_completing, - output instruction_id_t tr_num_instructions_in_flight, - output instruction_id_t tr_num_of_instructions_pending_writeback + output id_t tr_num_instructions_in_flight, + output id_t tr_num_of_instructions_pending_writeback ); ////////////////////////////////////// - - //Inflight metadata for IDs - (* ramstyle = "MLAB, no_rw_check" *) logic[$bits(inflight_instruction_packet)-1:0] id_metadata [MAX_INFLIGHT_COUNT-1:0]; - + logic unit_ack [NUM_WB_UNITS]; //aliases for write-back-interface signals - instruction_id_t unit_instruction_id [NUM_WB_UNITS-1:0]; - logic [NUM_WB_UNITS-1:0] unit_done; - logic [XLEN-1:0] unit_rd [NUM_WB_UNITS-1:0]; + id_t unit_instruction_id [NUM_WB_UNITS]; + logic unit_done [NUM_WB_UNITS]; + logic [XLEN-1:0] unit_rd [NUM_WB_UNITS]; //Per-ID muxes for commit buffer - logic [$clog2(NUM_WB_UNITS)-1:0] id_unit_select [MAX_INFLIGHT_COUNT-1:0]; - logic [$clog2(NUM_WB_UNITS)-1:0] id_unit_select_r [MAX_INFLIGHT_COUNT-1:0]; + logic [$clog2(NUM_WB_UNITS)-1:0] buffer_unit_select [WRITEBACK_BUFFERS]; //Commit buffer - logic [XLEN-1:0] results_by_id [MAX_INFLIGHT_COUNT-1:0]; - logic [XLEN-1:0] results_by_id_new [MAX_INFLIGHT_COUNT-1:0]; - instruction_id_t id_retiring; - inflight_instruction_packet retiring_instruction_packet; + typedef struct packed{ + logic [XLEN-1:0] rd; + id_t id; + } commit_buffer_t; + commit_buffer_t commit_buffer [WRITEBACK_BUFFERS]; + logic commit_buffer_valid [WRITEBACK_BUFFERS]; - logic [MAX_INFLIGHT_COUNT-1:0] id_inuse; - logic [MAX_INFLIGHT_COUNT-1:0] id_potential_exception; - logic [MAX_INFLIGHT_COUNT-1:0] exception_cleared_one_hot; + id_t id_retiring; - logic [MAX_INFLIGHT_COUNT-1:0] id_writeback_pending; - logic [MAX_INFLIGHT_COUNT-1:0] id_writeback_pending_r; + localparam LOG2_WRITEBACK_BUFFERS = $clog2(WRITEBACK_BUFFERS); - logic [MAX_INFLIGHT_COUNT-1:0] id_writing_to_buffer; + logic retiring; + logic [$clog2(NUM_WB_UNITS):0] num_units_done; + logic [$clog2(WRITEBACK_BUFFERS):0] num_buffers_ready; - logic [MAX_INFLIGHT_COUNT-1:0] id_retiring_one_hot; - logic [MAX_INFLIGHT_COUNT-1:0] id_issued_one_hot; + logic result_ready [WRITEBACK_BUFFERS]; - logic retiring_next_cycle, retiring; + logic commit_buffer_ready [WRITEBACK_BUFFERS]; + + logic [LOG2_WRITEBACK_BUFFERS-1:0] commit_buffer_index_retiring; + + genvar i, j; //////////////////////////////////////////////////// //Implementation //Re-assigning interface inputs to array types so that they can be dynamically indexed - genvar i; - generate - for (i=0; i< NUM_WB_UNITS; i++) begin : interface_to_array_g - assign unit_instruction_id[i] = unit_wb[i].id; - assign unit_done[i] = unit_wb[i].done; - assign unit_rd[i] = unit_wb[i].rd; - end - endgenerate + generate for (i=0; i< NUM_WB_UNITS; i++) begin : wb_interfaces_to_arrays_g + assign unit_instruction_id[i] = unit_wb[i].id; + assign unit_done[i] = unit_wb[i].done; + assign unit_rd[i] = unit_wb[i].rd; + assign unit_wb[i].ack = unit_ack[i]; + end endgenerate //////////////////////////////////////////////////// - //ID done determination - //For each ID, check if a unit is reporting that ID as done and OR the results together - //Additionally, OR the result of any store operation completing + //Unit done determination always_comb begin - id_writing_to_buffer = '0; - for (int i=0; i< MAX_INFLIGHT_COUNT; i++) begin - for (int j=0; j< NUM_WB_UNITS; j++) begin - id_writing_to_buffer[i] |= (unit_instruction_id[j] == ID_W'(i)) && unit_done[j]; - end - id_writing_to_buffer[i] |= (wb_store.commit_id == ID_W'(i)) && wb_store.commit; + num_units_done = 0; + for (int i=0; i < NUM_MULTI_CYCLE_WB_UNITS; i++) begin + num_units_done += ($clog2(NUM_WB_UNITS)+1)'(unit_done[i]); end + num_buffers_ready = 0; + for (int i=0; i < WRITEBACK_BUFFERS; i++) begin + num_buffers_ready += ($clog2(WRITEBACK_BUFFERS)+1)'(commit_buffer_ready[i]); + end + single_cycle_issue_possible = (($clog2(NUM_WB_UNITS)+1)'(num_buffers_ready) > num_units_done); + end + + //////////////////////////////////////////////////// + //Commit Buffer index retiring + //Priority given to decreasing indices + always_comb begin + commit_buffer_index_retiring = 0; + for (int i=WRITEBACK_BUFFERS-1; i >= 0; i--) begin + if (commit_buffer_valid[i]) + commit_buffer_index_retiring = LOG2_WRITEBACK_BUFFERS'(i); + end + end + + //////////////////////////////////////////////////// + //Commit Buffer ready to accept new data + always_comb begin + for (int i=0; i < WRITEBACK_BUFFERS; i++) begin + commit_buffer_ready[i] = ~commit_buffer_valid[i]; + end + //Can always retire, so if not retiring, this index will not be valid and thus ready to commit to + commit_buffer_ready[commit_buffer_index_retiring] = 1; end //////////////////////////////////////////////////// //Unit select for writeback buffer - //Set unit_ID for each ID as they are issued - //If ID is not in use, use the current issue_unit_id value - //This is used to support single cycle units, such as the ALU + logic commit_buffer_write [WRITEBACK_BUFFERS]; always_comb begin - id_issued_one_hot = 0; - id_issued_one_hot[ti.issue_id] = 1; - id_issued_one_hot &= {MAX_INFLIGHT_COUNT{ti.issued}}; + unit_ack = '{default: 0}; + buffer_unit_select = '{default: 0}; + commit_buffer_write = '{default: 0}; + for (int i=0; i < WRITEBACK_BUFFERS; i++) begin + for (int j=0; j < NUM_WB_UNITS; j++) begin + if (unit_done[j] & ~unit_ack[j] & ~commit_buffer_write[i]) begin + buffer_unit_select[i] = $clog2(NUM_WB_UNITS)'(j); + unit_ack[j] = commit_buffer_ready[i]; + commit_buffer_write[i] = commit_buffer_ready[i]; + end + end + end + // single_cycle_issue_possible = 0; + // for (int i=0; i < WRITEBACK_BUFFERS; i++) begin + // if (commit_buffer_ready[i] & ~commit_buffer_write[i]) begin + // single_cycle_issue_possible = 1; + // buffer_unit_select[i] = ALU_UNIT_WB_ID; + // commit_buffer_write[i] = 1; + // break; + // end + // end end - generate for (i=0; i< MAX_INFLIGHT_COUNT; i++) begin - always_ff @ (posedge clk) begin - if (id_issued_one_hot[i]) - id_unit_select_r[i] <= ti.issue_unit_id; - end - assign id_unit_select[i] = id_inuse[i] ? id_unit_select_r[i] : ti.issue_unit_id; - end endgenerate - //////////////////////////////////////////////////// - //Writeback Buffer - //Mux outputs of units based on IDs - //If ID is done write result to buffer - generate for (i=0; i< MAX_INFLIGHT_COUNT; i++) begin - always_ff @ (posedge clk) begin - if (id_writing_to_buffer[i]) - results_by_id[i] <= unit_rd[id_unit_select[i]]; - end - end endgenerate - - //////////////////////////////////////////////////// - //Unit Forwarding Support - //Track whether an ID has written to the commit buffer - set_clr_reg_with_rst #(.SET_OVER_CLR(0), .WIDTH($bits(id_inuse)), .RST_VALUE('0)) id_inuse_m ( - .clk, .rst, - .set(id_issued_one_hot), - .clr(id_writing_to_buffer), - .result(id_inuse) - ); - - assign wb_store.forwarding_data_ready = ~id_inuse[wb_store.id_needed_at_commit]; - assign wb_store.forwarded_data = results_by_id[wb_store.id_needed_at_commit]; - - //////////////////////////////////////////////////// - //ID Tracking - //Provides ordering of IDs, ID for issue and oldest ID for committing to register file - writeback_id_tracking id_counters (.*, .issued(ti.issued), .retired(retiring_next_cycle), .id_available(ti.id_available), - .oldest_id(oldest_id), .next_id(ti.issue_id), .empty(instruction_queue_empty)); - - //////////////////////////////////////////////////// - //Metadata storage for IDs - //stores destination register for each ID and whether it is a store instruction - initial id_metadata = '{default: 0}; - //Inflight Instruction ID table - //Stores rd_addr and whether instruction is a store + //Writeback Commit Buffer always_ff @ (posedge clk) begin - if (ti.id_available) - id_metadata[ti.issue_id] <= ti.inflight_packet; + for (int i=0; i < WRITEBACK_BUFFERS; i++) begin + if (rst) + commit_buffer_valid[i] <= 0; + else + commit_buffer_valid[i] <= commit_buffer_write[i] | (commit_buffer_valid[i] & ~commit_buffer_ready[i]); + end end - assign retiring_instruction_packet = id_metadata[id_retiring]; - //////////////////////////////////////////////////// - //Potential Exception Tracking - // always_comb begin - // exception_cleared_one_hot = 0; - // exception_cleared_one_hot[load_store_exception_id] = load_store_exception_clear; - // end - // always_ff @ (posedge clk) begin - // if (rst) - // id_potential_exception <= 0; - // else - // id_potential_exception <= (id_potential_exception | {MAX_INFLIGHT_COUNT{ti.exception_possible}} & id_issued_one_hot) & ~exception_cleared_one_hot; - // end - // assign potential_exception = |id_potential_exception; + always_ff @ (posedge clk) begin + for (int i=0; i < WRITEBACK_BUFFERS; i++) begin + if (commit_buffer_ready[i]) begin + commit_buffer[i].rd <= unit_rd[buffer_unit_select[i]]; + commit_buffer[i].id <= unit_instruction_id[buffer_unit_select[i]]; + end + end + end //////////////////////////////////////////////////// //Register File Interface - //Track whether the ID has a pending write to the register file - always_ff @ (posedge clk) begin - if (rst) - id_writeback_pending_r <= 0; - else - id_writeback_pending_r <= id_writeback_pending; - end - - assign id_writeback_pending = id_writing_to_buffer | (id_writeback_pending_r & ~id_retiring_one_hot); - - //Is the oldest instruction ready to commit? - assign retiring_next_cycle = id_writeback_pending[oldest_id] & ~wb_store.hold_for_store_ids[oldest_id]; - - always_ff @(posedge clk) begin - retiring <= retiring_next_cycle; - id_retiring <= oldest_id; - end - always_comb begin - id_retiring_one_hot = 0; - id_retiring_one_hot[id_retiring] = retiring; + retiring = 0; + for (int i=0; i < WRITEBACK_BUFFERS; i++) begin + retiring |= commit_buffer_valid[i]; + end end + assign id_retiring = commit_buffer[commit_buffer_index_retiring].id; + //Instruction completion tracking for retired instruction count - assign instruction_retired = retiring & ~retiring_instruction_packet.is_store; - assign retired_id = $clog2(MAX_IDS)'(id_retiring); + assign instruction_retired = retiring; + assign retired_id = id_retiring; + - assign rf_wb.rd_addr = retiring_instruction_packet.rd_addr; assign rf_wb.id = id_retiring; assign rf_wb.retiring = instruction_retired; - assign rf_wb.rd_nzero = |retiring_instruction_packet.rd_addr; - assign rf_wb.rd_data = results_by_id[id_retiring]; + assign rf_wb.rd_data = commit_buffer[commit_buffer_index_retiring].rd; //Register bypass for issue operands - assign rf_wb.rs1_valid = id_writeback_pending_r[rf_wb.rs1_id];//includes the instruction writing to the register file - assign rf_wb.rs2_valid = id_writeback_pending_r[rf_wb.rs2_id]; - assign rf_wb.rs1_data = results_by_id[rf_wb.rs1_id]; - assign rf_wb.rs2_data = results_by_id[rf_wb.rs2_id]; + logic [WRITEBACK_BUFFERS-1:0] rs1_addr_match; + logic [WRITEBACK_BUFFERS-1:0] rs2_addr_match; + logic [LOG2_WRITEBACK_BUFFERS-1:0] rs1_sel; + logic [LOG2_WRITEBACK_BUFFERS-1:0] rs2_sel; + always_comb begin + writeback_is_idle = 0; + rs1_sel = {LOG2_WRITEBACK_BUFFERS{1'b?}}; + rs2_sel = {LOG2_WRITEBACK_BUFFERS{1'b?}}; + for (int i=0; i < WRITEBACK_BUFFERS; i++) begin + writeback_is_idle |= commit_buffer_valid[i]; + rs1_addr_match[i] = commit_buffer_valid[i] && (commit_buffer[i].id == rf_wb.rs1_id); + rs2_addr_match[i] = commit_buffer_valid[i] && (commit_buffer[i].id == rf_wb.rs2_id); + if (rs1_addr_match[i]) + rs1_sel = LOG2_WRITEBACK_BUFFERS'(i); + if (rs2_addr_match[i]) + rs2_sel = LOG2_WRITEBACK_BUFFERS'(i); + end + writeback_is_idle = ~writeback_is_idle; + end + + assign rf_wb.rs1_valid = |rs1_addr_match; + assign rf_wb.rs2_valid = |rs2_addr_match; + assign rf_wb.rs1_data = commit_buffer[rs1_sel].rd; + assign rf_wb.rs2_data = commit_buffer[rs2_sel].rd; //////////////////////////////////////////////////// //End of Implementation //////////////////////////////////////////////////// @@ -233,22 +222,23 @@ module write_back( //////////////////////////////////////////////////// //Trace Interface - generate if (ENABLE_TRACE_INTERFACE) begin - //Checks if any two pairs are set indicating mux contention - always_comb begin - tr_num_instructions_completing = 0; - for (int i=0; i 2 ? 2'b1 : 0; + // end + // end + // endgenerate endmodule diff --git a/tools/taiga_compile_order b/tools/taiga_compile_order index 5c28c11..457f62a 100644 --- a/tools/taiga_compile_order +++ b/tools/taiga_compile_order @@ -98,11 +98,9 @@ ../core/illegal_instruction_checker.sv ../core/decode_and_issue.sv -../core/id_inuse.sv ../core/reg_inuse.sv ../core/register_file.sv -../core/writeback_id_tracking.sv ../core/write_back.sv ../core/placer_randomizer.sv