blob: 0bfd073546fcd6a34dadfe650afd80ff12b873ea (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
module idu
import riscv_types::*;
#(
)
(
input logic clk,
input logic rst_l,
// I-MEM Interface
input logic [INSTR_SIZE-1:0] imem_id_instr_ID,
// Fetch Interface
input logic [PC_SIZE-1:0] imem_id_pc_ID,
//------------------
// Execute Interface
//------------------
input logic exe_idu_exeRdy_EXE,
// Alu information
output alu_op_t idu_exe_aluOp_ID,
// Register Idx
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
);
// OpCode
opcode_t instrOpCode_ID;
// Instruction Type
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;
// 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;
// Funct3 and Funct7
logic [2:0] instrFunct3_ID;
logic instrFunct7_ID;
// Control Bits
// Memory Op
mem_op_t instrMemOp_ID;
// Branch OP
brjmp_op_t instrBrJmpOp_ID;
// ALU Operand Selection
aluSelOp1_t instrAluIn1_ID;
aluSelOp2_t instrAluIn2_ID;
// Reg File
logic [NUM_REG-1:0] [WORD_WID-1:0] regData_XXX;
//------------------------
// Instruction Type Decode
//------------------------
// 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);
// Register Index Decode
assign instrRs1Idx_ID = imem_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 instrRs2Vld_ID = instrTypeR_ID | instrTypeS_ID | instrTypeB_ID;
assign instrRdIdx_ID = imem_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];
// 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 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}} & 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) & 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) ? 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.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
assign idu_exe_aluOp_ID.rs2Sel = (instrOpCode_ID == INSTR_TYPE_REG) ? RS2 : IMM; // Only R Type needs non-immediate op in ALU
assign idu_exe_aluOp_ID.func3 = imem_id_instr_ID[14:12];
assign idu_exe_aluOp_ID.func7 = imem_id_instr_ID[30];
//---------------
// 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
//---------------
// Memory Control
//---------------
assign instrMemOp_ID = (instrOpCode_ID == INSTR_TYPE_ST) ? MEM_OP_STORE :
(instrOpCode_ID == INSTR_TYPE_LD) ? MEM_OP_LOAD :
MEM_OP_NONE;
//------------------
// Writeback Control
//------------------
assign instrAluOp_ID = ;
endmodule
|