aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--].gitignore0
-rwxr-xr-x[-rw-r--r--]core/pkg/riscv_types.sv32
-rw-r--r--core/rtl/exe.sv191
-rw-r--r--core/rtl/idu.sv199
-rwxr-xr-x[-rw-r--r--]core/tb/.gitignore0
-rwxr-xr-x[-rw-r--r--]core/tb/core_tb.sv0
-rwxr-xr-x[-rw-r--r--]core/tb/core_tb_imem.sv0
-rwxr-xr-x[-rw-r--r--]core/testcode/riscv_arithmetic_basic_test_0.S0
-rwxr-xr-x[-rw-r--r--]docker_tools/Dockerfile0
-rwxr-xr-x[-rw-r--r--]primitives/primitives.core0
-rwxr-xr-x[-rw-r--r--]primitives/rtl/AFF.sv0
-rwxr-xr-x[-rw-r--r--]primitives/rtl/AFFR.sv0
-rwxr-xr-x[-rw-r--r--]primitives/rtl/DMUX.sv0
-rwxr-xr-x[-rw-r--r--]primitives/rtl/FLIP.sv0
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