Lab17 V14.0
版本控制
| 版本 | 描述 |
|---|---|
| V0 | Lab3 |
| V1.0 | Lab3 相对V0变化: 修改了文件名,各阶段以_stage结尾(因为if是关键词,所以module名不能叫if,遂改为if_stage,为了统一命名,将所有module后缀加上_stage) 删除了imm_sign信号(默认对立即数进行有符号数扩展) 由于对sw指令进行了重新理解:无论如何都是需要将rt_data传递给EXE阶段,故将部分译码逻辑进行后移至EXE阶段,避免id_to_exe_data总线过于庞大 将ins_shmat剔除出id_to_exe_data,因为imm包括ins_shamt 对信号进行重命名(例如在ID阶段有个信号叫rf_we,最终要传递给WB阶段,那么在EXE阶段,该信号叫作exe_rf_we,同理mem_rf_we,wb_rf_we),不然都叫rf_we,Debug的时候太痛苦了。 |
| V2.0 | Lab4 相对V1.0的变化 引入`ifdef-`else-`endif来实现相对V1.0的代码增量 增加了旁路控制,减少流水线阻塞(因为增加了旁路,所以修改了ID、EXE、MEM的接口) 修改了ready_go命令,用于控制流水线的阻塞 |
| V3.0 | Lab6(加载的是func_lab6的.coe文件,而不是func_lab5的,因为没有func_lab5这个东西) 相对V2.0的变化:电路细节变化详见:“CPU设计实战电路图”,图中Lab6的变化均以红色背景的方框框起来,并以黄色背景的“Lab6复用/新增信号”标注。本lab6.docx中,新增及修改的信号以红色标注。 删掉了ALU.v的接口,将alu_shamt合并至data_1,方便对新加指令sllv、srlv、srav的数据通路的复用 增加了ID.v中的alu_add的“或门”的输入 扩充了id_to_exe_data总线数据, 因为alu_op扩充了新的指令 添加了imm_zero_ext信号 修改了ins_R、ins_J、ins_I,因为增加了新的指令 乘法器和除法器调用vivado的IP,其周期参数化可配置设计 乘法和除法结果存放的寄存器HI/LO放在WB.v中 增加了sfr.v,用于特殊寄存器的存储 增加了mul_div.v,用于处理乘法和除法。增加了mul.v用于处理乘法,增加了divu.v用于处理无符号除法,增加了divs.v用于处理有符号除法 修改了id_to_exe_data,添加了新信号:imm_zero_ext_en 修改了id_to_exe_data,扩充了alu_op的位宽,并将alu_op调整至id_to_exe_data的最高位,方便未来扩充指令 |
| V4.0 | Lab7 修改了alu_op的位宽 新增了两个bus:lw_bus、sw_bus,同时将mem_rd整合至lw_bus,将mem_we整合至sw_bus 扩大了id_to_exe_data lw_bus传递至MEM阶段结束,sw_bus传递至EXE阶段结束 修改了旁路,之前都是lw的旁路,这里将其扩充了lb、lbu、lh、lhu、lwl、lwr |
| V5.0 | Lab8 (对应第7章任务一):添加syscall例外支持 增加MTC0、MFC0、ERET指令 增加CP0寄存器Status、Cause、EPC 增加SYSCALL指令 新建SSR.v(即system registers),是ID.v的子模块 为ID、EXE、MEM、WB级增加了flush信号,用于将数据清零 |
| V6.0 | 添加break指令断点例外 添加地址错、整数溢出、保留指令例外 增加CP0寄存器Count、Compare、BadVAddr 增加时钟中断 增加6个硬中断 增加2个软件中断 |
| V6.8 | 此版本感觉叫5.8更好,但是本人就顺着叫6.8了,此版本实际上是V5.0的重写,重新设计了数据通路: 将SSR.v放在WB阶段(依据原书P173) MFC0/MTC0也放在WB阶段,并且不引入旁路,而是直接插入NOP(依据原书P180) |
| V7.0 | 完成了原书Lab10需要的类SRAM总线的测试 该版本存在软件中断这一遗留问题(详见32.15小节) |
| V7.1 | 在约束50MHz(PLL出来2个时钟:50和100MHz)的条件下,V7.0留有的裕度已经很小了,本V7.1版本主要在V7.0电路的基础上对电路时序进行优化。 |
| V8.0 | 文件变化得较多,包括: 修改了confreg.v sram_wrap.v替换为axi_wrap_ram.v 增加了axi_wrap.v 将soc_sram_lite_top.v替换为soc_axi_lite_top.v 增加了2个IP:axi_crossbar_1x2、axi_ram 更改了顶层,之前顶层是mycpu_top,现在将其重命名为mycpu_sram,在其上新增一顶层,其名为mycpu_top,可以这样理解: mycpu_top(old) + axi_interface = mpycpu_top(new) |
| V9.0 | 相对Lab11没有任何变化,仅仅是修改了CPU_CDE_SRAM/rlt/CONFREG/confreg.v里的宏RANDOM_SEED进行测试 |
| V10.0 | Lab13与Lab3~Lab12没有任何联系,是一个独立的个体,因此没有`define Lab13,且由于代码过与简单,不予绘制专门的电路图 |
| V11.0 | Lab14 将tlb.v添加进工程 修改了IF、ID、EXE、MEM、WB等接口信号,用于tlb 添加了TLB的C0寄存器 |
| V12.0 | Lab15(还是对应原书Lab14) 添加了tlbr、tlbwi、tlbp指令例外 取指、数据访问的MMU |
| V13.0 | Lab16 Lab16_pre此版本为Lab16的预处理版本,主要进行了以下处理: 从此版本开始,后面的代码的独立模块使用VHDL进行编写,仅Verilog调用VHDL时使用Verilog进行编写。 重写“类SRAM-AXI转接桥”,支持AXI的burst传输 添加容量为16Byte的全相联ICache(该Cache只有一行)和DCache(同ICache) 使修改后的代码通过Lab15的测试 |
| V14.0 | Lab17 将Lab16设计的Cache集成到CPU中,成为ICache 将Lab16设计的Cache集成到CPU中,成为DCache |
Top顶层
接口信号
MYCPU_AXI_TOP.v(new TOP)
| 名称 | 宽度 | 方向 | 描述 |
|---|---|---|---|
| 中断 | |||
| int | 6 | I | 恒为6’h0(我猜:这应该是中断信号) |
| AXI 时钟与复位 | |||
| aclk | 1 | I | 时钟信号,来自clk_pll的输出时钟 |
| aresetn | 1 | I | 复位信号,低电平复位 |
| AXI 写请求通道 | |||
| awid[n:0] | 4 | O | 写请求标识号 |
| awaddr[m:0] | 32 | O | 写请求地址 |
| awsize[2:0] | 3 | O | 写请求数据宽度 |
| awlen[3:0] | 8 | O | 写请求数据长度 |
| awburst[1:0] | 2 | O | 写请求类型 |
| awavalid | 1 | O | 写请求有效信号 |
| awready | 1 | I | 写请求接收准备好信号 |
| AXI 写数据通道 | |||
| wid[n:0] | 4 | O | 写数据标识号,与写请求标识号对应 |
| wdata[j:0] | 32 | O | 写数据 |
| wstrb[k:0] | 4 | O | 写数据屏蔽信号,1位对应8个数据位 |
| wvalid | 1 | O | 写数据有效信号 |
| wready | 1 | I | 写数据接收准备好信号 |
| AXI 写响应通道 | |||
| bid[n:0] | 4 | I | 写响应标识号,与写请求标识号对应 |
| bresp[1:0] | 2 | I | 写响应状态 |
| wvalid | 1 | I | 写响应有效信号 |
| wready | 1 | O | 写响应接收准备好信号 |
| AXI 读请求通道 | |||
| arid[n:0] | 4 | O | 读请求标识号 |
| araddr[m:0] | 32 | O | 读请求地址 |
| arsize[2:0] | 3 | O | 读请求数据宽度 |
| arlen[3:0] | 8 | O | 读请求数据长度 |
| arburst[1:0] | 2 | O | 读请求类型 |
| aravalid | 1 | O | 读请求有效信号 |
| arready | 1 | I | 读请求接收准备好信号 |
| AXI 读响应通道 | |||
| rid[n:0] | 4 | I | 读数据标识号,与读请求标识号对应 |
| rdata[j:0] | 32 | I | 读数据 |
| rresp[1:0] | 2 | I | 读响应状态 |
| rvalid | 1 | I | 读数据有效信号 |
| rready | 1 | O | 写读数据接收准备好信号 |
MYCPU_TOP.v(old TOP)
| 名称 | 宽度 | 方向 | 描述 |
|---|---|---|---|
| 时钟与复位 | |||
| clk | 1 | I | 时钟信号,来自clk_pll的输出时钟 |
| resetn | 1 | I | 复位信号,低电平同步复位 |
| 取指端访存接口 | |||
| inst_sram_req | 1 | O | 请求信号,为1时有读写请求,为1时无读写请求 |
| inst_sram_wr | 1 | O | 为1表示该次是写请求,为0表示该次是读请求 |
| inst_sram_size | 2 | O | 该次请求传输的字节数,0:1byte,1:2bytes,2:4bytes |
| inst_sram_wstrb | 4 | O | 该次写请求的字节写使能 |
| inst_sram_addr | 32 | O | 该次请求的地址 |
| inst_sram_wdata | 32 | O | 该次写请求的写数据 |
| inst_sram_addr_ok | 1 | I | 该次写请求的地址传输OK,读:地址被接收;写:地址和数据被接收 |
| inst_sram_data_ok | 1 | I | 该次请求的数据传输OK,读:数据返回;写:数据写入完成 |
| inst_sram_rdata | 32 | I | 该次写请求返回的读数据 |
| 数据端访存接口 | |||
| data_sram_req | 1 | O | 请求信号,为1时有读写请求,为1时无读写请求 |
| data_sram_wr | 1 | O | 为1表示该次是写请求,为0表示该次是读请求 |
| data_sram_size | 2 | O | 该次请求传输的字节数,0:1byte,1:2bytes,2:4bytes |
| data_sram_wstrb | 4 | O | 该次写请求的字节写使能 |
| data_sram_addr | 32 | O | 该次请求的地址 |
| data_sram_wdata | 32 | O | 该次写请求的写数据 |
| data_sram_addr_ok | 1 | I | 该次写请求的地址传输OK,读:地址被接收;写:地址和数据被接收 |
| data_sram_data_ok | 1 | I | 该次请求的数据传输OK,读:数据返回;写:数据写入完成 |
| data_sram_rdata | 32 | I | 该次写请求返回的读数据 |
| debug信号,供验证平台使用 | |||
| debug_wb_pc | 32 | O | 写回级(多周期最后一级)的PC,需要myCPU里将PC一路传递到写回级 |
| debug_wb_rf_wen | 4 | O | 写回级写寄存器堆(regfiles)的写使能,为字节使能,如果myCPU写regfiles为单字节写使能,则将写使能扩展成4位即可 |
| debug_wb_rf_wnum | 5 | O | 写回级写regfiles的目的寄存器号 |
| debug_wb_rf_wdata | 32 | O | 写回级写regfiles的写数据 |
接口时序
略(MIPS经典五级流水线)
代码结构
MYCPU_AXI_TOP.v
|____MYCPU_TOP.v
|____IF.v
|____ID.v
|____RF.v(2个读端口,1个写端口)
|____SFR.v(1个读端口,2个写端口)
|____EXE.v
|____ALU.v
|____MUL_DIV.v(专门处理乘法和除法)
|____MUL.v
|____DIVU.v
|____DIVS.v
|____MEM.v
|____WB.v
|____SSR.v
|____MYCPU.h
DATA_RAM.v
IF.v(修改为IF_STAGE,因为会与关键词if冲突)
接口信号
| 名称 | 宽度 | 方向 | 描述 |
|---|---|---|---|
| 时钟与复位 | |||
| clk | 1 | I | 时钟信号,来自clk_pll的输出时钟 |
| resetn | 1 | I | 复位信号,低电平同步复位 |
| 与TOP | |||
| inst_sram_req | 1 | O | 请求信号,为1时有读写请求,为1时无读写请求 |
| inst_sram_wr | 1 | O | 为1表示该次是写请求,为0表示该次是读请求 |
| inst_sram_size | 2 | O | 该次请求传输的字节数,0:1byte,1:2bytes,2:4bytes |
| inst_sram_wstrb | 4 | O | 该次写请求的字节写使能 |
| inst_sram_addr | 32 | O | 该次请求的地址 |
| inst_sram_wdata | 32 | O | 该次写请求的写数据 |
| inst_sram_addr_ok | 1 | I | 该次写请求的地址传输OK,读:地址被接收;写:地址和数据被接收 |
| inst_sram_data_ok | 1 | I | 该次请求的数据传输OK,读:数据返回;写:数据写入完成 |
| inst_sram_rdata | 32 | I | 该次写请求返回的读数据 |
| 与TLB | |||
| if_s0_vpn2 | 19 | O | tlb: s0_vpn2 |
| if_s0_odd_page | 1 | O | tlb: s0_odd_pagd |
| if_s0_asid | 8 | O | tlb: s0_asid |
| if_s0_found | 1 | I | tlb: s0_found |
| if_s0_index | $clog2(`TLBNUM) | I | tlb: s0_index |
| if_s0_pfn | 20 | I | tlb: s0_pfn |
| if_s0_c | 3 | I | tlb: s0_c |
| if_s0_d | 1 | I | tlb: s0_d |
| if_s0_v | 1 | I | tlb: s0_v |
| 与ID | |||
| id_to_if_allowin | 1 | I | pipe allowin |
| if_to_id_vld | 1 | O | pipe valid |
| if_to_id_data | 64 | O | pipe data(instruction 32-bits, pc 32-bits) |
| jump_bus | 33 | I | branch instructions(enable 1bit,address 32-bits) |
| if_to_id_flush | 1 | O | IF传给ID的数据部分清零(PC不清零) |
| id_tlb_exc | 1 | I | ID阶段的tlb 例外 |
| 与EXE | |||
| exe_tlb_flush | 1 | I | EXE阶段检测到的tlb_flush使能信号 |
| exe_inst_tlb_exc | 1 | I | EXE阶段的tlb 例外(为什么不叫exe_tlb_exc呢,是为了与EXE阶段检测到读/写SRAM时检测到的tlb_exc区别开) |
| 与MEM | |||
| mem_tlb_flush | 1 | I | MEM阶段检测到的tlb_flush使能信号 |
| mem_tlb_exc | 1 | I | MEM阶段的tlb 例外 |
| 与WB | |||
| wb_jump_en | 1 | I | 检测到EXC,然后决定是否jump |
| wb_jump_pc | 32 | I | 检测到EXC,jump的PC值 |
| wb_exc_flush | 1 | I | WB阶段检测到EXC,对流水线清空 |
| wb_tlb_flush | 1 | I | WB阶段检测到的tlb_flush使能信号 |
接口时序
ID.v
接口信号
| 名称 | 宽度 | 方向 | 描述 |
|---|---|---|---|
| 时钟与复位 | |||
| clk | 1 | I | 时钟信号,来自clk_pll的输出时钟 |
| resetn | 1 | I | 复位信号,低电平同步复位 |
| 与TOP | |||
| inst_sram_en | 1 | O | RAM使能信号,高电平有效 |
| inst_sram_wen | 4 | O | RAM字节写使能信号,高电平有效 |
| inst_sram_addr | 32 | O | RMA读写地址,字节寻址 |
| inst_sram_wdata | 32 | O | RAM写数据 |
| inst_sram_rdata | 32 | I | RAM读数据 |
| 与IF | |||
| id_to_if_allowin | 1 | I | pipe allowin |
| if_to_id_vld | 1 | O | pipe valid |
| if_to_id_data | 64 | O | pipe data(instruction 32-bits, pc 32-bits) |
| jump_bus | 33 | I | branch instructions(enable 1bit,address 32-bits) |
| if_to_id_flush | 1 | I | IF传给ID的数据部分清零(PC不清零) |
| id_tlb_exc | 1 | O | ID阶段的tlb 例外 |
| 与EXE | |||
| exe_to_id_allowin | 1 | I | pipe allowin |
| id_to_exe_vld | 1 | O | pipe valid |
| id_to_exe_data | 179 | O | {alu_op:21, shamt_is_shamt:1, imm_zero_ext_en:1, ins_R:1, ins_I:1, imm:16, mem_rd:1, mem_we:1, rf_we:1, rf_dst_addr:5, rt_data:32, rs_sfr_data_2:32, pc:32} {id_exc_bus:16, alu_op:21, shamt_is_shamt:1, imm_zero_ext_en:1, ins_R:1, ins_I:1, imm:16, lwx_bus_less2:10, swx_bus:8, rf_we:4, rf_dst_addr:5, rt_data:32, rs_sfr_data_2:32, pc:32} |
| exe_bypass_bus | 38 | I | {exe_rf_we:1, exe_rf_dst_addr:5, exe_rf_data:32} |
| exe_to_id_sfr_bus | 76 | I | [75] exe_sfr_we1 [74:70] exe_sfr_w_addr1 [69:38] exe_sfr_data1 [37] exe_sfr_we2 [36:32] exe_sfr_w_addr2 [31:0] exe_sfr_data2 |
| lwx_bus_less2 将其合并至id_to_exe_data中 | 10 | O | lwx类总线: ins_lb: 1, ins_lbu: 1, ins_lh: 1, ins_lhu: 1, ins_lwl: 1, ins_lwr: 1, ins_lw: 1, rs_low2: 2 mem_rd: 1 |
| swx_bus 将其合并至id_to_exe_data中 | 8 | O | swx类总线: ins_sb: 1, ins_sh: 1, ins_swl: 1, ins_swr: 1, mem_we[3:0]: 4 |
| mul_div_busy | 1 | I | 正在进行乘法或除法运算 |
| exe_ins_mfc0 | 1 | I | 指令mfc0传递至EXE阶段 |
| exe_ins_lwx | 1 | I | lwx类指令传递至EXE阶段 |
| exe_tlb_flush | 1 | I | EXE阶段检测到的tlb_flush使能信号 |
| 与MEM | |||
| mem_bypass_bus | 38 | I | {mem_rf_we:1, mem_rf_dst_addr:5, mem_rf_data:32} |
| mem_ins_mfc0 | 1 | I | 指令mfc0传递至MEM阶段 |
| mem_stall_en | 1 | I | MEM阶段的stall |
| mem_tlb_flush | 1 | I | MEM阶段检测到的tlb_flush使能信号 |
| 与WB | |||
| wb_to_rf_bus | 41 | I | {rf_we:4, rf_addr:5, rf_data:32} |
| wb_exc_flush | 1 | I | WB阶段检测到EXC,对流水线清空 |
| wb_c0_has_int | 1 | I | WB阶段的SSR检测到中断 |
| wb_ins_mfc0 | 1 | I | 指令mfc0传递至WB阶段 |
| wb_tlb_flush | 1 | I | WB阶段检测到的tlb_flush使能信号 |
接口信号(RF.v)
| 名称 | 宽度 | 方向 | 描述 |
|---|---|---|---|
| 时钟与复位 | |||
| clk | 1 | I | 时钟信号,来自clk_pll的输出时钟 |
| 与ID内部信号 | |||
| rf_r_addr1 | 5 | I | RF读地址1 |
| rf_r_data1 | 32 | O | RF读数据1 |
| rf_r_addr2 | 5 | I | RF读地址2 |
| rf_r_data2 | 32 | O | RF读数据2 |
| rf_wen1 | 4 | I | RF写使能1 |
| rf_w_addr1 | 5 | I | RF写地址1 |
| rf_w_data1 | 32 | O | RF写数据1 |
接口信号(SFR)
当写入同一地址时,以sfr_we_1优先

——lab10_Opt~lab17&spm=1001.2101.3001.5002&articleId=139319721&d=1&t=3&u=5de7208ab9284ec5ab13b8016126238f)
1万+

被折叠的 条评论
为什么被折叠?



