diff options
author | Joshua Yun <joshua@joshuayun.com> | 2025-05-22 22:46:34 -0500 |
---|---|---|
committer | Joshua Yun <joshua@joshuayun.com> | 2025-05-22 22:46:34 -0500 |
commit | 88db611b50f16146bc6ca39f543348d0d9f5eadb (patch) | |
tree | 6374c9aec65ffd7a36581b9d9a319e197ed2cde4 | |
parent | e580017e209a0888c3f5a2063d265de50c66c56b (diff) | |
download | riscv-processor-88db611b50f16146bc6ca39f543348d0d9f5eadb.tar.gz |
finished exe stage
-rwxr-xr-x[-rw-r--r--] | .gitignore | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | core/pkg/riscv_types.sv | 32 | ||||
-rw-r--r-- | core/rtl/exe.sv | 191 | ||||
-rw-r--r-- | core/rtl/idu.sv | 199 | ||||
-rwxr-xr-x[-rw-r--r--] | core/tb/.gitignore | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | core/tb/core_tb.sv | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | core/tb/core_tb_imem.sv | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | core/testcode/riscv_arithmetic_basic_test_0.S | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | docker_tools/Dockerfile | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | primitives/primitives.core | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | primitives/rtl/AFF.sv | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | primitives/rtl/AFFR.sv | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | primitives/rtl/DMUX.sv | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | primitives/rtl/FLIP.sv | 0 |
14 files changed, 267 insertions, 155 deletions
diff --git a/.gitignore b/.gitignore index a007fea..a007fea 100644..100755 --- a/.gitignore +++ b/.gitignore diff --git a/core/pkg/riscv_types.sv b/core/pkg/riscv_types.sv index 59c1f74..d95ebc5 100644..100755 --- a/core/pkg/riscv_types.sv +++ b/core/pkg/riscv_types.sv @@ -19,12 +19,6 @@ package riscv_types; INSTR_TYPE_CSR = 7'b1110011 // I control and status register } opcode_t; - typedef enum logic [1:0] { - MEM_OP_LOAD, - MEM_OP_STORE, - MEM_OP_NONE - } mem_op_t; - typedef enum logic [2:0] { BEQ = 0, BNE = 1, @@ -34,7 +28,6 @@ package riscv_types; BGEU = 5 } br_op_t; - //------------ // ALU Control //------------ @@ -58,4 +51,29 @@ package riscv_types; alu_sel_op_2_t rs2Sel; } alu_op_t; + //------------- + // Memory Types + //------------- + typedef enum logic [1:0] { + MEM_OP_LOAD, + MEM_OP_STORE, + MEM_OP_NONE + } mem_op_t; + + typedef enum logic [1:0] { + MEM_SIZE_1B, + MEM_SIZE_2B, + MEM_SIZE_4B + } mem_op_size_t; + + //----------------- + // Write Back Types + //----------------- + typedef enum logic [1:0] { + PC, + MEM, + ALU, + NONE + } rd_data_sel_t; + endpackage diff --git a/core/rtl/exe.sv b/core/rtl/exe.sv index 4615638..c39807a 100644 --- a/core/rtl/exe.sv +++ b/core/rtl/exe.sv @@ -1,39 +1,61 @@ module exe ( - input logic clk, - input logic rst, - - //----------------- - // Decode Interface - //----------------- - input logic idu_exe_rs1Vld_EXE, - input logic [REG_IDX-1:0] idu_exe_rs1Idx_EXE, - - input logic idu_exe_rs2Vld_EXE, - input logic [REG_IDX-1:0] idu_exe_rs2Idx_EXE, - - input alu_op_t idu_exe_aluOp_EXE, - - //----------------- - // Memory Interface - //----------------- - output logic [WORD_WID-1:0] exe_mem_aluOpOut_EXE, - - //----------------------- - // Fetch Branch Interface - //----------------------- - output logic exe_ifu_brRes_EXE, - output logic exe_ifu_brTaken_EXE, - output logic [WORD_WID-1:0] exe_ifu_brPC_EXE, - - //-------------------- - // Writeback Interface - //-------------------- - input logic wb_exe_rdVld_WB, - input logic [ REG_IDX-1:0] wb_exe_rdIdx_WB, - input logic [WORD_WID-1:0] wb_exe_rdData_WB + input logic clk, + input logic rst, + + //----------------- + // Decode Interface + //----------------- + input logic idu_exe_instrVld_ID, + + // Register Access + input logic idu_exe_rs1Vld_ID, + input logic [REG_IDX-1:0] idu_exe_rs1Idx_ID, + input logic idu_exe_rs2Vld_ID, + input logic [REG_IDX-1:0] idu_exe_rs2Idx_ID, + + // Branch Type + input logic idu_exe_instrJmp_ID, + input logic idu_exe_instrBr_ID, + + // ALU information + input alu_op_t idu_exe_aluOp_ID, + + // Passthrough Information + input mem_op_t idu_exe_instrMemOp_ID, + input mem_size_t idu_exe_instrMemSize_ID, + input rd_data_sel_t idu_exe_instrRdDataSel_ID, + + //----------------- + // Memory Interface + //----------------- + // ALU Result information + output logic [WORD_WID-1:0] exe_mem_aluOpOut_EXE, + // Stall + input logic mem_exe_stallVld_EXE, + // Memory Information + output mem_op_t exe_mem_instrMemOp_EXE, + output mem_size_t exe_mem_instrMemSize_EXE, + // Passthrough information + output rd_data_sel_t exe_mem_instrRdDataSel_EXE, + + //----------------------- + // Fetch Branch Interface + //----------------------- + output logic exe_ifu_brRes_EXE, + output logic exe_ifu_brTaken_EXE, + output logic [WORD_WID-1:0] exe_ifu_brPC_EXE, + + //-------------------- + // Writeback Interface + //-------------------- + input logic wb_exe_rdVld_WB, + input logic [REG_IDX-1:0] wb_exe_rdIdx_WB, + input logic [WORD_WID-1:0] wb_exe_rdData_WB ); + logic instrVld_EXE; + // Alu logic [WORD_WID-1:0] aluSumDiff_EXE; logic [WORD_WID-1:0] aluSumDiffIn1_EXE; @@ -51,40 +73,56 @@ module exe ( logic aluCmpLowUsign_EXE; // Branch Resolution - logic [ 5:0] brResChoice_EXE; + logic [5:0] brResChoice_EXE; + + // Reg File + logic [NUM_REG-1:1] [WORD_WID-1:0] regData_XXX; + + // Stall Signal + assign stallVld_ID = exe_mem_instrVld_EXE & ~mem_exe_stallVld_EXE; //-------------------- // Decode Output Flops //-------------------- - assign stallVld_ID = ~exe_idu_exeRdy_EXE; // Flop Decode information - AFF #( .DTYPE(alu_op_t) ) AFF_EXE_aluOp ( .q(idu_exe_aluOp_EXE), .d(idu_exe_aluOp_ID), .en(stallVld_ID), .clk(clk) ); - AFF #( .WIDTH(WORD_WID) ) AFF_EXE_pc ( .q(idu_exe_pc_EXE), .d(idu_exe_pc_ID), .en(stallVld_ID), .clk(clk) ); - AFF #( .WIDTH(1) ) AFF_EXE_instrJmp ( .q(idu_exe_instrJmp_EXE), .d(idu_exe_instrJmp_ID), .en(stallVld_ID), .clk(clk) ); - AFF #( .WIDTH(1) ) AFF_EXE_brRes ( .q(idu_exe_brRes_EXE), .d(brResNxt_EXEM1), .en(stallVld_ID), .clk(clk) ); + AFFR #(.WIDTH(1)) AFFR_EXE_instrVld (.q(exe_mem_instrVld_EXE), .d(idu_exe_instrVld_ID), .en(stallVld_ID), .clk(clk), rst(rst)); + AFF #(.DTYPE(alu_op_t)) AFF_EXE_aluOp (.q(idu_exe_aluOp_EXE), .d(idu_exe_aluOp_ID), .en(stallVld_ID), .clk(clk)); + AFF #(.WIDTH(WORD_WID)) AFF_EXE_pc (.q(idu_exe_pc_EXE), .d(idu_exe_pc_ID), .en(stallVld_ID), .clk(clk)); + AFF #(.WIDTH(1)) AFF_EXE_instrJmp (.q(idu_exe_instrJmp_EXE), .d(idu_exe_instrJmp_ID), .en(stallVld_ID), .clk(clk)); + AFF #(.WIDTH(1)) AFF_EXE_brRes (.q(idu_exe_brRes_EXE), .d(brResNxt_EXEM1), .en(stallVld_ID), .clk(clk)); //-------------- // Register File //-------------- - // FIXME: Add support for the zero register - always_ff @(posedge clk) begin + assign rs1WrFwd_ID = wb_exe_rdWrVld_WB & (idu_exe_rs1Idx_ID == wb_exe_rdIdx_WB); + assign rs2WrFwd_ID = wb_exe_rdWrVld_WB & (idu_exe_rs2Idx_ID == wb_exe_rdIdx_WB); + always_ff @(posedge clk) begin // RS1 Read Port with Forwarding if (instrRs1Vld_ID) begin - idu_exe_rs1Data_EXE <= (wb_exe_rdVld_WB & (idu_exe_rs1Idx_ID == wb_exe_rdIdx_WB)) ? wb_exe_rdData_WB : regData_XXX[idu_exe_rs1Idx_ID]; + if (idx_exe_rs1Idx == REG_IDX'0) // X0 Register + idu_exe_rs1Data_EXE <= WORD_SIZE'0; + else if (rs1WrFwd_ID) begin // Write Foward + idu_exe_rs1Data_EXE <= wb_exe_rdData_WB; + else // Normal Read + idu_exe_rs1Data_EXE <= regData_XXX[idu_exe_rs1Idx_ID]; end // RS2 Read Port with Forwarding - if (instrRdVld_ID) begin - idu_exe_rs2Data_EXE <= (wb_exe_rdVld_WB & (idu_exe_rs1Idx_ID == wb_exe_rdIdx_WB)) ? wb_exe_rdData_WB : regData_XXX[idu_exe_rs2Idx_ID]; + if (instrRs2Vld_ID) begin + if (idx_exe_rs2Idx == REG_IDX'0) // X0 Register + idu_exe_rs2Data_EXE <= WORD_WID'0; + else if (rs2WrFwd_ID) begin // Write Foward + idu_exe_rs2Data_EXE <= wb_exe_rdData_WB; + else // Normal Read + idu_exe_rs2Data_EXE <= regData_XXX[idu_exe_rs1Idx_ID]; end // RD Write Port - if (wb_exe_rdData_WB) begin + if (wb_exe_rdWrVld_WB & (~|wb_exe_rdIdx_WB)) begin regData_XXX[wb_exe_rdIdx_WB] <= wb_exe_rdData_WB; end - end //---- @@ -92,29 +130,24 @@ module exe ( //---- // Operand Selection - assign aluIn1_EXE = (aluOp_EXE.rs1Sel == PC) ? pc_EXE : // PC for AUIPC, JAL - (aluOp_EXE.rs1Sel == ZERO) ? WORD_WID'(0) : // 0 for LUI - rs1Data_EXE; // RS1 for other operations + assign aluIn1_EXE = (aluOp_EXE.rs1Sel == PC) ? pc_EXE : // PC for AUIPC, JAL + (aluOp_EXE.rs1Sel == ZERO) ? WORD_WID'(0) : // 0 for LUI + rs1Data_EXE; // RS1 for other operations - assign aluIn2_EXE = (aluOp_EXE.rs2Sel == RS2) ? rs2Data_EXE : // RS2 for R type operations - aluOp_EXE.immediate; // Immediate for all other operations + assign aluIn2_EXE = (aluOp_EXE.rs2Sel == RS2) ? rs2Data_EXE : // RS2 for R type operations + aluOp_EXE.immediate; // Immediate for all other operations // Two's complement negation of aluIn2 if func7 is set (subtract) assign aluSumDiffIn1_EXE = aluIn1_EXE; assign aluSumDiffIn2_EXE = ({WORD_WID{aluOp_EXE.func7}} ^ aluIn2_EXE) + aluOp_EXE.func7; - assign aluSumDiff_EXE = aluSumDiffIn1_EXE + aluSumDiffIn2_EXE; + assign aluSumDiff_EXE = aluSumDiffIn1_EXE + aluSumDiffIn2_EXE; - // Shifter, TODO: Explicit signed barrel shifter + // Shifter, TODO: Explicit signed barrel shifter with sign bit assign aluRightShftUsign_EXE = aluIn1_EXE >> aluIn2_EXE[4:0]; - assign aluRightShftSext_EXE = ~({WORD_WID{1'b1}} >> aluIn2_EXE[4:0]); + assign aluRightShftSext_EXE = ~({WORD_WID{1'b1}} >> aluIn2_EXE[4:0]); assign aluRightShft_EXE = aluRightShftUsgn_EXE | (aluRightShftSext_EXE & {WORD_WID{aluOp_EXE.func7}}); - FLIP #( - .WIDTH(WORD_WID) - ) EXE_aluLeftShft ( - .in (aluRightShftUsign_EXE), - .out(aluLeftShft_EXE) - ); + FLIP #( .WIDTH(WORD_WID) ) EXE_aluLeftShft ( .in (aluRightShftUsign_EXE), .out(aluLeftShft_EXE) ); // Set Less Than assign aluCmpMsbDiff_EXE = aluIn2_EXE ^ aluIn1_EXE; @@ -152,22 +185,24 @@ module exe ( //------------------ // Branch Resolution //------------------ - assign exe_ifu_brPC_EXE = aluOpOut_EXE; - assign exe_ifu_brRes_EXE = brRes_EXE; // FIXME: Only send this once after a branch is processed until stall is lifted + assign exe_ifu_brPC_EXE = aluOpOut_EXE; + assign exe_ifu_brRes_EXE = brRes_EXE; + assign exe_ifu_brTaken_EXE = (brTaken_EXE & idu_exe_instrBr_ID) | idu_exe_instrJmp_ID; + assign brResChoice_EXE[0] = ~|aluXor_EXE; - assign brResChoice_EXE[1] = |aluXor_EXE; - assign brResChoice_EXE[2] = aluCmpSign_EXE; - assign brResChoice_EXE[3] = ~aluCmpSign_EXE; - assign brResChoice_EXE[4] = aluCmpUSign_EXE; - assign brResChoice_EXE[5] = ~aluCmpUSign_EXE; + assign brResChoice_EXE[1] = |aluXor_EXE; + assign brResChoice_EXE[2] = aluCmpSign_EXE; + assign brResChoice_EXE[3] = ~aluCmpSign_EXE; + assign brResChoice_EXE[4] = aluCmpUSign_EXE; + assign brResChoice_EXE[5] = ~aluCmpUSign_EXE; EMUX #( .WIDTH (1), .INPUTS(6) ) EMUX_exe_aluOpSel ( .in (brResChoice_EXE), - .out(exe_ifu_brTaken_EXE), + .out(brTaken_EXE), .sel(idu_exe_brOp_ID) ); @@ -175,5 +210,27 @@ module exe ( // Pipeline passthrough //--------------------- + // Memory + AFF #(.DTYPE(mem_op_t)) AFF_EXE_instRdDataSel ( + .q(exe_mem_instrMemOp_EXE), + .d(idu_exe_instrMemOp_ID), + .en(stallVld_ID), + .clk(clk) + ); + + AFF #(.DTYPE(mem_op_size_t)) AFF_EXE_instMemSize ( + .q(exe_mem_instrMemSize_EXE), + .d(idu_exe_instrMemSize_ID), + .en(stallVld_ID), + .clk(clk) + ); + + // Write Back + AFF #(.DTYPE(rd_data_sel_t)) AFF_EXE_instRdDataSel ( + .q(exe_mem_instrRdDataSel_EXE), + .d(idu_exe_instrRdDataSel_ID), + .en(stallVld_ID), + .clk(clk) + ); endmodule diff --git a/core/rtl/idu.sv b/core/rtl/idu.sv index 0bfd073..8736613 100644 --- a/core/rtl/idu.sv +++ b/core/rtl/idu.sv @@ -7,58 +7,76 @@ import riscv_types::*; input logic rst_l, // I-MEM Interface - input logic [INSTR_SIZE-1:0] imem_id_instr_ID, + input logic imem_idu_vld_ID, + input logic [INSTR_SIZE-1:0] imem_idu_data_ID, + //---------------- // Fetch Interface - input logic [PC_SIZE-1:0] imem_id_pc_ID, + //---------------- + input logic [PC_SIZE-1:0] ifu_idu_pc_ID, + input logic ifu_idu_instrVld_ID //------------------ // Execute Interface //------------------ - input logic exe_idu_exeRdy_EXE, - - // Alu information - output alu_op_t idu_exe_aluOp_ID, + output logic idu_exe_instrVld_EXE, // Register Idx - output logic idu_exe_rs1Vld_EXE, - output logic [REG_IDX-1:0] idu_exe_rs1Idx_EXE, + output logic idu_exe_rs1Vld_EXE, + output logic [REG_IDX-1:0] idu_exe_rs1Idx_EXE, + output logic idu_exe_rs2Vld_EXE, + output logic [REG_IDX-1:0] idu_exe_rs2Idx_EXE, + + // Branch Type + output logic idu_exe_instrJmp_ID, + output logic idu_exe_instrBr_ID, + + // Alu information + output alu_op_t idu_exe_aluOp_ID, - output logic idu_exe_rs2Vld_EXE, - output logic [REG_IDX-1:0] idu_exe_rs2Idx_EXE + // Passthrough information + output mem_op_t idu_exe_instrMemOp_ID, + output mem_size_t idu_exe_instrMemSize_ID, + output rd_data_sel_t idu_exe_instrRdDataSel_ID ); // OpCode opcode_t instrOpCode_ID; +// Instruction Op +logic instrAuipc_ID; +logic instrJal_ID; +logic instrJal_ID; +logic instrLui_ID; +logic instrReg_ID; +logic instrImm_ID; +logic instrLd_ID; +logic instrSt_ID; +logic instrBr_ID; + // Instruction Type -logic instrTypeR_ID; -logic instrTypeI_ID; -logic instrTypeS_ID; -logic instrTypeB_ID; -logic instrTypeU_ID; -logic instrTypeJ_ID; - - // Immediate +logic instrTypeR_ID; +logic instrTypeI_ID; +logic instrTypeS_ID; +logic instrTypeB_ID; +logic instrTypeU_ID; +logic instrTypeJ_ID; + +// Immediate logic [WORD_WID-1:0] instrImm_ID; -logic instrImmSign_ID; +logic instrImmSign_ID; // Register Indices -logic [REG_IDX-1:0] instrRs1Idx_ID; -logic instrRs1Vld_ID; -logic [REG_IDX-1:0] instrRs2Idx_ID; -logic instrRs2Vld_ID; -logic [REG_IDX-1:0] instrRdIdx_ID; -logic instrRdVld_ID; +logic [REG_IDX-1:0] instrRs1Idx_ID; +logic instrRs1Vld_ID; +logic [REG_IDX-1:0] instrRs2Idx_ID; +logic instrRs2Vld_ID; +logic [REG_IDX-1:0] instrRdIdx_ID; +logic instrRdVld_ID; // Funct3 and Funct7 -logic [2:0] instrFunct3_ID; -logic instrFunct7_ID; - -// Control Bits - -// Memory Op -mem_op_t instrMemOp_ID; +logic [2:0] instrFunct3_ID; +logic instrFunct7_ID; // Branch OP brjmp_op_t instrBrJmpOp_ID; @@ -67,94 +85,113 @@ brjmp_op_t instrBrJmpOp_ID; aluSelOp1_t instrAluIn1_ID; aluSelOp2_t instrAluIn2_ID; -// Reg File -logic [NUM_REG-1:0] [WORD_WID-1:0] regData_XXX; +//------------------- +// Instruction Decode +//------------------- -//------------------------ -// Instruction Type Decode -//------------------------ +assign instr_ID = imem_idu_data_ID; + +// Instruction Type (OpCode) Decode +assign instrOpCode_ID = opcode_t'(instr_ID[6:0]); + +assign instrAuipc_ID = (instrOpCode_ID == INSTR_TYPE_AUIPC); +assign instrJal_ID = (instrOpCode_ID == INSTR_TYPE_JAL); +assign instrJal_ID = (instrOpCode_ID == INSTR_TYPE_JALR); +assign instrLui_ID = (instrOpCode_ID == INSTR_TYPE_LUI); +assign instrReg_ID = (instrOpCode_ID == INSTR_TYPE_REG); +assign instrImm_ID = (instrOpCode_ID == INSTR_TYPE_IMM); +assign instrLd_ID = (instrOpCode_ID == INSTR_TYPE_LD); +assign instrSt_ID = (instrOpCode_ID == INSTR_TYPE_ST); +assign instrBr_ID = (instrOpCode_ID == INSTR_TYPE_BR); // FIXME: Add support for FENCE + ECALL + EBREAK + CSRs -assign instrTypeI_ID = (instrOpCode_ID == INSTR_TYPE_IMM) - | (instrOpCode_ID == INSTR_TYPE_JALR) - | (instrOpCode_ID == INSTR_TYPE_LD); -assign instrTypeU_ID = (instrOpCode_ID == INSTR_TYPE_LUI) - | (instrOpCode_ID == INSTR_TYPE_AUIPC); -assign instrTypeR_ID = (instrOpCode_ID == INSTR_TYPE_REG); -assign instrTypeS_ID = (instrOpCode_ID == INSTR_TYPE_ST); -assign instrTypeB_ID = (instrOpCode_ID == INSTR_TYPE_BR); -assign instrTypeJ_ID = (instrOpCode_ID == INSTR_TYPE_JAL); +assign instrTypeI_ID = instrImm_ID + | instrJal_IDR + | instrLd_ID; +assign instrTypeU_ID = instrLui_ID + | instrLui_PC; +assign instrTypeR_ID = instrReg_ID; +assign instrTypeS_ID = instrSt_ID; +assign instrTypeB_ID = instrBr_ID; +assign instrTypeJ_ID = instrJal_ID; // Register Index Decode -assign instrRs1Idx_ID = imem_id_instr_ID[19:15]; +assign instrRs1Idx_ID = instr_ID[19:15]; assign instrRs1Vld_ID = instrTypeR_ID | instrTypeI_ID | instrTypeS_ID | instrTypeB_ID; -assign instrRs2Idx_ID = imem_id_instr_ID[24:20]; +assign instrRs2Idx_ID = instr_ID[24:20]; assign instrRs2Vld_ID = instrTypeR_ID | instrTypeS_ID | instrTypeB_ID; -assign instrRdIdx_ID = imem_id_instr_ID[11:7]; +assign instrRdIdx_ID = instr_ID[11:7]; assign instrRdVld_ID = instrTypeR_ID | instrTypeI_ID | instrTypeU_ID | instrTypeJ_ID; // Func Bit decode -assign instrFunct7_ID = imem_id_instr_ID[30]; -assign instrFunct3_ID = imem_id_instr_ID[14:12]; +assign instrFunct7_ID = instr_ID[30]; +assign instrFunct3_ID = instr_ID[14:12]; -// Instruction Type (OpCode) Decode -assign instrImmSign_ID = imem_id_instr_ID[31]; -assign instrOpCode_ID = opcode_t'(imem_id_instr_ID[6:0]); //---------------- // ALU Information //---------------- // Immediate Decode -assign idu_exe_aluOp_ID.imm[0] = instrTypeJ_ID ? imem_id_instr_ID[25] : // Bit 25 for I-Type - instrTypeS_ID ? imem_id_instr_ID[7] : // Bit 7 for S-Type - 1'b0; // All other instructions set to 0 +assign instrImmSign_ID = instr_ID[31]; + +assign idu_exe_aluOp_ID.imm[0] = instrTypeI_ID ? instr_ID[20] : // Bit 20 for I-Type + instrTypeS_ID ? instr_ID[7] : // Bit 7 for S-Type + 1'b0; // All other instructions set to 0 + +assign idu_exe_aluOp_ID.imm[4:1] = ({3{instrTypeI_ID | instrTypeJ_ID}} & instr_ID[24:21]) // I-Type + J-Type bits + | ({3{instrTypeS_ID | instrTypeB_ID}} & instr_ID[11:8]); // S-Type + B-Type bits -assign idu_exe_aluOp_ID.imm[4:1] = ({3{instrTypeI_ID | instrTypeJ_ID}} & imem_id_instr_ID[24:21]) // I-Type + J-Type bits - | ({3{instrTypeS_ID | instrTypeB_ID}} & imem_id_instr_ID[11:8]); // S-Type + B-Type bits +assign idu_exe_aluOp_ID.imm[10:5] = {6{~instrTypeU_ID}} & instr_ID[30:25]; // U type doesn't use 10:5 -assign idu_exe_aluOp_ID.imm[10:5] = {6{~instrTypeU_ID}} & imem_id_instr_ID[30:25]; // U type is the only instr that doesn't have 10:5 +assign idu_exe_aluOp_ID.imm[11] = ((instrTypeI_ID | instrTypeS_ID) & instr_ID[31]) // I-Type + S-Type bit + | ( instrTypeB_ID & instr_ID[7]) // B-Type bit + | ( instrTypeJ_ID & instr_ID[20]); // J-Type bit -assign idu_exe_aluOp_ID.imm[11] = ((instrTypeI_ID | instrTypeS_ID) & imem_id_instr_ID[31]) // I-Type + S-Type bit - | ( instrTypeB_ID & imem_id_instr_ID[7]) // B-Type bit - | ( instrTypeJ_ID & imem_id_instr_ID[20]); // J-Type bit +assign idu_exe_aluOp_ID.imm[19:12] = (instrTypeU_ID | instrTypeJ_ID) ? instr_ID[19:12] : // J and U types use 19:12 + {8{instrImmSign_ID}}; // Else use SEXT Bit -assign idu_exe_aluOp_ID.imm[19:12] = (instrTypeU_ID | instrTypeJ_ID) ? imem_id_instr_ID[19:12] : { 8{instrImmSign_ID}}; // Only J and U types use 19:12 as not sign bit -assign idu_exe_aluOp_ID.imm[31:20] = (instrTypeU_ID) ? imem_id_instr_ID[31:20] : {12{instrImmSign_ID}}; // Only U type use 31:20 as not sign bit +assign idu_exe_aluOp_ID.imm[31:20] = (instrTypeU_ID) ? instr_ID[31:20] : // U type uses 31:20 + {12{instrImmSign_ID}}; // Else use SEXT bit -assign idu_exe_aluOp_ID.rs1Sel = (instrOpCode_ID == INSTR_TYPE_AUIPC) | (instrOpCode_ID == INSTR_TYPE_JAL) ? PC : // Loading PC for AUIPC, PC Offset for JAL - (instrOpCode_ID == INSTR_TYPE_LUI) ? ZERO : // Only loading immediate for LUI - RS1; // All else use RS1 value +// ALU Operand Selection +// FIXME: Make Non Priority Mux +assign idu_exe_aluOp_ID.rs1Sel = (instrAuipc) | (instrJal) ? PC : // Loading PC for AUIPC, PC Offset for JAL + (instrLui) ? ZERO : // Only loading immediate for LUI + RS1; // All else use RS1 value + +assign idu_exe_aluOp_ID.rs2Sel = (instrReg) ? RS2 : // RS2 Used in R2R Instr + IMM; // Immediate used for all other instructions -assign idu_exe_aluOp_ID.rs2Sel = (instrOpCode_ID == INSTR_TYPE_REG) ? RS2 : IMM; // Only R Type needs non-immediate op in ALU +// Alu Control Signals +assign idu_exe_aluOp_ID.func3 = instr_ID[14:12]; +assign idu_exe_aluOp_ID.func7 = instr_ID[30]; -assign idu_exe_aluOp_ID.func3 = imem_id_instr_ID[14:12]; -assign idu_exe_aluOp_ID.func7 = imem_id_instr_ID[30]; +// Supply PC for Jmp and AUIPC +assign idu_exe_pc_ID = ifu_idu_pc_ID; //--------------- // Branch Control //--------------- -assign idu_exe_instrJmp_ID = (instrOpCode_ID == INSTR_TYPE_JALR) | (instrOpCode_ID == INSTR_TYPE_JAL); -assign idu_exe_brAluOp_ID = (idu_exe_aluOp_ID.func3 == 3'b0) ? BR_ALU_XOR : BR_ALU_CMP; // Only equality needs XOR all other OPs use compare -assign idu_exe_brCmpSign_ID = (idu_exe_aluOp_ID.func3[2:1] == 2'b11); // Unsigned comparisons have func3 top two bits set -assign idu_exe_brCmpGreater_ID = (idu_exe_aluOp_ID.func3[2:1] == 2'b11); // Unsigned comparisons have func3 top two bits set +assign idu_exe_instrJmp_ID = instrJal_ID | instrJalr_ID; +assign idu_exe_instrBr_ID = instrBr_ID; //--------------- // Memory Control //--------------- -assign instrMemOp_ID = (instrOpCode_ID == INSTR_TYPE_ST) ? MEM_OP_STORE : - (instrOpCode_ID == INSTR_TYPE_LD) ? MEM_OP_LOAD : - MEM_OP_NONE; +assign idu_exe_instrMemOp_ID = (instrSt_ID) ? MEM_OP_STORE : + (instrID_ID) ? MEM_OP_LOAD : + MEM_OP_NONE; //------------------ // Writeback Control //------------------ - - -assign instrAluOp_ID = ; +assign idu_exe_instrRdDataSel_ID = (instrJal_ID | instrJalr_ID) ? PC : // Jump loads PC into RD + (instrLd_ID | instrSt_ID) ? MEM : // Mem loads memory into RD + ALU // All Other OPs load AlU result endmodule diff --git a/core/tb/.gitignore b/core/tb/.gitignore index b5295dc..b5295dc 100644..100755 --- a/core/tb/.gitignore +++ b/core/tb/.gitignore diff --git a/core/tb/core_tb.sv b/core/tb/core_tb.sv index 5824ed8..5824ed8 100644..100755 --- a/core/tb/core_tb.sv +++ b/core/tb/core_tb.sv diff --git a/core/tb/core_tb_imem.sv b/core/tb/core_tb_imem.sv index 740be8a..740be8a 100644..100755 --- a/core/tb/core_tb_imem.sv +++ b/core/tb/core_tb_imem.sv diff --git a/core/testcode/riscv_arithmetic_basic_test_0.S b/core/testcode/riscv_arithmetic_basic_test_0.S index 3fa840a..3fa840a 100644..100755 --- a/core/testcode/riscv_arithmetic_basic_test_0.S +++ b/core/testcode/riscv_arithmetic_basic_test_0.S diff --git a/docker_tools/Dockerfile b/docker_tools/Dockerfile index a9e88d7..a9e88d7 100644..100755 --- a/docker_tools/Dockerfile +++ b/docker_tools/Dockerfile diff --git a/primitives/primitives.core b/primitives/primitives.core index 72a19d7..72a19d7 100644..100755 --- a/primitives/primitives.core +++ b/primitives/primitives.core diff --git a/primitives/rtl/AFF.sv b/primitives/rtl/AFF.sv index 15789bf..15789bf 100644..100755 --- a/primitives/rtl/AFF.sv +++ b/primitives/rtl/AFF.sv diff --git a/primitives/rtl/AFFR.sv b/primitives/rtl/AFFR.sv index 0be8444..0be8444 100644..100755 --- a/primitives/rtl/AFFR.sv +++ b/primitives/rtl/AFFR.sv diff --git a/primitives/rtl/DMUX.sv b/primitives/rtl/DMUX.sv index e69de29..e69de29 100644..100755 --- a/primitives/rtl/DMUX.sv +++ b/primitives/rtl/DMUX.sv diff --git a/primitives/rtl/FLIP.sv b/primitives/rtl/FLIP.sv index baf3c2b..baf3c2b 100644..100755 --- a/primitives/rtl/FLIP.sv +++ b/primitives/rtl/FLIP.sv |