|
1 | 1 | `include "lib/defines.vh" |
| 2 | +// 指令解码,同时读取寄存器 |
| 3 | +// IF/ID阶段可能会取出经符号扩展为32位的立即数和两个从寄存器中读取的数,放入ID/EX流水线寄存器 |
2 | 4 | module ID( |
3 | 5 | input wire clk, |
4 | 6 | input wire rst, |
@@ -86,9 +88,9 @@ module ID( |
86 | 88 | wire [15:0] imm; |
87 | 89 | wire [25:0] instr_index; |
88 | 90 | wire [19:0] code; |
89 | | - wire [4:0] base; |
90 | | - wire [15:0] offset; |
91 | | - wire [2:0] sel; |
| 91 | + wire [4:0] base;//基址 |
| 92 | + wire [15:0] offset;//偏移 |
| 93 | + wire [2:0] sel;//选择信号 |
92 | 94 |
|
93 | 95 | wire [63:0] op_d, func_d; |
94 | 96 | wire [31:0] rs_d, rt_d, rd_d, sa_d; |
@@ -143,72 +145,148 @@ module ID( |
143 | 145 | assign offset = inst[15:0]; |
144 | 146 | assign sel = inst[2:0]; |
145 | 147 |
|
146 | | - wire inst_ori, inst_lui, inst_addiu, inst_beq; |
147 | | - wire inst_subu, inst_jr, inst_jal, inst_addu; |
148 | | - wire inst_bne, inst_sll, inst_or, inst_xor , inst_lw, inst_sw; |
149 | | - wire inst_sltiu, inst_lb, inst_lbu, inst_lh; |
150 | | - wire inst_lhu, inst_sb, inst_sh; |
151 | | - wire inst_add, inst_addi; |
152 | | - wire inst_sub, inst_slt, inst_slti, inst_sltu; |
| 148 | +// 算术运算指令 |
| 149 | + wire inst_addu; // 将寄存器 rs 的值与寄存器 rt 的值相加,结果写入 rd 寄存器中。 |
| 150 | + wire inst_addiu;// 将寄存器 rs 的值与有符号扩展 至 32 位的立即数 imm 相加,结果写入 rt 寄存器中。 |
| 151 | + wire inst_add; // 将寄存器 rs 的值与寄存器 rt 的值相加,结果写入寄存器 rd 中。 |
| 152 | + // 如果产生溢出,则触发整型溢出例外(IntegerOverflow)。 |
| 153 | + wire inst_addi; // 将寄存器 rs 的值与有符号扩展至 32 位的立即数 imm 相加,结果写入 rt 寄存器中。 |
| 154 | + // 如果产生溢出,则触发整型溢出例外(IntegerOverflow)。 |
| 155 | + |
| 156 | + |
| 157 | + wire inst_sub; //将寄存器 rs 的值与寄存器 rt 的值相减,结果写入 rd 寄存器中。 |
| 158 | + // 如果产生溢出,则触发整型溢出例外(IntegerOverflow)。 |
| 159 | + wire inst_subu; // 将寄存器 rs 的值与寄存器 rt 的值相减,结果写入 rd 寄存器中。 |
| 160 | + |
| 161 | + |
| 162 | + wire inst_slt; //将寄存器 rs 的值与寄存器 rt 中的值进行有符号数比较, |
| 163 | + // 如果寄存器 rs 中的值小,则寄存器 rd 置 1;否则寄存器 rd 置 0。 |
| 164 | + wire inst_slti; //将寄存器 rs 的值与有符号扩展至 32 位的立即数 imm 进行有符号数比较, |
| 165 | + // 如果寄存器 rs 中的值小,则寄存器 rt 置 1;否则寄存器 rt 置 0。 |
| 166 | + wire inst_sltu; // 将寄存器 rs 的值与寄存器 rt 中的值进行无符号数比较, |
| 167 | + // 如果寄存器 rs 中的值小,则寄存器 rd 置 1;否则寄存器 rd 置 0。 |
| 168 | + wire inst_sltiu;// 将寄存器 rs 的值与有符号扩展至 32 位的立即数 imm 进行无符号数比较, |
| 169 | + // 如果寄存器 rs 中的值小,则寄存器 rt 置 1;否则寄存器 rt 置 0。 |
| 170 | + |
| 171 | +// 逻辑运算指令 |
| 172 | + wire inst_ori; // 寄存器 rs 中的值与 0 扩展至 32 位的立即数 imm 按位逻辑或,结果写入寄存器 rt 中。 |
| 173 | + wire inst_lui; // 将 16 位立即数 imm 写入寄存器 rt 的高 16 位,寄存器 rt 的低 16 位置 0。 |
| 174 | + wire inst_or; // 寄存器 rs 中的值与寄存器 rt 中的值按位逻辑或,结果写入寄存器 rd 中。 |
| 175 | + wire inst_xor; // 寄存器 rs 中的值与 0 扩展至 32 位的立即数 imm 按位逻辑或,结果写入寄存器 rt 中。 |
| 176 | + |
| 177 | + |
| 178 | +// 移位指令 |
| 179 | + wire inst_sll; // 由立即数 sa 指定移位量,对寄存器 rt 的值进行逻辑左移,结果写入寄存器 rd 中。 |
| 180 | + |
| 181 | +// 分支跳转指令 |
| 182 | + wire inst_beq; // 如果寄存器 rs 的值等于寄存器 rt 的值则转移,否则顺序执行。 |
| 183 | + // 转移目标由立即数 offset 左移 2 位并进行有符号扩展的值加上该分支指令对应的延迟槽指令的 PC 计算得到。 |
| 184 | + wire inst_bne; // 如果寄存器 rs 的值不等于寄存器 rt 的值则转移,否则顺序执行。 |
| 185 | + // 转移目标由立即数 offset 左移 2位并进行有符号扩展的值 |
| 186 | + // 加上该分支指令对应的延迟槽指令的 PC 计算得到。 |
| 187 | + wire inst_jr; // 无条件跳转。跳转目标为寄存器 rs 中的值。 |
| 188 | + wire inst_jal; // 无条件跳转。跳转目标由该分支指令对应的延迟槽指令的 PC 的最高 4 位与立即数 instr_index 左移2 位后的值拼接得到。 |
| 189 | + // 同时将该分支对应延迟槽指令之后的指令的 PC 值保存至第 31 号通用寄存器中。 |
| 190 | + |
| 191 | +//访存指令 |
| 192 | + wire inst_lw; // 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址, |
| 193 | + // 如果地址不是 4 的整数倍则触发地址错例外, |
| 194 | + // 否则据此虚地址从存储器中读取连续 4 个字节的值,写入到 rt 寄存器中。 |
| 195 | + wire inst_sw; // 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址, |
| 196 | + // 如果地址不是 4 的整数倍则触发地址错例外, |
| 197 | + // 否则据此虚地址将 rt 寄存器存入存储器中。 |
| 198 | + |
| 199 | + wire inst_lb; // 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址, |
| 200 | + // 据此虚地址从存储器中读取 1 个字节的值并进行符号扩展,写入到 rt 寄存器中。 |
| 201 | + wire inst_lbu; // 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址, |
| 202 | + // 据此虚地址从存储器中读取 1 个字节的值并进行 0 扩展,写入到 rt 寄存器中。 |
| 203 | + wire inst_lh; // 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 2 的整数倍 |
| 204 | + // 则触发地址错例外,否则据此虚地址从存储器中读取连续 2 个字节的值并进行符号扩展,写入到rt 寄存器中。 |
| 205 | + |
| 206 | + wire inst_lhu; // 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 2 的整数倍则触发地址错例外, |
| 207 | + // 否则据此虚地址从存储器中读取连续 2 个字节的值并进行 0 扩展,写入到 rt寄存器中。 |
| 208 | + wire inst_sb; // 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,据此虚地址将 rt 寄存器的最低字节存入存储器中。 |
| 209 | + wire inst_sh; // 将 base 寄存器的值加上符号扩展后的立即数 offset 得到访存的虚地址,如果地址不是 2 的整数倍则触发地址错例外, |
| 210 | + // 否则据此虚地址将 rt 寄存器的低半字存入存储器中。 |
| 211 | + |
| 212 | + // 数据移动指令 |
| 213 | + |
| 214 | + |
| 215 | + |
153 | 216 |
|
154 | 217 | wire op_add, op_sub, op_slt, op_sltu; |
155 | 218 | wire op_and, op_nor, op_or, op_xor; |
156 | 219 | wire op_sll, op_srl, op_sra, op_lui; |
157 | 220 |
|
| 221 | + // 6-64译码器 |
158 | 222 | decoder_6_64 u0_decoder_6_64( |
159 | 223 | .in (opcode ), |
160 | 224 | .out (op_d ) |
161 | 225 | ); |
162 | 226 |
|
| 227 | + // 6-64译码器 |
163 | 228 | decoder_6_64 u1_decoder_6_64( |
164 | 229 | .in (func ), |
165 | 230 | .out (func_d ) |
166 | 231 | ); |
167 | | - |
| 232 | + |
| 233 | + // 5-32译码器 |
168 | 234 | decoder_5_32 u0_decoder_5_32( |
169 | 235 | .in (rs ), |
170 | 236 | .out (rs_d ) |
171 | 237 | ); |
172 | 238 |
|
| 239 | + // 5-32译码器 |
173 | 240 | decoder_5_32 u1_decoder_5_32( |
174 | 241 | .in (rt ), |
175 | 242 | .out (rt_d ) |
176 | 243 | ); |
177 | 244 |
|
178 | | - |
179 | | - assign inst_ori = op_d[6'b00_1101]; |
180 | | - assign inst_lui = op_d[6'b00_1111]; |
| 245 | + // 算术运算指令 |
181 | 246 | assign inst_addiu = op_d[6'b00_1001]; |
182 | | - assign inst_beq = op_d[6'b00_0100]; |
183 | | - |
184 | | - assign inst_subu = op_d[6'b00_0000] & func_d[6'b10_0011]; |
185 | | - assign inst_jr = op_d[6'b00_0000] & func_d[6'b00_1000]; |
186 | | - assign inst_jal = op_d[6'b00_0011]; |
187 | 247 | assign inst_addu = op_d[6'b00_0000] & func_d[6'b10_0001]; |
188 | | - |
189 | | - assign inst_bne = op_d[6'b00_0101]; |
190 | | - assign inst_sll = op_d[6'b00_0000] & func_d[6'b00_0000]; |
191 | | - assign inst_or = op_d[6'b00_0000] & func_d[6'b10_0101]; |
192 | | - |
193 | | - assign inst_xor = op_d[6'b00_0000] & func_d[6'b10_0110]; |
194 | | - assign inst_lw = op_d[6'b10_0011]; |
195 | | - assign inst_sw = op_d[6'b10_1011]; |
196 | | - |
197 | 248 | assign inst_add = op_d[6'b00_0000] & func_d[6'b10_0000]; |
198 | 249 | assign inst_addi = op_d[6'b00_1000]; |
| 250 | + |
199 | 251 | assign inst_sub = op_d[6'b00_0000] & func_d[6'b10_0010]; |
200 | | - |
| 252 | + assign inst_subu = op_d[6'b00_0000] & func_d[6'b10_0011]; |
| 253 | + |
201 | 254 | assign inst_slt = op_d[6'b00_0000] & func_d[6'b10_1010]; |
202 | 255 | assign inst_slti = op_d[6'b00_1010]; |
203 | 256 | assign inst_sltu = op_d[6'b00_0000] & func_d[6'b10_1011]; |
204 | 257 | assign inst_sltiu = op_d[6'b00_1011]; |
205 | 258 |
|
206 | | - assign inst_lb = 1'b0; |
207 | | - assign inst_lbu = 1'b0; |
208 | | - assign inst_lh = 1'b0; |
209 | | - assign inst_lhu = 1'b0; |
210 | | - assign inst_sb = 1'b0; |
211 | | - assign inst_sh = 1'b0; |
| 259 | + // 逻辑运算指令 |
| 260 | + assign inst_ori = op_d[6'b00_1101]; |
| 261 | + assign inst_lui = op_d[6'b00_1111]; |
| 262 | + assign inst_or = op_d[6'b00_0000] & func_d[6'b10_0101]; |
| 263 | + assign inst_xor = op_d[6'b00_0000] & func_d[6'b10_0110]; |
| 264 | + |
| 265 | + // 移位指令 |
| 266 | + assign inst_sll = op_d[6'b00_0000] & func_d[6'b00_0000]; |
| 267 | + |
| 268 | + |
| 269 | + // 分支跳转指令 |
| 270 | + assign inst_beq = op_d[6'b00_0100]; |
| 271 | + assign inst_bne = op_d[6'b00_0101]; |
| 272 | + assign inst_jr = op_d[6'b00_0000] & func_d[6'b00_1000]; |
| 273 | + assign inst_jal = op_d[6'b00_0011]; |
| 274 | + |
| 275 | + |
| 276 | + // 访存指令 |
| 277 | + assign inst_lw = op_d[6'b10_0011]; |
| 278 | + assign inst_sw = op_d[6'b10_1011]; |
| 279 | + |
| 280 | + assign inst_lb = op_d[6'b10_0000]; |
| 281 | + assign inst_lbu = op_d[6'b10_0100]; |
| 282 | + assign inst_lh = op_d[6'b10_0001]; |
| 283 | + assign inst_lhu = op_d[6'b10_0101]; |
| 284 | + assign inst_sb = op_d[6'b10_1000]; |
| 285 | + assign inst_sh = op_d[6'b10_1001]; |
| 286 | + |
| 287 | + |
| 288 | + |
| 289 | + |
212 | 290 |
|
213 | 291 | // rs to reg1 |
214 | 292 | assign sel_alu_src1[0] = inst_ori | inst_addiu | inst_subu | inst_jr | inst_addu | inst_or | inst_xor | inst_lw | inst_sw; |
@@ -256,6 +334,7 @@ module ID( |
256 | 334 | // load and store enable |
257 | 335 | assign data_ram_en = inst_sw|inst_lw; |
258 | 336 |
|
| 337 | + |
259 | 338 | // write enable |
260 | 339 | assign data_ram_wen = inst_sw; |
261 | 340 |
|
|
0 commit comments