CPU 速通系列 0-2:openmips 内部

背景知识

代码

Path src/cpu/openmips.sv

  1`include "defines.svh"
  2
  3module openmips (
  4
  5    input logic clk,
  6    input logic rst,
  7
  8    input  logic [`RegBus] rom_data_i,
  9    output logic [`RegBus] rom_addr_o,
 10    output logic           rom_ce_o
 11
 12);
 13
 14    logic [`InstAddrBus] pc;
 15    logic [`InstAddrBus] id_pc_i;
 16    logic [`InstBus] id_inst_i;
 17
 18    //连接译码阶段ID模块的输出与ID/EX模块的输入
 19    logic [`AluOpBus] id_aluop_o;
 20    logic [`AluSelBus] id_alusel_o;
 21    logic [`RegBus] id_reg1_o;
 22    logic [`RegBus] id_reg2_o;
 23    logic id_wreg_o;
 24    logic [`RegAddrBus] id_wd_o;
 25    logic id_is_in_delayslot_o;
 26    logic [`RegBus] id_link_address_o;
 27
 28    //连接ID/EX模块的输出与执行阶段EX模块的输入
 29    logic [`AluOpBus] ex_aluop_i;
 30    logic [`AluSelBus] ex_alusel_i;
 31    logic [`RegBus] ex_reg1_i;
 32    logic [`RegBus] ex_reg2_i;
 33    logic ex_wreg_i;
 34    logic [`RegAddrBus] ex_wd_i;
 35    logic ex_is_in_delayslot_i;
 36    logic [`RegBus] ex_link_address_i;
 37
 38    //连接执行阶段EX模块的输出与EX/MEM模块的输入
 39    logic ex_wreg_o;
 40    logic [`RegAddrBus] ex_wd_o;
 41    logic [`RegBus] ex_wdata_o;
 42    logic [`RegBus] ex_hi_o;
 43    logic [`RegBus] ex_lo_o;
 44    logic ex_whilo_o;
 45
 46    //连接EX/MEM模块的输出与访存阶段MEM模块的输入
 47    logic mem_wreg_i;
 48    logic [`RegAddrBus] mem_wd_i;
 49    logic [`RegBus] mem_wdata_i;
 50    logic [`RegBus] mem_hi_i;
 51    logic [`RegBus] mem_lo_i;
 52    logic mem_whilo_i;
 53
 54    //连接访存阶段MEM模块的输出与MEM/WB模块的输入
 55    logic mem_wreg_o;
 56    logic [`RegAddrBus] mem_wd_o;
 57    logic [`RegBus] mem_wdata_o;
 58    logic [`RegBus] mem_hi_o;
 59    logic [`RegBus] mem_lo_o;
 60    logic mem_whilo_o;
 61
 62    //连接MEM/WB模块的输出与回写阶段的输入
 63    logic wb_wreg_i;
 64    logic [`RegAddrBus] wb_wd_i;
 65    logic [`RegBus] wb_wdata_i;
 66    logic [`RegBus] wb_hi_i;
 67    logic [`RegBus] wb_lo_i;
 68    logic wb_whilo_i;
 69
 70    //连接译码阶段ID模块与通用寄存器Regfile模块
 71    logic reg1_read;
 72    logic reg2_read;
 73    logic [`RegBus] reg1_data;
 74    logic [`RegBus] reg2_data;
 75    logic [`RegAddrBus] reg1_addr;
 76    logic [`RegAddrBus] reg2_addr;
 77
 78    //连接执行阶段与hilo模块的输出,读取HI、LO寄存器
 79    logic [`RegBus] hi;
 80    logic [`RegBus] lo;
 81
 82    //连接执行阶段与ex_reg模块,用于多周期的MADD、MADDU、MSUB、MSUBU指令
 83    logic [`DoubleRegBus] hilo_temp_o;
 84    logic [1:0] cnt_o;
 85
 86    logic [`DoubleRegBus] hilo_temp_i;
 87    logic [1:0] cnt_i;
 88
 89    logic [`DoubleRegBus] div_result;
 90    logic div_ready;
 91    logic [`RegBus] div_opdata1;
 92    logic [`RegBus] div_opdata2;
 93    logic div_start;
 94    logic div_annul;
 95    logic signed_div;
 96
 97    logic is_in_delayslot_i;
 98    logic is_in_delayslot_o;
 99    logic next_inst_in_delayslot_o;
100    logic id_branch_flag_o;
101    logic [`RegBus] branch_target_address;
102
103    logic [5:0] stall;
104    logic stallreq_from_id;
105    logic stallreq_from_ex;
106
107    //pc_reg例化
108    pc_reg pc_reg0 (
109        .clk(clk),
110        .rst(rst),
111        .stall(stall),
112        .branch_flag_i(id_branch_flag_o),
113        .branch_target_address_i(branch_target_address),
114        .pc(pc),
115        .ce(rom_ce_o)
116
117    );
118
119    assign rom_addr_o = pc;
120
121    //IF/ID模块例化
122    if_id if_id0 (
123        .clk(clk),
124        .rst(rst),
125        .stall(stall),
126        .if_pc(pc),
127        .if_inst(rom_data_i),
128        .id_pc(id_pc_i),
129        .id_inst(id_inst_i)
130    );
131
132    //译码阶段ID模块
133    id id0 (
134        .rst(rst),
135        .pc_i(id_pc_i),
136        .inst_i(id_inst_i),
137
138        .reg1_data_i(reg1_data),
139        .reg2_data_i(reg2_data),
140
141        //处于执行阶段的指令要写入的目的寄存器信息
142        .ex_wreg_i(ex_wreg_o),
143        .ex_wdata_i(ex_wdata_o),
144        .ex_wd_i(ex_wd_o),
145
146        //处于访存阶段的指令要写入的目的寄存器信息
147        .mem_wreg_i(mem_wreg_o),
148        .mem_wdata_i(mem_wdata_o),
149        .mem_wd_i(mem_wd_o),
150
151        .is_in_delayslot_i(is_in_delayslot_i),
152
153        //送到regfile的信息
154        .reg1_read_o(reg1_read),
155        .reg2_read_o(reg2_read),
156
157        .reg1_addr_o(reg1_addr),
158        .reg2_addr_o(reg2_addr),
159
160        //送到ID/EX模块的信息
161        .aluop_o(id_aluop_o),
162        .alusel_o(id_alusel_o),
163        .reg1_o(id_reg1_o),
164        .reg2_o(id_reg2_o),
165        .wd_o(id_wd_o),
166        .wreg_o(id_wreg_o),
167
168        .next_inst_in_delayslot_o(next_inst_in_delayslot_o),
169        .branch_flag_o(id_branch_flag_o),
170        .branch_target_address_o(branch_target_address),
171        .link_addr_o(id_link_address_o),
172
173        .is_in_delayslot_o(id_is_in_delayslot_o),
174
175        .stallreq(stallreq_from_id)
176    );
177
178    //通用寄存器Regfile例化
179    regfile regfile1 (
180        .clk(clk),
181        .rst(rst),
182        .we(wb_wreg_i),
183        .waddr(wb_wd_i),
184        .wdata(wb_wdata_i),
185        .re1(reg1_read),
186        .raddr1(reg1_addr),
187        .rdata1(reg1_data),
188        .re2(reg2_read),
189        .raddr2(reg2_addr),
190        .rdata2(reg2_data)
191    );
192
193    //ID/EX模块
194    id_ex id_ex0 (
195        .clk(clk),
196        .rst(rst),
197
198        .stall(stall),
199
200        //从译码阶段ID模块传递的信息
201        .id_aluop(id_aluop_o),
202        .id_alusel(id_alusel_o),
203        .id_reg1(id_reg1_o),
204        .id_reg2(id_reg2_o),
205        .id_wd(id_wd_o),
206        .id_wreg(id_wreg_o),
207        .id_link_address(id_link_address_o),
208        .id_is_in_delayslot(id_is_in_delayslot_o),
209        .next_inst_in_delayslot_i(next_inst_in_delayslot_o),
210
211        //传递到执行阶段EX模块的信息
212        .ex_aluop(ex_aluop_i),
213        .ex_alusel(ex_alusel_i),
214        .ex_reg1(ex_reg1_i),
215        .ex_reg2(ex_reg2_i),
216        .ex_wd(ex_wd_i),
217        .ex_wreg(ex_wreg_i),
218        .ex_link_address(ex_link_address_i),
219        .ex_is_in_delayslot(ex_is_in_delayslot_i),
220        .is_in_delayslot_o(is_in_delayslot_i)
221    );
222
223    //EX模块
224    ex ex0 (
225        .rst(rst),
226
227        //送到执行阶段EX模块的信息
228        .aluop_i(ex_aluop_i),
229        .alusel_i(ex_alusel_i),
230        .reg1_i(ex_reg1_i),
231        .reg2_i(ex_reg2_i),
232        .wd_i(ex_wd_i),
233        .wreg_i(ex_wreg_i),
234        .hi_i(hi),
235        .lo_i(lo),
236
237        .wb_hi_i(wb_hi_i),
238        .wb_lo_i(wb_lo_i),
239        .wb_whilo_i(wb_whilo_i),
240        .mem_hi_i(mem_hi_o),
241        .mem_lo_i(mem_lo_o),
242        .mem_whilo_i(mem_whilo_o),
243
244        .hilo_temp_i(hilo_temp_i),
245        .cnt_i(cnt_i),
246
247        .div_result_i(div_result),
248        .div_ready_i (div_ready),
249
250        .link_address_i(ex_link_address_i),
251        .is_in_delayslot_i(ex_is_in_delayslot_i),
252
253        //EX模块的输出到EX/MEM模块信息
254        .wd_o(ex_wd_o),
255        .wreg_o(ex_wreg_o),
256        .wdata_o(ex_wdata_o),
257
258        .hi_o(ex_hi_o),
259        .lo_o(ex_lo_o),
260        .whilo_o(ex_whilo_o),
261
262        .hilo_temp_o(hilo_temp_o),
263        .cnt_o(cnt_o),
264
265        .div_opdata1_o(div_opdata1),
266        .div_opdata2_o(div_opdata2),
267        .div_start_o  (div_start),
268        .signed_div_o (signed_div),
269
270        .stallreq(stallreq_from_ex)
271
272    );
273
274    //EX/MEM模块
275    ex_mem ex_mem0 (
276        .clk(clk),
277        .rst(rst),
278
279        .stall(stall),
280
281        //来自执行阶段EX模块的信息
282        .ex_wd(ex_wd_o),
283        .ex_wreg(ex_wreg_o),
284        .ex_wdata(ex_wdata_o),
285        .ex_hi(ex_hi_o),
286        .ex_lo(ex_lo_o),
287        .ex_whilo(ex_whilo_o),
288
289        .hilo_i(hilo_temp_o),
290        .cnt_i (cnt_o),
291
292        //送到访存阶段MEM模块的信息
293        .mem_wd(mem_wd_i),
294        .mem_wreg(mem_wreg_i),
295        .mem_wdata(mem_wdata_i),
296        .mem_hi(mem_hi_i),
297        .mem_lo(mem_lo_i),
298        .mem_whilo(mem_whilo_i),
299
300        .hilo_o(hilo_temp_i),
301        .cnt_o (cnt_i)
302
303    );
304
305    //MEM模块例化
306    mem mem0 (
307        .rst(rst),
308
309        //来自EX/MEM模块的信息	
310        .wd_i(mem_wd_i),
311        .wreg_i(mem_wreg_i),
312        .wdata_i(mem_wdata_i),
313        .hi_i(mem_hi_i),
314        .lo_i(mem_lo_i),
315        .whilo_i(mem_whilo_i),
316
317        //送到MEM/WB模块的信息
318        .wd_o(mem_wd_o),
319        .wreg_o(mem_wreg_o),
320        .wdata_o(mem_wdata_o),
321        .hi_o(mem_hi_o),
322        .lo_o(mem_lo_o),
323        .whilo_o(mem_whilo_o)
324    );
325
326    //MEM/WB模块
327    mem_wb mem_wb0 (
328        .clk(clk),
329        .rst(rst),
330
331        .stall(stall),
332
333        //来自访存阶段MEM模块的信息	
334        .mem_wd(mem_wd_o),
335        .mem_wreg(mem_wreg_o),
336        .mem_wdata(mem_wdata_o),
337        .mem_hi(mem_hi_o),
338        .mem_lo(mem_lo_o),
339        .mem_whilo(mem_whilo_o),
340
341        //送到回写阶段的信息
342        .wb_wd(wb_wd_i),
343        .wb_wreg(wb_wreg_i),
344        .wb_wdata(wb_wdata_i),
345        .wb_hi(wb_hi_i),
346        .wb_lo(wb_lo_i),
347        .wb_whilo(wb_whilo_i)
348
349    );
350
351    hilo_reg hilo_reg0 (
352        .clk(clk),
353        .rst(rst),
354
355        //写端口
356        .we  (wb_whilo_i),
357        .hi_i(wb_hi_i),
358        .lo_i(wb_lo_i),
359
360        //读端口1
361        .hi_o(hi),
362        .lo_o(lo)
363    );
364
365    ctrl ctrl0 (
366        .rst(rst),
367
368        .stallreq_from_id(stallreq_from_id),
369
370        //来自执行阶段的暂停请求
371        .stallreq_from_ex(stallreq_from_ex),
372
373        .stall(stall)
374    );
375
376    div div0 (
377        .clk(clk),
378        .rst(rst),
379
380        .signed_div_i(signed_div),
381        .opdata1_i(div_opdata1),
382        .opdata2_i(div_opdata2),
383        .start_i(div_start),
384        .annul_i(1'b0),
385
386        .result_o(div_result),
387        .ready_o (div_ready)
388    );
389
390endmodule

解读

实现了一个名为openmips的模块。

设计意图

简要而言,该模块是一个基于MIPS指令集架构的处理器设计,用于执行指令。


具体而言,该模块包含了多个子模块,用于实现不同阶段的处理器功能,包括指令获取、译码、执行、访存和回写等。

端口

  • clk:输入时钟信号

  • rst:复位信号

  • rom_data_i:ROM数据输入

  • rom_addr_o:ROM地址输出

  • rom_ce_o:ROM使能信号输出

  • 其他各种输入和输出端口

实现思路

该模块通过实例化多个子模块来完成处理器的不同功能阶段,包括指令获取、译码、执行、访存和回写等。 代码主要负责各个子模块之间的连接和数据传递。

其中,译码阶段(ID)模块将指令解码并提取需要的信息,包括目的寄存器和操作数等,然后将这些信息传递给下一个阶段。

执行阶段(EX)模块执行具体的指令操作,并产生执行结果。

访存阶段(MEM)模块执行内存访问操作,包括读取和写入数据。

回写阶段(WB)模块将执行阶段的结果写入目的寄存器。

此外,还包括其他辅助模块,用于控制流处理、寄存器读写、HI/LO寄存器的操作等。

整个处理器模块通过时钟信号进行同步,并通过各个子模块之间的信号传递实现数据的流动和处理器功能的完成。

参考资料

本文与 AI 合作完成。

因为涉及到很多个模块,这里就不一一列出了,我会在新的文章各自介绍。