diff --git a/ariane.sv b/ariane.sv index 49dcf1b32..b9854dc74 100644 --- a/ariane.sv +++ b/ariane.sv @@ -10,7 +10,7 @@ import ariane_pkg::*; module ariane #( - parameter N_EXT_PERF_COUNTERS = 0 + parameter N_EXT_PERF_COUNTERS = 0 ) ( input logic clk_i, @@ -60,9 +60,9 @@ module ariane logic [4:0] waddr_a_i; logic [63:0] wdata_a_i; logic we_a_i; - logic [4:0] alu_trans_id, trans_id_o; + logic [TRANS_ID_BITS-1:0] alu_trans_id, lsu_trans_id, trans_id_o; logic alu_valid_o; - logic [63:0] alu_result; + logic [63:0] alu_result, lsu_result; // synth stuff assign flush_i = 1'b0; @@ -102,7 +102,7 @@ module ariane logic lsu_req_i; logic lsu_gnt_o; logic lsu_we_i; - logic [3:0] lsu_be_i; + logic [7:0] lsu_be_i; logic lsu_err_o; logic [63:0] lsu_vaddr_i; priv_lvl_t priv_lvl_i; @@ -144,38 +144,39 @@ module ariane id_stage #( - .NR_WB_PORTS ( 1 ) + .NR_ENTRIES ( NR_SB_ENTRIES ), + .NR_WB_PORTS ( NR_WB_PORTS ) ) id_stage_i ( - .clk_i ( clk_i ), - .rst_ni ( rst_n ), - .test_en_i ( test_en_i ), - .flush_i ( flush_i ), - .instruction_i ( instr_rdata_id_o ), - .instruction_valid_i ( instr_valid_id_o ), - .pc_if_i ( pc_if_o ), // PC from if - .ex_i ( exception_if ), // exception from if - .ready_o ( ready_o ), - .operator_o ( operator_o ), - .operand_a_o ( operand_a_o ), - .operand_b_o ( operand_b_o ), - .trans_id_o ( trans_id_o ), - .alu_ready_i ( alu_ready_i ), - .alu_valid_o ( alu_valid_i ), - .lsu_ready_i ( ), - .lsu_valid_o ( ), - .mult_ready_i ( ), - .mult_valid_o ( ), - .trans_id_i ( {alu_trans_id} ), - .wdata_i ( {alu_result} ), - .wb_valid_i ( {alu_valid_o} ), + .clk_i ( clk_i ), + .rst_ni ( rst_n ), + .test_en_i ( test_en_i ), + .flush_i ( flush_i ), + .instruction_i ( instr_rdata_id_o ), + .instruction_valid_i ( instr_valid_id_o ), + .pc_if_i ( pc_if_o ), // PC from if + .ex_i ( exception_if ), // exception from if + .ready_o ( ready_o ), + .operator_o ( operator_o ), + .operand_a_o ( operand_a_o ), + .operand_b_o ( operand_b_o ), + .trans_id_o ( trans_id_o ), + .alu_ready_i ( alu_ready_i ), + .alu_valid_o ( alu_valid_i ), + .lsu_ready_i ( ), + .lsu_valid_o ( ), + .mult_ready_i ( ), + .mult_valid_o ( ), + .trans_id_i ( {alu_trans_id, lsu_trans_id} ), + .wdata_i ( {alu_result, lsu_result} ), + .wb_valid_i ( {alu_valid_o, l su_valid_o} ), - .waddr_a_i ( waddr_a_i ), - .wdata_a_i ( wdata_a_i ), - .we_a_i ( we_a_i ), + .waddr_a_i ( waddr_a_i ), + .wdata_a_i ( wdata_a_i ), + .we_a_i ( we_a_i ), - .commit_instr_o ( commit_instr_o ), - .commit_ack_i ( commit_ack_i ) + .commit_instr_o ( commit_instr_o ), + .commit_ack_i ( commit_ack_i ) ); ex_stage ex_stage_i ( @@ -186,6 +187,7 @@ module ariane .operand_b_i ( operand_b_o ), .trans_id_i ( trans_id_o ), .comparison_result_o ( comparison_result_o ), + .alu_ready_o ( alu_ready_i ), .alu_valid_i ( alu_valid_i ), .alu_result_o ( alu_result ), @@ -194,12 +196,15 @@ module ariane .lsu_ready_o ( lsu_ready_o ), .lsu_valid_i ( lsu_valid_i ), + .lsu_result_o ( lsu_result ), + .lsu_trans_id_o ( lsu_trans_id ), + .lsu_valid_o ( lsu_valid_o ), .mult_ready_o ( mult_ready_o ), .mult_valid_i ( mult_valid_i ) ); - commit_stage i_commit_stage ( + commit_stage commit_stage ( .clk_i ( clk_i ), .rst_ni ( rst_n ), .priv_lvl_o ( priv_lvl_o ), @@ -211,7 +216,7 @@ module ariane .we_a_o ( we_a_i ) ); - mmu i_mmu ( + mmu mmu_i ( .clk_i ( clk_i ), .rst_ni ( rst_n ), .enable_translation_i ( enable_translation_i ), @@ -223,7 +228,7 @@ module ariane .fetch_rdata_o ( fetch_rdata_o ), .lsu_req_i ( lsu_req_i ), .lsu_gnt_o ( lsu_gnt_o ), - .lsu_valid_o ( lsu_valid_o ), + .lsu_valid_o ( ), .lsu_we_i ( lsu_we_i ), .lsu_be_i ( lsu_be_i ), .lsu_err_o ( lsu_err_o ), diff --git a/ex_stage.sv b/ex_stage.sv index 37694a160..93ab39885 100644 --- a/ex_stage.sv +++ b/ex_stage.sv @@ -7,18 +7,21 @@ module ex_stage ( input fu_op operator_i, input logic [63:0] operand_a_i, input logic [63:0] operand_b_i, - input logic [4:0] trans_id_i, + input logic [TRANS_ID_BITS-1:0] trans_id_i, // ALU 1 output logic alu_ready_o, // FU is ready input logic alu_valid_i, // Output is valid output logic alu_valid_o, // ALU result is valid output logic [63:0] alu_result_o, - output logic [4:0] alu_trans_id_o, // ID of scoreboard entry at which to write back + output logic [TRANS_ID_BITS-1:0] alu_trans_id_o, // ID of scoreboard entry at which to write back output logic comparison_result_o, // LSU output logic lsu_ready_o, // FU is ready - input logic lsu_valid_i, // Output is valid + input logic lsu_valid_i, // Input is valid + output logic lsu_valid_o, // Output is valid + output logic [63:0] lsu_result_o, + output logic [TRANS_ID_BITS-1:0] lsu_trans_id_o, // MULT output logic mult_ready_o, // FU is ready input logic mult_valid_i // Output is valid @@ -45,6 +48,21 @@ alu alu_i ( // Load-Store Unit + assign lsu_valid_o = 1'b0; + assign lsu_trans_id_o = trans_id_i; + logic rst_n; + logic data_req_o; + logic data_gnt_i; + logic data_rvalid_i; + logic data_err_i; + logic [63:0] data_addr_o; + logic data_we_o; + logic [7:0] data_be_o; + logic [63:0] data_wdata_o; + logic [63:0] data_rdata_i; + logic lsu_trans_id_i; + exception lsu_exception_o; + // pass through diff --git a/id_stage.sv b/id_stage.sv index c2c90f21a..ac57b89d0 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -14,41 +14,41 @@ module id_stage #( parameter int NR_ENTRIES = 4, parameter int NR_WB_PORTS = 4 )( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - input logic test_en_i, // Test Enable + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low + input logic test_en_i, // Test Enable - input logic flush_i, + input logic flush_i, // from IF - input logic [31:0] instruction_i, - input logic instruction_valid_i, - input logic [63:0] pc_if_i, - input exception ex_i, - output logic ready_o, // id is ready - output fu_op operator_o, - output logic [63:0] operand_a_o, - output logic [63:0] operand_b_o, - output logic [4:0] trans_id_o, + input logic [31:0] instruction_i, + input logic instruction_valid_i, + input logic [63:0] pc_if_i, + input exception ex_i, + output logic ready_o, // id is ready + output fu_op operator_o, + output logic [63:0] operand_a_o, + output logic [63:0] operand_b_o, + output logic [TRANS_ID_BITS-1:0] trans_id_o, - input logic alu_ready_i, - output logic alu_valid_o, + input logic alu_ready_i, + output logic alu_valid_o, - input logic lsu_ready_i, - output logic lsu_valid_o, + input logic lsu_ready_i, + output logic lsu_valid_o, - input logic mult_ready_i, - output logic mult_valid_o, + input logic mult_ready_i, + output logic mult_valid_o, // write back port - input logic [NR_WB_PORTS-1:0][4:0] trans_id_i, - input logic [NR_WB_PORTS-1:0][63:0] wdata_i, - input logic [NR_WB_PORTS-1:0] wb_valid_i, + input logic [NR_WB_PORTS-1:0][TRANS_ID_BITS-1:0] trans_id_i, + input logic [NR_WB_PORTS-1:0][63:0] wdata_i, + input logic [NR_WB_PORTS-1:0] wb_valid_i, // commit port - input logic[4:0] waddr_a_i, - input logic[63:0] wdata_a_i, - input logic we_a_i, + input logic[4:0] waddr_a_i, + input logic[63:0] wdata_a_i, + input logic we_a_i, - output scoreboard_entry commit_instr_o, - input logic commit_ack_i + output scoreboard_entry commit_instr_o, + input logic commit_ack_i ); diff --git a/include/ariane_pkg.svh b/include/ariane_pkg.svh index 6eefb7941..dd23438b9 100644 --- a/include/ariane_pkg.svh +++ b/include/ariane_pkg.svh @@ -9,7 +9,13 @@ * in one package. */ package ariane_pkg; - + // --------------- + // Global Config + // --------------- + localparam NR_SB_ENTRIES = 4; // number of scoreboard entries + localparam TRANS_ID_BITS = $clog2(NR_SB_ENTRIES); // depending on the number of scoreboard entries we need that many bits + // to uniquely identify the entry in the scoreboard + localparam NR_WB_PORTS = 2; // --------------- // Fetch Stage // --------------- @@ -41,7 +47,7 @@ package ariane_pkg; } misspredict; typedef enum logic[3:0] { - NONE, ALU, MULT, LSU, CSR + NONE, LSU, ALU, MULT, CSR } fu_t; localparam EXC_OFF_RST = 8'h80; @@ -62,18 +68,18 @@ package ariane_pkg; // ID/EX/WB Stage // --------------- typedef struct packed { - logic [4:0] trans_id; // this can potentially be simplified, we could index the scoreboard entry with the transaction id - // in any case make the width more generic - fu_t fu; // functional unit to use - fu_op op; // operation to perform in each functional unit - logic [4:0] rs1; // register source address 1 - logic [4:0] rs2; // register source address 2 - logic [4:0] rd; // register destination address - logic [63:0] result; // for unfinished instructions this field also holds the immediate - logic valid; // is the result valid - logic use_imm; // should we use the immediate as operand b? - logic use_pc; // set if we need to use the PC as operand A, PC from exception - exception ex; // exception has occurred + logic [TRANS_ID_BITS-1:0] trans_id; // this can potentially be simplified, we could index the scoreboard entry + // with the transaction id in any case make the width more generic + fu_t fu; // functional unit to use + fu_op op; // operation to perform in each functional unit + logic [4:0] rs1; // register source address 1 + logic [4:0] rs2; // register source address 2 + logic [4:0] rd; // register destination address + logic [63:0] result; // for unfinished instructions this field also holds the immediate + logic valid; // is the result valid + logic use_imm; // should we use the immediate as operand b? + logic use_pc; // set if we need to use the PC as operand A, PC from exception + exception ex; // exception has occurred } scoreboard_entry; // -------------------- diff --git a/issue_read_operands.sv b/issue_read_operands.sv index 4e20acd25..290436bcd 100755 --- a/issue_read_operands.sv +++ b/issue_read_operands.sv @@ -30,10 +30,10 @@ module issue_read_operands ( // get clobber input input logic [31:0][$bits(fu_t)-1:0] rd_clobber_i, // To FU, just single issue for now - output fu_op operator_o, + output fu_op operator_o, output logic [63:0] operand_a_o, output logic [63:0] operand_b_o, - output logic [4:0] trans_id_o, + output logic [TRANS_ID_BITS-1:0] trans_id_o, // ALU 1 input logic alu_ready_i, // FU is ready output logic alu_valid_o, // Output is valid @@ -57,7 +57,7 @@ module issue_read_operands ( // output flipflop (ID <-> EX) logic [63:0] operand_a_n, operand_a_q, operand_b_n, operand_b_q; logic alu_valid_n, alu_valid_q; - logic [4:0] trans_id_n, trans_id_q; + logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q; fu_op operator_n, operator_q; // forwarding signals diff --git a/scoreboard.sv b/scoreboard.sv index 419452c5a..18b11b1c0 100644 --- a/scoreboard.sv +++ b/scoreboard.sv @@ -8,45 +8,45 @@ import ariane_pkg::*; module scoreboard #( - parameter int NR_ENTRIES = 8, + parameter int NR_ENTRIES = 8, parameter int NR_WB_PORTS = 1, - parameter type dtype = scoreboard_entry + parameter type dtype = scoreboard_entry ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - output logic full_o, // We can't take anymore data - input logic flush_i, + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low + output logic full_o, // We can't take anymore data + input logic flush_i, // list of clobbered registers to issue stage - output logic [31:0][$bits(fu_t)-1:0] rd_clobber_o, + output logic [31:0][$bits(fu_t)-1:0] rd_clobber_o, // regfile like interface to operand read stage - input logic [4:0] rs1_i, - output logic [63:0] rs1_o, - output logic rs1_valid_o, + input logic [4:0] rs1_i, + output logic [63:0] rs1_o, + output logic rs1_valid_o, - input logic [4:0] rs2_i, - output logic [63:0] rs2_o, - output logic rs2_valid_o, + input logic [4:0] rs2_i, + output logic [63:0] rs2_o, + output logic rs2_valid_o, // advertise instruction to commit stage, if commit_ack_i is asserted advance the commit pointer - output dtype commit_instr_o, - input logic commit_ack_i, + output dtype commit_instr_o, + input logic commit_ack_i, - // instruction to put on top of scoreboard e.g.: top pointer - // we can always put this instruction to the top unless we signal with asserted full_o - input dtype decoded_instr_i, - input logic decoded_instr_valid_i, + // instruction to put on top of scoreboard e.g. : top pointer + // we can always put this instruction to the to p unless we signal with asserted full_o + input dtype decoded_instr_i, + input logic decoded_instr_valid_i, // instruction to issue logic, if issue_instr_valid and issue_ready is asserted, advance the issue pointer - output dtype issue_instr_o, - output logic issue_instr_valid_o, - input logic issue_ack_i, + output dtype issue_instr_o, + output logic issue_instr_valid_o, + input logic issue_ack_i, // write-back port - input logic [NR_WB_PORTS-1:0][4:0] trans_id_i, // transaction ID at which to write the result back - input logic [NR_WB_PORTS-1:0][63:0] wdata_i, // write data in - input logic [NR_WB_PORTS-1:0] wb_valid_i // data in is valid + input logic [NR_WB_PORTS-1:0][TRANS_ID_BITS-1:0] trans_id_i, // transaction ID at which to write the result back + input logic [NR_WB_PORTS-1:0][63:0] wdata_i, // write data in + input logic [NR_WB_PORTS-1:0] wb_valid_i // data in is valid ); localparam BITS_ENTRIES = $clog2(NR_ENTRIES); @@ -135,13 +135,17 @@ always_comb begin : read_operands end // provide a direct combinational path from WB a.k.a forwarding - if (mem_q[trans_id_i].rd == rs1_i && wb_valid_i) begin - rs1_o = wdata_i; - rs1_valid_o = wb_valid_i; - end - if (mem_q[trans_id_i].rd == rs2_i && wb_valid_i) begin - rs2_o = wdata_i; - rs2_valid_o = wb_valid_i; + for (int j = 0; j < NR_WB_PORTS; j++) begin + if (mem_q[trans_id_i[j]].rd == rs1_i && wb_valid_i[j]) begin + rs1_o = wdata_i[j]; + rs1_valid_o = wb_valid_i[j]; + break; + end + if (mem_q[trans_id_i[j]].rd == rs2_i && wb_valid_i[j]) begin + rs2_o = wdata_i[j]; + rs2_valid_o = wb_valid_i[j]; + break; + end end // make sure we didn't read the zero register