发布时间 : 星期三 文章MIPS流水线CPU的verilog实现 - 图文更新完毕开始阅读c9f71522ed630b1c59eeb52e
6. 写回级WB模块的设计
WB部分非常简单,只有一个数据选择器选择写回的数据来源,可在顶层模块中直接实现。
7. 取指令级IF模块的设计
IF模块由指令指针寄存器PC、指令存储器子模块Instruction ROM、指令指针选择器MUX和一个32位加法器组成,IF级模块接口信息如下表所示: 引脚名称 clk reset Z J JR PC_IFWrite JumpAddr[31:0] JrAddr[31:0] BranchAddr[31:0] Instruction_if[31:0] NextPC_if[31:0] 方向 说 明 系统时钟 系统复位信号,高电平有效 分支指令的条件判断结果 跳转指令 Input 寄存器跳转指令 阻塞流水线的信号,低电平有效 J指令跳转地址 JR指令跳转地址 条件分支地址 指令机器 Output 下一个PC值 21
(1) 指令存储器ROM
用Xilinx CORE Generator实现产生的ROM无法满足流水线CPU的指令要求,我们需用Verilog HDL设计一个ROM阵列。考虑到FPGA的资源,指令存储器可设计为容量各为26×32bit的ROM。设计ROM时需将测试的机器码写入,课程提供一段简单测试程序的机器码,机器码存于PipelineDemo.coe文件中。
课程已提供该ROM的代码,已设计好上述测试程序机器码的指令存储器,文件名为InstructionROM.v。
需要注意的是,ROM的地址信号同RAM一样有“对齐限制”的要求,因此, ROM的地址应该接的信号是PC[7:2]。
(2) 指令指针选择器
指令指针选择器为一8选1数据选择器,选择信号为PCSource={JR,J,Z},具体含义如下表:
地址 {JR,J,Z}= 100 {JR,J,Z}= 010 {JR,J,Z}= 001 {JR,J,Z}= 000 PC来源 JR指令的跳转地址 J指令的跳转地址 Branch指令的分支地址 下一条指令地址PC+4 (3) PC寄存器
当发生数据冒险时,需要保持PC寄存器不变,因此PC寄存器是一个带使能端的D型寄存器,使能信号为PC_IFWrite。
8. 流水线寄存器的设计
流水线寄存器负责将流水线的各部分分开,共有IF/ID、ID/EX、EX/MEM、MEM/WB四组。根据前面的介绍可知,四组流水线寄存器要求不完全相同,因此设计也有不同考虑。
(1)EX/MEM、MEM/WB两组流水线寄存器只是普通D型寄存器。 (2)当流水线发生数据冒险时,需清空ID/EX流水线寄存器而插入一个气泡,因此ID/EX流水线寄存器是一个带同步清零功能的D型寄存器,清零信号为Stall。
(3)当流水线发生数据冒险时,需保持IF/ID流水线寄存器不变,因此IF/ID流水线寄存器具有使能信号输入,使能信号为PC_IFWrite;当流水线发生分支冒险时,需清空IF/ID流水线寄存器,清零信号为IF_flush。因此,IF/ID流水线寄存器是一个带使能功能、同步清零功能的D型寄存器。
需要注意的是,由于仿真对初始值的要求,上述寄存器都应考虑有reset信号的接入,以提供仿真时各寄存器的初值。
9. 顶层文件的设计
按照流水线MIPS微处理器的原理框图连接各模块即可。为方便测试,可将关键变量输出,关键变量有:指令指针PC、指令码Instruction、流水线插入气泡标志Stall、分支标志JumpFlag(即{JR,J,Z})、ALU输入输出(ALU_A、ALU_B、ALUResult)和数据存储器的输出MemDout_wb。
22
四、 实验代码
见附录二。
五、 实验设备
1. 装有ISE、ModelSim SE和ChipScope Pro软件的计算机;
2. XUP Virtex-Ⅱ Pro开发系统一套; 3. SVGA显示器一台。
六、 实验仿真结果与分析
1. ID级仿真
(1) Decode子模块的仿真
测试指令为:
Instruction = 32'h0800000b; //j later(later address is 2Ch) 跳转指令,J信号为“1”,其他控制信号为“0”。 Instruction = 32'h20080042; //addi $t0,$0,42
加立即数,ALUCode=00000,ALUScrB选择立即数即为“1”;同时它需要写回,则RegWrite信号为“1”,其他控制信号为“0”。 Instruction = 32'h01095022; //sub $t2,$t0,$t1
减法,ALUCode=00101;从寄存器中取值,ALUScrA与ALUScrB都为“0”;需要写回,则RegWrite信号为“1”;写回地址是RdAddr,RegDst=1;其他控制信号为“0”。
Instruction = 32'h01485825; //or $t3,$t2,$t0
逻辑或运算,ALUCode=00011;从寄存器中取值,ALUScrA与ALUScrB都为“0”;需要写回,则RegWrite信号为“1”;写回地址是RdAddr,RegDst=1;其他控制信号为“0”。
Instruction = 32'hac0b000c; //sw $t3,0C($0)
SW指令,MemWrite=1;它属于I型指令,ALUScrB选择立即数即为“1”;其他控制信号为“0”.
Instruction = 32'h8d2c0008; //lw $t4,08($t1)
LW指令,MemtoReg=1,Memread=1;需要写回,则RegWrite信号为“1”;它属于I型指令,ALUScrB选择立即数即为“1”;其他控制信号为“0”。 Instruction = 32'h000c4080; //sll $t0,$t4,2 移位运算指令,ALUCode=10000;ALUScrA选择位移数sa,即为“1”;需要写回,则RegWrite信号为“1”;写回地址是RdAddr,RegDst=1;其他控制信号为“0”。
Instruction = 32'h012a582b ; //sltu $t3,$t1,$t2
23
SLTU指令,ALUCode=10100;需要写回,则RegWrite信号为“1”;写回地址是RdAddr,RegDst=1;其他控制信号为“0”。
Instruction = 32'h14000001 ; //bne $0,$0,end (end address is 34h) 分支条件判断BNE指令,ALUCode=01011;其他控制信号为“0”。 Instruction = 32'h1000fff4 ; //beq $0,$0,earlier (earlier address is 4h) 分支条件判断BEQ指令,ALUCode=00010;其他控制信号为“0”.
由此判断该模块符合设计要求。
(2)ID模块仿真
测试指令仍为Decode模块的测试指令,由于已确定Decode模块设计正确,故只观察出Decode输出信号外的信号。
a) Instruction = 32'h20080042; //addi $t0,$0,42
加立即数,定义控制信号RegWrite_wb=1;RegWriteAddr_wb=5'b01000;RegWriteData_wb=32'b111。
可看到Imm=00000042已经无符号扩展,写回地址RtAddr= RegWriteAddr_wb=5'b01000,写回数据RtData= RegWriteData_wb=32'b111
b) Instruction_id = 32'h20080021; //addi $t1,$0,21
24