mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 21:07:34 -04:00
cleaning and small fixes
This commit is contained in:
parent
f80a14b7c2
commit
c24081a1b8
7 changed files with 122 additions and 390 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
83
ex_stage.sv
83
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
|
221
id_stage.sv
221
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;
|
||||
|
||||
|
||||
|
|
|
@ -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 ),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue