diff --git a/alu_simplified.sv b/alu_simplified.sv index 396d0dbc..212cd1bd 100644 --- a/alu_simplified.sv +++ b/alu_simplified.sv @@ -27,9 +27,6 @@ import riscv_defines::*; module littleriscv_alu_simplified ( - input logic clk, - input logic rst_n, - input logic [ALU_OP_WIDTH-1:0] operator_i, input logic [31:0] operand_a_i, input logic [31:0] operand_b_i, @@ -42,10 +39,8 @@ module littleriscv_alu_simplified logic [31:0] operand_a_rev; - logic [31:0] operand_a_neg; - logic [31:0] operand_a_neg_rev; + logic [32:0] operand_b_neg; - assign operand_a_neg = ~operand_a_i; // bit reverse operand_a for left shifts and bit counting generate @@ -56,19 +51,6 @@ module littleriscv_alu_simplified end endgenerate - // bit reverse operand_a_neg for left shifts and bit counting - generate - genvar m; - for(m = 0; m < 32; m++) - begin - assign operand_a_neg_rev[m] = operand_a_neg[31-m]; - end - endgenerate - - logic [31:0] operand_b_neg; - - assign operand_b_neg = (~operand_b_i) + 32'h0001; - ///////////////////////////////////// // _ _ _ // @@ -80,7 +62,8 @@ module littleriscv_alu_simplified ///////////////////////////////////// logic adder_op_b_negate; - logic [31:0] adder_in_a, adder_in_b; + logic [32:0] adder_in_a, adder_in_b; + logic [33:0] adder_result_ext; logic [31:0] adder_result; always_comb @@ -106,13 +89,16 @@ module littleriscv_alu_simplified // prepare operand a - assign adder_in_a = operand_a_i; + assign adder_in_a = {operand_a_i,1'b1}; // prepare operand b - assign adder_in_b = adder_op_b_negate ? operand_b_neg : operand_b_i; + assign adder_in_b = {operand_b_i,1'b0}; + assign operand_b_neg = adder_in_b ^ {33{adder_op_b_negate}}; // actual adder - assign adder_result = adder_in_a + adder_in_b; + assign adder_result_ext = $signed(adder_in_a) + $signed(operand_b_neg); + + assign adder_result = adder_result_ext[32:1]; assign adder_result_o = adder_result; diff --git a/controller.sv b/controller.sv index f9c94a05..d5ae6136 100644 --- a/controller.sv +++ b/controller.sv @@ -46,8 +46,6 @@ module littleriscv_controller input logic illegal_insn_i, // decoder encountered an invalid instruction input logic eret_insn_i, // decoder encountered an eret instruction input logic pipe_flush_i, // decoder wants to do a pipe flush - input logic rega_used_i, // register A is used - input logic regb_used_i, // register B is used // from IF/ID pipeline input logic instr_valid_i, // instruction coming from IF/ID pipeline is valid @@ -87,22 +85,8 @@ module littleriscv_controller input logic dbg_stall_i, // Pipeline stall is requested input logic dbg_jump_req_i, // Change PC to value from debug unit - // Forwarding signals from regfile - - input logic regfile_we_ex_i, // FW: write enable from EX stage - input logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_wb_i, // FW: write address from WB stage - - input logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_fw_i, // FW: ALU/MUL write address from EX stage - input logic regfile_alu_we_fw_i, // FW: ALU/MUL write enable from EX stage - // forwarding signals output logic [1:0] operand_a_fw_mux_sel_o, // regfile ra data selector form ID stage - output logic [1:0] operand_b_fw_mux_sel_o, // regfile rb data selector form ID stage - - // forwarding detection signals - input logic reg_d_wb_is_reg_a_i, - input logic reg_d_wb_is_reg_b_i, - // stall signals output logic halt_if_o, @@ -275,11 +259,9 @@ module littleriscv_controller // handle conditional branches if ((jump_in_dec_i == BRANCH_COND) & branch_taken_ex_i & id_ready_i) begin - halt_if_o = 1'b1; - //halt_id_o = 1'b1; + halt_if_o = 1'b1; ctrl_fsm_ns = BRANCH_2ND_STAGE; end - else begin // handle unconditional jumps @@ -496,42 +478,10 @@ module littleriscv_controller // - always stall if a result is to be forwarded to the PC // we don't care about in which state the ctrl_fsm is as we deassert_we // anyway when we are not in DECODE -/* - if ((jump_in_dec_i == BRANCH_JALR) && (regfile_we_wb_o == 1'b1) && (reg_d_wb_is_reg_a_i == 1'b1)) - begin - jr_stall_o = 1'b1; - deassert_we_o = 1'b1; - end -*/ end // Forwarding control unit - always_comb - begin - // default assignements - operand_a_fw_mux_sel_o = SEL_REGFILE; - operand_b_fw_mux_sel_o = SEL_REGFILE; - - // Forwarding WB -> ID -/* - if (regfile_we_wb_o == 1'b1) - begin - if (reg_d_wb_is_reg_a_i == 1'b1) - operand_a_fw_mux_sel_o = SEL_FW_WB; - if (reg_d_wb_is_reg_b_i == 1'b1) - operand_b_fw_mux_sel_o = SEL_FW_WB; - end -*/ - // Forwarding EX -> ID - - // for misaligned memory accesses - if (data_misaligned_i) - begin - operand_a_fw_mux_sel_o = SEL_MISALIGNED; - operand_b_fw_mux_sel_o = SEL_REGFILE; - end - - end + assign operand_a_fw_mux_sel_o = data_misaligned_i ? SEL_MISALIGNED : SEL_REGFILE; // update registers always_ff @(posedge clk , negedge rst_n) diff --git a/ex_stage.sv b/ex_stage.sv index d2ae38ac..f31b952c 100644 --- a/ex_stage.sv +++ b/ex_stage.sv @@ -31,77 +31,31 @@ import riscv_defines::*; -module littleriscv_ex_stage -#( - parameter REG_ADDR_WIDTH = 5 -) +module littleriscv_ex_block ( - input logic clk, - input logic rst_n, - // ALU signals from ID stage input logic [ALU_OP_WIDTH-1:0] alu_operator_i, - input logic [31:0] alu_operand_a_i, - input logic [31:0] alu_operand_b_i, - input logic [31:0] alu_operand_c_i, + input logic [31:0] alu_operand_a_i, + input logic [31:0] alu_operand_b_i, - - output logic [31:0] alu_adder_result_ex_o, - - // input from ID stage - input logic branch_in_ex_i, - input logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_i, - input logic regfile_alu_we_i, - input logic jal_in_ex_i, - - // directly passed through to WB stage, not used in EX - input logic regfile_we_i, - - - // CSR access - input logic csr_access_i, - input logic [31:0] csr_rdata_i, - - // Output of EX stage pipeline - output logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_wb_o, - output logic regfile_we_wb_o, - - // Forwarding ports : to ID stage - output logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_fw_o, - output logic regfile_alu_we_fw_o, - output logic [31:0] regfile_alu_wdata_fw_o, // forward to RF and ID/EX pipe, ALU & MUL + output logic [31:0] alu_adder_result_ex_o, + output logic [31:0] regfile_wdata_ex_o, // To IF: Jump and branch target and decision - output logic [31:0] jump_target_o, - output logic branch_decision_o + output logic [31:0] jump_target_o, + output logic branch_decision_o ); - logic regfile_we_conflict; // Tests for a conflict when WB and EX want to write to a register at the same cycle. -// assign regfile_we_conflict = regfile_we_wb_o && regfile_alu_we_fw_o; - assign regfile_we_conflict = 1'b0; - logic [31:0] alu_result; - logic [31:0] alu_csr_result; logic alu_cmp_result; - logic alu_ready; - - // EX stage result mux (ALU, MAC unit, CSR) - assign alu_csr_result = csr_access_i ? csr_rdata_i : alu_result; - - assign regfile_alu_wdata_fw_o = jal_in_ex_i ? alu_operand_c_i : alu_csr_result; // Select return address - - - assign regfile_alu_we_fw_o = regfile_alu_we_i; - assign regfile_alu_waddr_fw_o = regfile_alu_waddr_i; - + assign regfile_wdata_ex_o = alu_result; // branch handling - assign branch_decision_o = alu_cmp_result; - assign jump_target_o = alu_adder_result_ex_o; + assign branch_decision_o = alu_cmp_result; + assign jump_target_o = alu_adder_result_ex_o; - //////////////////////////// // _ _ _ _ // // / \ | | | | | | // @@ -111,22 +65,17 @@ module littleriscv_ex_stage // // //////////////////////////// - - littleriscv_alu_simplified alu_i ( - .clk ( clk ), - .rst_n ( rst_n ), - - .operator_i ( alu_operator_i ), - .operand_a_i ( alu_operand_a_i ), - .operand_b_i ( alu_operand_b_i ), + .operator_i ( alu_operator_i ), + .operand_a_i ( alu_operand_a_i ), + .operand_b_i ( alu_operand_b_i ), .adder_result_o (alu_adder_result_ex_o ), - .result_o ( alu_result ), - .comparison_result_o ( alu_cmp_result ) + .result_o ( alu_result ), + .comparison_result_o ( alu_cmp_result ) ); -endmodule +endmodule \ No newline at end of file diff --git a/id_stage.sv b/id_stage.sv index de616003..aab170c5 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -65,7 +65,6 @@ module littleriscv_id_stage output logic pc_set_o, output logic [2:0] pc_mux_o, output logic [1:0] exc_pc_mux_o, - output logic [4:0] exc_vec_pc_mux_o, input logic illegal_c_insn_i, input logic is_compressed_i, @@ -76,42 +75,26 @@ module littleriscv_id_stage // Stalls output logic halt_if_o, // controller requests a halt of the IF stage + input logic if_ready_i, // IF stage is done output logic id_ready_o, // ID stage is ready for the next instruction + input logic lsu_ready_ex_i, input logic data_valid_lsu_i, input logic wb_ready_i, - input logic lsu_ready_ex_i, - input logic if_ready_i, // IF stage is done input logic if_valid_i, // IF stage is done output logic id_valid_o, // ID stage is done input logic wb_valid_i, // WB stage is done - // Pipeline ID/EX - output logic [31:0] pc_ex_o, - + // ALU + output logic [ALU_OP_WIDTH-1:0] alu_operator_ex_o, output logic [31:0] alu_operand_a_ex_o, output logic [31:0] alu_operand_b_ex_o, output logic [31:0] alu_operand_c_ex_o, // Still needed if 2r1w reg file used - output logic jal_in_ex_o, // Select operand C as return address to save in regfile - - - - output logic regfile_we_ex_o, - - output logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_ex_o, - output logic regfile_alu_we_ex_o, - - // ALU - output logic [ALU_OP_WIDTH-1:0] alu_operator_ex_o, - - - - // CSR ID/EX + // CSR ID output logic csr_access_ex_o, output logic [1:0] csr_op_ex_o, - // Interface to load store unit output logic data_req_ex_o, output logic data_we_ex_o, @@ -122,7 +105,6 @@ module littleriscv_id_stage input logic data_misaligned_i, input logic [31:0] misaligned_addr_i, - input logic first_cycle_misaligned_i, // Interrupt signals input logic irq_i, @@ -158,17 +140,10 @@ module littleriscv_id_stage input logic dbg_jump_req_i, - // Forward Signals - //input logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_wb_i, - //input logic regfile_we_wb_i, - input logic [31:0] regfile_wdata_wb_i, // From wb_stage: selects data from data memory, ex_stage result and sp rdata - - - input logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_fw_i, - input logic regfile_alu_we_fw_i, - input logic [31:0] regfile_alu_wdata_fw_i, - - // from ALU + // Write back signal + input logic [31:0] regfile_wdata_wb_i, + input logic [31:0] regfile_wdata_ex_i, + input logic [31:0] csr_rdata_i, // Performance Counters output logic perf_jump_o, // we are executing a jump instruction @@ -198,9 +173,10 @@ module littleriscv_id_stage logic load_stall; logic halt_id; - - logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_wb; + //FSM signals to write back multi cycles instructions logic regfile_we, regfile_we_q; + logic select_data_lsu; + // Immediate decoding and sign extension logic [31:0] imm_i_type; @@ -245,7 +221,6 @@ module littleriscv_id_stage // Register Write Control logic regfile_mem_we_id; - logic select_data_lsu; // Data Memory Control logic data_we_id; @@ -259,30 +234,18 @@ module littleriscv_id_stage logic csr_access; logic [1:0] csr_op; - // Forwarding logic [1:0] operand_a_fw_mux_sel; - logic [1:0] operand_b_fw_mux_sel; - + logic [31:0] operand_a_fw_id; logic [31:0] operand_b_fw_id; - + logic [31:0] operand_b; logic [31:0] alu_operand_a; logic [31:0] alu_operand_b; logic [31:0] alu_operand_c; // Still needed if 2r1w reg file used - // Immediates for ID - - - - - - // Forwarding detection signals - logic reg_d_wb_is_reg_a_id; - logic reg_d_wb_is_reg_b_id; - assign instr = instr_rdata_i; // immediate extraction and sign extension @@ -302,31 +265,17 @@ module littleriscv_id_stage assign imm_vs_type = { {26 {instr[24]}}, instr[24:20], instr[25] }; assign imm_vu_type = { 26'b0, instr[24:20], instr[25] }; - - //--------------------------------------------------------------------------- // source register selection //--------------------------------------------------------------------------- assign regfile_addr_ra_id = instr[`REG_S1]; assign regfile_addr_rb_id = instr[`REG_S2]; - - //--------------------------------------------------------------------------- // destination registers //--------------------------------------------------------------------------- - - assign regfile_alu_waddr_id = instr[`REG_D]; - // Forwarding control signals - //assign reg_d_wb_is_reg_a_id = (regfile_waddr_wb_i == regfile_addr_ra_id) && (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0); - //assign reg_d_wb_is_reg_b_id = (regfile_waddr_wb_i == regfile_addr_rb_id) && (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0); - assign reg_d_wb_is_reg_a_id = (rega_used_dec == 1'b1) && (regfile_addr_ra_id != '0); - assign reg_d_wb_is_reg_b_id = (regb_used_dec == 1'b1) && (regfile_addr_rb_id != '0); - - - // kill instruction in the IF/ID stage by setting the instr_valid_id control // signal to 0 for instructions that are done assign clear_instr_valid_o = id_ready_o | halt_id; @@ -347,7 +296,7 @@ module littleriscv_id_stage begin : alu_operand_a_mux case (alu_op_a_mux_sel) OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id; - OP_A_REGB_OR_FWD: alu_operand_a = operand_b_fw_id; + //OP_A_REGB_OR_FWD: alu_operand_a = regfile_data_rb_id; OP_A_CURRPC: alu_operand_a = pc_id_i; OP_A_IMM: alu_operand_a = imm_a; default: alu_operand_a = operand_a_fw_id; @@ -359,20 +308,20 @@ module littleriscv_id_stage unique case (imm_a_mux_sel) IMMA_Z: imm_a = imm_z_type; IMMA_ZERO: imm_a = '0; - default: imm_a = '0; + default: imm_a = '0; endcase end + // Operand a forwarding mux used with LSU instructions + always_comb + begin : operand_a_fw_mux + case (operand_a_fw_mux_sel) + SEL_MISALIGNED: operand_a_fw_id = misaligned_addr_i; + SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id; + default: operand_a_fw_id = regfile_data_ra_id; + endcase; // case (operand_a_fw_mux_sel) + end - // Operand a forwarding mux - always_comb - begin : operand_a_fw_mux - case (operand_a_fw_mux_sel) - SEL_MISALIGNED: operand_a_fw_id = misaligned_addr_i; - SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id; - default: operand_a_fw_id = regfile_data_ra_id; - endcase; // case (operand_a_fw_mux_sel) - end ////////////////////////////////////////////////////// // ___ _ ____ // @@ -384,8 +333,6 @@ module littleriscv_id_stage ////////////////////////////////////////////////////// // Immediate Mux for operand B - // TODO: check if sign-extension stuff works well here, maybe able to save - // some area here always_comb begin : immediate_b_mux unique case (imm_b_mux_sel) @@ -393,7 +340,6 @@ module littleriscv_id_stage IMMB_S: imm_b = imm_s_type; IMMB_U: imm_b = imm_u_type; IMMB_PCINCR: imm_b = (is_compressed_i && (~data_misaligned_i)) ? 32'h2 : 32'h4; - IMMB_S2: imm_b = imm_s2_type; IMMB_BI: imm_b = imm_bi_type; IMMB_S3: imm_b = imm_s3_type; @@ -407,38 +353,18 @@ module littleriscv_id_stage // ALU_Op_b Mux always_comb - begin : alu_operand_b_mux + begin : alu_operand_b_mux case (alu_op_b_mux_sel) - OP_B_REGA_OR_FWD: operand_b = operand_a_fw_id; - OP_B_REGB_OR_FWD: operand_b = operand_b_fw_id; + //OP_B_REGA_OR_FWD: operand_b = regfile_data_ra_id; + OP_B_REGB_OR_FWD: operand_b = regfile_data_rb_id; OP_B_IMM: operand_b = imm_b; - OP_B_BMASK: operand_b = $unsigned(operand_b_fw_id[4:0]); OP_B_ZERO: operand_b = '0; - default: operand_b = operand_b_fw_id; + default: operand_b = regfile_data_rb_id; endcase // case (alu_op_b_mux_sel) - end - - - // scalar replication for operand B and shuffle type - always_comb - begin end - assign alu_operand_b = operand_b; - -/* - // Operand b forwarding mux - always_comb - begin : operand_b_fw_mux - case (operand_b_fw_mux_sel) - SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i; - SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id; - default: operand_b_fw_id = regfile_data_rb_id; - endcase; // case (operand_b_fw_mux_sel) - end -*/ - -assign operand_b_fw_id = regfile_data_rb_id; + assign alu_operand_b = operand_b; + assign operand_b_fw_id = operand_b; ////////////////////////////////////////////////////// // ___ _ ____ // @@ -449,16 +375,18 @@ assign operand_b_fw_id = regfile_data_rb_id; // |_| // ////////////////////////////////////////////////////// - // ALU OP C Mux + // ALU OP C Mux, jump or store. TODO: Change it +/* always_comb begin : alu_operand_c_mux case (alu_op_c_mux_sel) - OP_C_REGB_OR_FWD: alu_operand_c = operand_b_fw_id; + OP_C_REGB_OR_FWD: alu_operand_c = regfile_data_rb_id; OP_C_RA: alu_operand_c = pc_if_i; // this is the return address - default: alu_operand_c = operand_b_fw_id; + default: alu_operand_c = regfile_data_rb_id; endcase // case (alu_op_c_mux_sel) end - +*/ + assign alu_operand_c = regfile_data_rb_id; ///////////////////////////////////////////////////////// // ____ _____ ____ ___ ____ _____ _____ ____ ____ // @@ -469,6 +397,34 @@ assign operand_b_fw_id = regfile_data_rb_id; // // ///////////////////////////////////////////////////////// + logic [31:0] regfile_wdata_mux; + logic regfile_we_mux; + logic [4:0] regfile_waddr_mux; + //TODO: add assertion + // Register File mux + always_comb + begin + if(dbg_reg_wreq_i) begin + regfile_wdata_mux = dbg_reg_wdata_i; + regfile_waddr_mux = dbg_reg_waddr_i; + regfile_we_mux = 1'b1; + end else begin + regfile_we_mux = regfile_we; + regfile_waddr_mux = regfile_alu_waddr_id; + if (select_data_lsu) + regfile_wdata_mux = regfile_wdata_wb_i; + else + if (csr_access) + regfile_wdata_mux = csr_rdata_i; + else + //TODO: modify this + if ((jump_in_id == BRANCH_JALR) || (jump_in_id == BRANCH_JAL)) + regfile_wdata_mux = pc_if_i; + else + regfile_wdata_mux = regfile_wdata_ex_i; + end + end + littleriscv_register_file registers_i ( .clk ( clk ), @@ -479,18 +435,13 @@ assign operand_b_fw_id = regfile_data_rb_id; // Read port a .raddr_a_i ( regfile_addr_ra_id ), .rdata_a_o ( regfile_data_ra_id ), - + // Read port b .raddr_b_i ( (dbg_reg_rreq_i == 1'b0) ? regfile_addr_rb_id : dbg_reg_raddr_i ), .rdata_b_o ( regfile_data_rb_id ), - - - // Write port a (multiplex between ALU and LSU). Conflict is resolved by stalling in EX. - //.waddr_a_i ( (dbg_reg_wreq_i == 1'b0) ? ( (regfile_we_wb_i == 1'b1) ? regfile_waddr_wb_i : regfile_alu_waddr_fw_i) : dbg_reg_waddr_i ), - //.wdata_a_i ( (dbg_reg_wreq_i == 1'b0) ? ( (regfile_we_wb_i == 1'b1) ? regfile_wdata_wb_i : regfile_alu_wdata_fw_i) : dbg_reg_wdata_i ), - .waddr_a_i ( (dbg_reg_wreq_i == 1'b0) ? regfile_alu_waddr_fw_i : dbg_reg_waddr_i ), -// .wdata_a_i ( (dbg_reg_wreq_i == 1'b0) ? regfile_alu_wdata_fw_i : dbg_reg_wdata_i ), - .wdata_a_i ( (dbg_reg_wreq_i == 1'b0) ? ( select_data_lsu ? regfile_wdata_wb_i : regfile_alu_wdata_fw_i ) : dbg_reg_wdata_i ), - .we_a_i ( (dbg_reg_wreq_i == 1'b0) ? regfile_we : 1'b1 ) + // write port + .waddr_a_i ( regfile_waddr_mux ), + .wdata_a_i ( regfile_wdata_mux ), + .we_a_i ( regfile_we_mux ) ); assign dbg_reg_rdata_o = regfile_data_rb_id; @@ -552,8 +503,6 @@ assign operand_b_fw_id = regfile_data_rb_id; .data_reg_offset_o ( data_reg_offset_id ), .data_load_event_o ( data_load_event_id ), - - // jump/branches .jump_in_dec_o ( jump_in_dec ), .jump_in_id_o ( jump_in_id ) @@ -582,8 +531,6 @@ assign operand_b_fw_id = regfile_data_rb_id; .illegal_insn_i ( illegal_insn_dec ), .eret_insn_i ( eret_insn_dec ), .pipe_flush_i ( pipe_flush_dec ), - .rega_used_i ( rega_used_dec ), - .regb_used_i ( regb_used_dec ), // from IF/ID pipeline .instr_valid_i ( instr_valid_i ), @@ -622,24 +569,8 @@ assign operand_b_fw_id = regfile_data_rb_id; .dbg_stall_i ( dbg_stall_i ), .dbg_jump_req_i ( dbg_jump_req_i ), - // Forwarding signals from regfile - .regfile_we_ex_i ( regfile_we_ex_o ), - //.regfile_waddr_wb_i ( regfile_waddr_wb_i ), // Write address for register file from ex-wb- pipeline registers - .regfile_waddr_wb_i ( ), // Write address for register file from ex-wb- pipeline registers - //.regfile_we_wb_i ( regfile_we_wb_i ), - - // regfile port 2 (or multiplexer signal in case of a 2r1w) - .regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw_i ), - .regfile_alu_we_fw_i ( regfile_alu_we_fw_i ), - - // Forwarding detection signals - .reg_d_wb_is_reg_a_i ( reg_d_wb_is_reg_a_id ), - .reg_d_wb_is_reg_b_i ( reg_d_wb_is_reg_b_id ), - - // Forwarding signals .operand_a_fw_mux_sel_o ( operand_a_fw_mux_sel ), - .operand_b_fw_mux_sel_o ( operand_b_fw_mux_sel ), // Stall signals .halt_if_o ( halt_if_o ), @@ -704,7 +635,6 @@ assign operand_b_fw_id = regfile_data_rb_id; - ///////////////////////////////////// // ___ ____ _______ __ // // |_ _| _ \ | ____\ \/ / // @@ -717,9 +647,6 @@ assign operand_b_fw_id = regfile_data_rb_id; always_comb begin - regfile_alu_waddr_ex_o = regfile_alu_waddr_id; - -// data_we_ex_o = (data_we_id & (~halt_id) & wb_ready_i); data_we_ex_o = data_we_id; data_type_ex_o = data_type_id; data_sign_ext_ex_o = data_sign_ext_id; @@ -731,19 +658,15 @@ assign operand_b_fw_id = regfile_data_rb_id; alu_operand_b_ex_o = alu_operand_b; alu_operand_c_ex_o = alu_operand_c; - regfile_we_ex_o = (regfile_mem_we_id & (~halt_id) & wb_ready_i); - regfile_alu_we_ex_o = (regfile_alu_we_id & (~halt_id) & wb_ready_i); - csr_access_ex_o = csr_access; csr_op_ex_o = id_ready_o ? csr_op : CSR_OP_NONE; + data_req_ex_o = data_req_id; data_reg_offset_ex_o = data_reg_offset_id; data_load_event_ex_o = ((data_req_id & (~halt_id) & wb_ready_i) ? data_load_event_id : 1'b0); - pc_ex_o = pc_id_i; branch_in_ex_o = (jump_in_dec == BRANCH_COND); - jal_in_ex_o = ((jump_in_id == BRANCH_JALR) || (jump_in_id == BRANCH_JAL)); end enum logic { IDLE, WAIT_LSU } id_wb_fsm_cs, id_wb_fsm_ns; @@ -779,6 +702,7 @@ assign operand_b_fw_id = regfile_data_rb_id; IDLE: begin + //if instr not valid, deassert and so it is 0 if(data_req_ex_o) begin //LSU operation regfile_we = 1'b0; @@ -805,7 +729,6 @@ assign operand_b_fw_id = regfile_data_rb_id; // stall control assign id_ready_o = (~jr_stall) & (~load_stall); - assign id_valid_o = (~halt_id) & id_ready_o; diff --git a/littleriscv_core.sv b/littleriscv_core.sv index 2cce2488..38219456 100644 --- a/littleriscv_core.sv +++ b/littleriscv_core.sv @@ -115,8 +115,6 @@ module littleriscv_core logic data_misaligned; logic [31:0] misaligned_addr; - logic first_cycle_misaligned; - // Jump and branch target and decision (EX->IF) logic [31:0] jump_target_ex; @@ -133,25 +131,9 @@ module littleriscv_core logic [31:0] alu_operand_a_ex; logic [31:0] alu_operand_b_ex; logic [31:0] alu_operand_c_ex; - logic jal_in_ex; - logic [31:0] alu_adder_result_ex; // Used to forward computed address to LSU - - - - // Register Write Control - logic regfile_we_ex; - logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_fw_wb_o; // From WB to ID - logic regfile_we_wb; - logic [31:0] regfile_wdata; - - logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_ex; - logic regfile_alu_we_ex; - - logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_fw; - logic regfile_alu_we_fw; - logic [31:0] regfile_alu_wdata_fw; + logic [31:0] regfile_wdata_ex; // CSR control logic csr_access_ex; @@ -173,6 +155,8 @@ module littleriscv_core logic [31:0] data_pc_ex; logic data_load_event_ex; logic data_misaligned_ex; + logic [31:0] regfile_wdata_lsu; + // stall control logic halt_if; @@ -389,34 +373,25 @@ module littleriscv_core .if_ready_i ( if_ready ), .id_ready_o ( id_ready ), + .lsu_ready_ex_i ( lsu_ready_ex ), .data_valid_lsu_i ( data_valid_lsu ), .wb_ready_i ( lsu_ready_wb ), - .lsu_ready_ex_i ( lsu_ready_ex ), .if_valid_i ( if_valid ), .id_valid_o ( id_valid ), .wb_valid_i ( wb_valid ), - // From the Pipeline ID/EX - .alu_operator_ex_o ( alu_operator_ex ), .alu_operand_a_ex_o ( alu_operand_a_ex ), .alu_operand_b_ex_o ( alu_operand_b_ex ), - .alu_operand_c_ex_o ( alu_operand_c_ex ), // Still needed if 2r1w reg file used - - .jal_in_ex_o ( jal_in_ex ), - - .regfile_we_ex_o ( regfile_we_ex ), - - .regfile_alu_we_ex_o ( regfile_alu_we_ex ), - .regfile_alu_waddr_ex_o ( regfile_alu_waddr_ex ), - + //used in LSU for store instructions + //TODO: change name + .alu_operand_c_ex_o ( alu_operand_c_ex ), // CSR ID/EX .csr_access_ex_o ( csr_access_ex ), .csr_op_ex_o ( csr_op_ex ), - // LSU .data_req_ex_o ( data_req_ex ), // to load store unit .data_we_ex_o ( data_we_ex ), // to load store unit @@ -427,7 +402,6 @@ module littleriscv_core .data_misaligned_i ( data_misaligned ), .misaligned_addr_i ( misaligned_addr ), - .first_cycle_misaligned_i ( first_cycle_misaligned), // Interrupt Signals .irq_i ( irq_i ), // incoming interrupts @@ -461,15 +435,10 @@ module littleriscv_core .dbg_jump_req_i ( dbg_jump_req ), - // Forward Signals - //.regfile_waddr_wb_i ( ), // Write address ex-wb pipeline - //.regfile_we_wb_i ( ), // write enable for the register file - .regfile_wdata_wb_i ( regfile_wdata ), // write data to commit in the register file - - .regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw ), - .regfile_alu_we_fw_i ( regfile_alu_we_fw ), - .regfile_alu_wdata_fw_i ( regfile_alu_wdata_fw ), - + // write data to commit in the register file + .regfile_wdata_wb_i ( regfile_wdata_lsu ), + .regfile_wdata_ex_i ( regfile_wdata_ex ), + .csr_rdata_i ( csr_rdata ), // Performance Counters .perf_jump_o ( perf_jump ), @@ -478,61 +447,22 @@ module littleriscv_core ); - ///////////////////////////////////////////////////// - // _______ __ ____ _____ _ ____ _____ // - // | ____\ \/ / / ___|_ _|/ \ / ___| ____| // - // | _| \ / \___ \ | | / _ \| | _| _| // - // | |___ / \ ___) || |/ ___ \ |_| | |___ // - // |_____/_/\_\ |____/ |_/_/ \_\____|_____| // - // // - ///////////////////////////////////////////////////// - littleriscv_ex_stage ex_stage_i + littleriscv_ex_block ex_block_i ( - // Global signals: Clock and active low asynchronous reset - .clk ( clk ), - .rst_n ( rst_ni ), - // Alu signals from ID stage + //TODO: hot encoding .alu_operator_i ( alu_operator_ex ), // from ID/EX pipe registers .alu_operand_a_i ( alu_operand_a_ex ), // from ID/EX pipe registers .alu_operand_b_i ( alu_operand_b_ex ), // from ID/EX pipe registers - .alu_operand_c_i ( alu_operand_c_ex ), // from ID/EX pipe registers - - .alu_adder_result_ex_o ( alu_adder_result_ex ), // from ALU to LSU - - // interface with CSRs - .csr_access_i ( csr_access_ex ), - .csr_rdata_i ( csr_rdata ), - - // From ID Stage: Regfile control signals - .branch_in_ex_i ( branch_in_ex ), - .regfile_alu_waddr_i ( regfile_alu_waddr_ex ), - .regfile_alu_we_i ( regfile_alu_we_ex ), - .jal_in_ex_i ( jal_in_ex ), - - .regfile_we_i ( regfile_we_ex ), - - // Output of ex stage pipeline - .regfile_waddr_wb_o ( ), - .regfile_we_wb_o ( ), + .regfile_wdata_ex_o ( regfile_wdata_ex ), // To IF: Jump and branch target and decision .jump_target_o ( jump_target_ex ), - .branch_decision_o ( branch_decision ), - - // To ID stage: Forwarding signals - .regfile_alu_waddr_fw_o ( regfile_alu_waddr_fw ), - .regfile_alu_we_fw_o ( regfile_alu_we_fw ), - .regfile_alu_wdata_fw_o ( regfile_alu_wdata_fw ) - - // stall control - //.lsu_ready_ex_i ( lsu_ready_ex ), - //.wb_ready_i ( lsu_ready_wb ) + .branch_decision_o ( branch_decision ) ); - //////////////////////////////////////////////////////////////////////////////////////// // _ ___ _ ____ ____ _____ ___ ____ _____ _ _ _ _ ___ _____ // // | | / _ \ / \ | _ \ / ___|_ _/ _ \| _ \| ____| | | | | \ | |_ _|_ _| // @@ -566,13 +496,12 @@ module littleriscv_core .data_reg_offset_ex_i ( data_reg_offset_ex ), .data_sign_ext_ex_i ( data_sign_ext_ex ), // sign extension - .data_rdata_ex_o ( regfile_wdata ), + .data_rdata_ex_o ( regfile_wdata_lsu ), .data_req_ex_i ( data_req_ex ), .adder_result_ex_i ( alu_adder_result_ex), .data_misaligned_o ( data_misaligned ), - .first_cycle_misaligned_o( first_cycle_misaligned), .misaligned_addr_o ( misaligned_addr ), // exception signals @@ -755,22 +684,23 @@ module littleriscv_core .rs2_value_vec ( id_stage_i.alu_operand_b ), .ex_valid ( ), - .ex_reg_addr ( regfile_alu_waddr_fw ), - .ex_reg_we ( id_stage_i.registers_i.we_a_i ), - .ex_reg_wdata ( regfile_alu_wdata_fw ), + .ex_reg_addr ( id_stage_i.regfile_waddr_mux ), + .ex_reg_we ( id_stage_i.regfile_we_mux ), + .ex_reg_wdata ( id_stage_i.regfile_wdata_mux ), .ex_data_addr ( data_addr_o ), .ex_data_req ( data_req_o ), .ex_data_gnt ( data_gnt_i ), .ex_data_we ( data_we_o ), + // use id_stage_i.regfile_wdata_mux .ex_data_wdata ( data_wdata_o ), - .wb_bypass ( ex_stage_i.branch_in_ex_i ), + .wb_bypass ( branch_in_ex_o ), .wb_valid ( data_valid_lsu ), .wb_reg_addr ( ), .wb_reg_we ( ), - .wb_reg_wdata ( regfile_wdata ), + .wb_reg_wdata ( regfile_wdata_lsu ), .imm_u_type ( id_stage_i.imm_u_type ), .imm_uj_type ( id_stage_i.imm_uj_type ), @@ -827,7 +757,7 @@ module littleriscv_core .ex_data_we ( data_we_o ), .ex_data_wdata ( data_wdata_o ), - .wb_bypass ( ex_stage_i.branch_in_ex_i ), + .wb_bypass ( ex_block_i.branch_in_ex_i ), .lsu_misaligned ( data_misaligned ), .wb_valid ( wb_valid ), diff --git a/load_store_unit.sv b/load_store_unit.sv index 19135e5b..f5b76f91 100644 --- a/load_store_unit.sv +++ b/load_store_unit.sv @@ -56,7 +56,6 @@ module littleriscv_load_store_unit input logic [31:0] adder_result_ex_i, output logic data_misaligned_o, // misaligned access was detected -> to controller - output logic first_cycle_misaligned_o, output logic [31:0] misaligned_addr_o, // exception signals @@ -340,10 +339,6 @@ module littleriscv_load_store_unit assign misaligned_st = data_misaligned_q; -// assign first_cycle_misaligned_o = data_misaligned; // Directly forward signal to - - - assign load_err_o = 1'b0; assign store_err_o = 1'b0; diff --git a/riscv_tracer.sv b/riscv_tracer.sv index bfa49a8a..bc5845e9 100644 --- a/riscv_tracer.sv +++ b/riscv_tracer.sv @@ -708,7 +708,6 @@ module littleriscv_tracer // replace register written back foreach(trace.regs_write[i]) begin - //$display("A: %x (%x) V: %x --%x\n",trace.regs_write[i].addr, ex_reg_addr, ex_reg_wdata,ex_reg_we); if ((trace.regs_write[i].addr == ex_reg_addr) && ex_reg_we) trace.regs_write[i].value = ex_reg_wdata; end