该项目是为32位流水线提供fun88英超代码 MIPS处理器。在 part 2,我介绍了单周期MIPS数据路径的所有VeriLog代码。
在这部分中,添加了流水线寄存器以完成 流水线MIPS处理器. verilog. 将呈现完整的32位流水线MIP处理器的代码。
以下是32位5级流水线的完整数据路径 MIPS处理器 添加流水线寄存器后, 转发 单位,摊位控制单元和冲洗控制单元到单循环数据路径。转发,失速控制和冲洗控制单元旨在解决流水线MIPS处理器中的数据和控制危险。以下是危险求解模块和fun88英超中的完整流水线MIPS处理器的详细说明。
![]() |
流水线MIPS处理器DataPath |
转发单位:
转发单元旨在解决流水线MIPS处理器中的数据危险。当检测到数据危险时,ALU输出端的正确数据被转发到ALU的输入。当前指令的源寄存器(ex_rs或ex_rt)与前一个指令的目标寄存器(MEM_WRITEREGISTER或EX_WRITERGISTER)相同时检测到数据危险。

转发单元的fun88英超代码:
`timescale 1 ps / 100 fs // yl315.net: FPGA projects, fun88英超 Projects, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // Forwarding Unit module ForwardingUnit(ForwardA,ForwardB,MEM_RegWrite,WB_RegWrite,MEM_WriteRegister,WB_WriteRegister,EX_rs,EX_rt); output [1:0] ForwardA,ForwardB; wire [1:0] ForwardA,ForwardB; input MEM_RegWrite,WB_RegWrite; input [4:0] MEM_WriteRegister,WB_WriteRegister,EX_rs,EX_rt; // a= 1 if ( MEM_WriteRegister != 0 ) or #(50) orMEM_WriteReg(a,MEM_WriteRegister[4],MEM_WriteRegister[3],MEM_WriteRegister[2],MEM_WriteRegister[1],MEM_WriteRegister[0]); CompareAddress CompMEM_WriteReg_EXrs(b,MEM_WriteRegister,EX_rs); and #(50) andx(x,MEM_RegWrite,a,b); // x=1 if ((MEM_RegWrite==1)&&(MEM_WriteRegister != 0)&&(MEM_WriteRegister==EX_rs)) // c= 1 if ( WB_WriteRegister != 0 ) or #(50) orWB_WriteReg(c,WB_WriteRegister[4],WB_WriteRegister[3],WB_WriteRegister[2],WB_WriteRegister[1],WB_WriteRegister[0]); CompareAddress CompWB_WriteReg_EXrs(d,WB_WriteRegister,EX_rs); and #(50) andy(y,WB_RegWrite,c,d); // y=1 if ((WB_RegWrite==1)&&(WB_WriteRegister != 0)&&(WB_WriteRegister==EX_rs)) // ForwardA[1] = x; va ForwardA[0] = (NOT x). y ; assign ForwardA[1] = x; not #(50) notxgate(notx,x); and #(50) NOTxANDy(ForwardA[0],notx,y); // ForwardB CompareAddress CompMEM_WriteReg_EXrt(b1,MEM_WriteRegister,EX_rt); CompareAddress CompWB_WriteReg_EXrt(d1,WB_WriteRegister,EX_rt); and #(50) andx1(x1,MEM_RegWrite,a,b1); and #(50) andy1(y1,WB_RegWrite,c,d1); assign ForwardB[1] = x1; not #(50) notx1gate(notx1,x1); and #(50) NOTx1ANDy1(ForwardB[0],notx1,y1); endmodule
添加转发单元以解决数据危险后,ALU输入的2×32到32多路复用器变为3x32至32多路复用器。
verilog.代码为多路复用器:
`timescale 1 ps / 100 fs // yl315.net: FPGA projects, fun88英超 Projects, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // mux3x32to32 module mux3x32to32(DataOut,A,B,C,Select); output [31:0] DataOut; input [1:0] Select; input [31:0] A,B,C; wire [31:0] DataOut1,DataOut2; mux2x32to32 muxAB(DataOut1,A,B, Select[1]); mux2x32to32 muxCA(DataOut2,C,A, Select[1]); mux2x32to32 muxABC(DataOut,DataOut1,DataOut2, Select[0]); endmodule
接下来,在发生数据危险时,需要停止控制单元,并且需要在转发前延迟1个周期。
摊位控制单元:
当当前读取存储器指令的目标寄存器(EX_RT)时,需要停滞1周期的数据危险 is the same as the XORI和LW指令ID_RT的ID阶段的即将到来的指令的源寄存器(ID_RS或ID_RT)(其中RT是目的地寄存器与XORI和LW的源寄存器)。


verilog. Code for Stall控制单元:
`timescale 1 ps / 100 fs // yl315.net: FPGA projects, verilog.项目, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // Stall Control module StallControl(PC_WriteEn,IFID_WriteEn,Stall_flush,EX_MemRead,EX_rt,ID_rs,ID_rt,ID_Op); output PC_WriteEn,IFID_WriteEn,Stall_flush; wire PC_WriteEn,IFID_WriteEn,Stall_flush; input EX_MemRead,EX_rt,ID_rs,ID_rt; input [5:0] ID_Op; wire [4:0] EX_rt,ID_rs,ID_rt,xorRsRt,xorRtRt; wire [5:0] xoropcodelw,xoropcodexori; wire EX_MemRead; //wire xoropcode1,xoroprt; // write in behavior model /*always @(EX_MemRead or EX_rt or ID_rs or ID_rt) begin if ((EX_MemRead==1)&&((EX_rt==ID_rs)||((EX_rt==ID_rt)&&(Opcode!= 6'b001110)&&(Opcode!= 6'b100011))) begin PC_WriteEn=1'b0; IFID_WriteEn=1'b0; Stall_flush =1'b1; end else begin PC_WriteEn=1'b1; IFID_WriteEn=1'b1; Stall_flush =1'b0; end end */ // write in structural model xor #(50) xorRsRt4(xorRsRt[4],EX_rt[4],ID_rs[4]); xor #(50) xorRsRt3(xorRsRt[3],EX_rt[3],ID_rs[3]); xor #(50) xorRsRt2(xorRsRt[2],EX_rt[2],ID_rs[2]); xor #(50) xorRsRt1(xorRsRt[1],EX_rt[1],ID_rs[1]); xor #(50) xorRsRt0(xorRsRt[0],EX_rt[0],ID_rs[0]); or #(50) OrRsRt1(OrRsRt,xorRsRt[4],xorRsRt[3],xorRsRt[2],xorRsRt[1],xorRsRt[0]); not #(50) notgate1(notOrRsRt,OrRsRt); // neu EX_rt==ID_rs thi notOrRsRt = 1 xor #(50) xorRtRt4(xorRtRt[4],EX_rt[4],ID_rt[4]); xor #(50) xorRtRt3(xorRtRt[3],EX_rt[3],ID_rt[3]); xor #(50) xorRtRt2(xorRtRt[2],EX_rt[2],ID_rt[2]); xor #(50) xorRtRt1(xorRtRt[1],EX_rt[1],ID_rt[1]); xor #(50) xorRtRt0(xorRtRt[0],EX_rt[0],ID_rt[0]); or #(50) OrRtRt1(OrRtRt,xorRtRt[4],xorRtRt[3],xorRtRt[2],xorRtRt[1],xorRtRt[0]); not #(50) notgate2(notOrRtRt,OrRtRt); // neu EX_rt==ID_rt thi notOrRtRt = 1 xor #(50) xoropcode5(xoropcodelw[5],ID_Op[5],1'b1); xor #(50) xoropcode4(xoropcodelw[4],ID_Op[4],1'b0); xor #(50) xoropcode3(xoropcodelw[3],ID_Op[3],1'b0); xor #(50) xoropcode2(xoropcodelw[2],ID_Op[2],1'b0); xor #(50) xoropcode1(xoropcodelw[1],ID_Op[1],1'b1); xor #(50) xoropcode0(xoropcodelw[0],ID_Op[0],1'b1); or #(50) oropcode1(ec1,xoropcodelw[5],xoropcodelw[4],xoropcodelw[3],xoropcodelw[2],xoropcodelw[1],xoropcodelw[0]); // opcode != opcode[lw] xoropcodelw =1 xor #(50) xoropcod5(xoropcodexori[5],ID_Op[5],1'b0); xor #(50) xoropcod4(xoropcodexori[4],ID_Op[4],1'b0); xor #(50) xoropcod3(xoropcodexori[3],ID_Op[3],1'b1); xor #(50) xoropcod2(xoropcodexori[2],ID_Op[2],1'b1); xor #(50) xoropcod1(xoropcodexori[1],ID_Op[1],1'b1); xor #(50) xoropcod0(xoropcodexori[0],ID_Op[0],1'b0); or #(50) oropcode2(ec2,xoropcodexori[5],xoropcodexori[4],xoropcodexori[3],xoropcodexori[2],xoropcodexori[1],xoropcodexori[0]); // opcode != opcode[xori] xoropcodexori =1 and #(50) and1(xorop,ec1,ec2); and #(50) and2(xoroprt,xorop,notOrRtRt); or #(50) OrEXIDRsRt(OrOut,notOrRsRt,xoroprt); and #(50) AndCondition(Condition,EX_MemRead,OrOut); // Condition =1 when stall is satisfied not #(50) NotPC_WriteEn(PC_WriteEn,Condition); not #(50) NotIFID_WriteEn(IFID_WriteEn,Condition); buf #(50) bufStallflush(Stall_flush,Condition); endmodule
冲洗控制单元:
冲洗控制单元旨在解决控制危害,当跳转指令(J,JR或BNE)执行时,它会丢弃IF和ID阶段中的指令。
Flush控制单元的fun88英超代码:
// yl315.net: FPGA projects, fun88英超 Projects, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // Flush control signals `timescale 1 ps / 100 fs module flush_block( ID_RegDst,ID_ALUSrc, ID_MemtoReg,ID_RegWrite,ID_MemRead,ID_MemWrite, ID_Branch,ID_ALUOp,ID_JRControl,flush,RegDst,ALUSrc,MemtoReg,RegWrite, MemRead,MemWrite,Branch,ALUOp,JRControl); output ID_RegDst,ID_ALUSrc,ID_MemtoReg,ID_RegWrite,ID_MemRead,ID_MemWrite,ID_Branch,ID_JRControl; output [1:0] ID_ALUOp; input flush,RegDst,ALUSrc,MemtoReg,RegWrite,MemRead,MemWrite,Branch,JRControl; input [1:0] ALUOp; not #50 (notflush,flush); and #50 and1(ID_RegDst,RegDst,notflush); and #50 and2(ID_ALUSrc,ALUSrc,notflush); and #50 and3(ID_MemtoReg,MemtoReg,notflush); and #50 and4(ID_RegWrite,RegWrite,notflush); and #50 and5(ID_MemRead,MemRead,notflush); and #50 and6(ID_MemWrite,MemWrite,notflush); and #50 and7(ID_Branch,Branch,notflush); and #50 and8(ID_JRControl,JRControl,notflush); and #50 and9(ID_ALUOp[1],ALUOp[1],notflush); and #50 and10(ID_ALUOp[0],ALUOp[0],notflush); endmodule `timescale 1 ps / 100 fs // yl315.net: FPGA projects, fun88英超 Projects, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // Discard instructions when needed module Discard_Instr(ID_flush,IF_flush,jump,bne,jr); output ID_flush,IF_flush; input jump,bne,jr; or #50 OR1(IF_flush,jump,bne,jr); or #50 OR2(ID_flush,bne,jr); endmodule
在同一地址写入和读取时,另一个危险可能会发生在写回阶段。读数数据可能不是正确的写入数据。要解决此问题,WB_Forward单元旨在将正确的写入数据转发到输出 data.

WB_Forward单元的fun88英超代码:
`timescale 1 ps / 100 fs // yl315.net: FPGA projects, fun88英超 Projects, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // Write Back Forwarding module WB_forward(ReadData1Out,ReadData2Out,ReadData1,ReadData2,rs,rt,WriteRegister,WriteData,RegWrite); // WB Hazard: Reading data while writing // Solve Hazard at the WriteBack Stage output [31:0] ReadData1Out,ReadData2Out; input [31:0] ReadData1,ReadData2,WriteData; input [4:0] rs,rt,WriteRegister; input RegWrite; wire ReadSourceRs,ReadSourceRt; wire compOut1,compOut2; // behavior model /* always @(rs or rt or WriteRegister or WriteData or RegWrite) begin if ((RegWrite==1)&&(WriteRegister != 0)&&(WriteRegister==rs)) ReadSourceRs = 1'b1; //Forwarding WriteData to ReadData1 else ReadSourceRs = 1'b0; if ((RegWrite==1)&&(WriteRegister != 0)&&(WriteRegister==rt)) ReadSourceRt = 1'b1; //Forwarding WriteData to ReadData2 else ReadSourceRt = 1'b0; end */ // Structural model or #(50) orWriteReg(orOut1,WriteRegister[4],WriteRegister[3],WriteRegister[2],WriteRegister[1],WriteRegister[0]); CompareAddress Compare1(compOut1,WriteRegister,rs); and #(50) andCondition1(ReadSourceRs,RegWrite,orOut1,compOut1); CompareAddress Compare2(compOut2,WriteRegister,rt); and #(50) andCondition2(ReadSourceRt,RegWrite,orOut1,compOut2); mux2x32to32 muxReadData1( ReadData1Out,ReadData1,WriteData, ReadSourceRs); mux2x32to32 muxReadData2( ReadData2Out,ReadData2,WriteData, ReadSourceRt); endmodule `timescale 1 ps / 100 fs module CompareAddress(equal,Addr1,Addr2); // yl315.net: FPGA projects, fun88英超 Projects, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // Compare Address output equal; wire equal; input [4:0] Addr1,Addr2; wire [4:0] Addr1,Addr2,xorAddress; xor #(50) xorAddress4(xorAddress[4],Addr1[4],Addr2[4]); xor #(50) xorAddress3(xorAddress[3],Addr1[3],Addr2[3]); xor #(50) xorAddress2(xorAddress[2],Addr1[2],Addr2[2]); xor #(50) xorAddress1(xorAddress[1],Addr1[1],Addr2[1]); xor #(50) xorAddress0(xorAddress[0],Addr1[0],Addr2[0]); or #(50) Orgate1(OrAddr,xorAddress[4],xorAddress[3],xorAddress[2],xorAddress[1],xorAddress[0]); not #(50) notgate1(equal,OrAddr); endmodule
现在,我们完成了整个32位流水线MIPS处理器的所有必要部分的fun88英超代码。
让我们来获取32位管道MIPS处理器的顶级fun88英超代码:
`timescale 1 ps / 100 fs // yl315.net: FPGA projects, verilog.项目, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // Top level fun88英超 code for 32-bit 5-stage Pipelined MIPS Processor module MIPSpipeline(clk, reset); input clk, reset; wire [31:0] PC, PCin; wire [31:0] PC4,ID_PC4,EX_PC4; wire [31:0] PCbne,PC4bne,PCj,PC4bnej,PCjr; // PC signals in MUX wire [31:0] Instruction,ID_Instruction,EX_Instruction; // Output of Instruction Memory wire [5:0] Opcode,Function; // Opcode, Function // Extend wire [15:0] imm16; // immediate in I type instruction wire [31:0] Im16_Ext,EX_Im16_Ext; wire [31:0] sign_ext_out,zero_ext_out; // regfile wire [4:0] rs,rt,rd,EX_rs,EX_rt,EX_rd,EX_WriteRegister,MEM_WriteRegister,WB_WriteRegister; wire [31:0] WB_WriteData, ReadData1, ReadData2,ReadData1Out,ReadData2Out, EX_ReadData1, EX_ReadData2; // ALU wire [31:0] Bus_A_ALU,Bus_B_ALU,Bus_B_forwarded; wire [31:0] EX_ALUResult,MEM_ALUResult,WB_ALUResult; wire ZeroFlag, OverflowFlag, CarryFlag, NegativeFlag,notZeroFlag; wire [31:0] WriteDataOfMem,MEM_ReadDataOfMem,WB_ReadDataOfMem; //Control signals wire RegDst,ALUSrc,MemtoReg,RegWrite,MemRead,MemWrite,Branch,Jump,SignZero,JRControl; wire ID_RegDst,ID_ALUSrc,ID_MemtoReg,ID_RegWrite,ID_MemRead,ID_MemWrite,ID_Branch,ID_JRControl; wire EX_RegDst,EX_ALUSrc,EX_MemtoReg,EX_RegWrite,EX_MemRead,EX_MemWrite,EX_Branch,EX_JRControl; wire MEM_MemtoReg,MEM_RegWrite,MEM_MemRead,MEM_MemWrite; wire WB_MemtoReg,WB_RegWrite; wire [1:0] ALUOp,ID_ALUOp,EX_ALUOp; wire [1:0] ALUControl; wire bneControl,notbneControl; wire JumpControl,JumpFlush; wire [1:0] ForwardA,ForwardB; //flush wire IF_flush,IFID_flush,notIFID_flush,Stall_flush,flush; //shift left wire [31:0] shiftleft2_bne_out,shiftleft2_jump_out; // shift left output // PC Write Enable, IF/ID Write Enable wire PC_WriteEn,IFID_WriteEn; //====== PC register====== register PC_Reg(PC,PCin,PC_WriteEn,reset,clk); Add Add1(PC4,PC,{29'b0,3'b100}); // PC4 = PC + 4 InstructionMem InstructionMem1(Instruction, PC); // register IF/ID register IFID_PC4(ID_PC4,PC4,IFID_WriteEn,reset,clk); register IFID_Instruction(ID_Instruction,Instruction,IFID_WriteEn,reset,clk); RegBit IF_flush_bit(IFID_flush,IF_flush, IFID_WriteEn,reset, clk); //========= ID STAGE=========== assign Opcode = ID_Instruction[31:26]; assign Function = ID_Instruction[5:0]; assign rs = ID_Instruction[25:21]; assign rt = ID_Instruction[20:16]; assign rd = ID_Instruction[15:11]; assign imm16= ID_Instruction[15:0]; // Main Control Control MainControl( RegDst, ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, Branch, ALUOp, Jump, SignZero, Opcode ); // Regfile regfile Register_File( ReadData1, ReadData2, WB_WriteData, rs, rt, WB_WriteRegister, WB_RegWrite, reset, clk); // forward Read Data if Write and Read at the same time WB_forward WB_forward_block(ReadData1Out,ReadData2Out,ReadData1,ReadData2,rs,rt,WB_WriteRegister,WB_WriteData,WB_RegWrite); // Sign-extend sign_extend sign_extend1(sign_ext_out,imm16); // Zero-extend zero_extend zero_extend1(zero_ext_out,imm16); // immediate extend: sign or zero mux2x32to32 muxSignZero( Im16_Ext,sign_ext_out,zero_ext_out, SignZero); JRControl_Block JRControl_Block1( JRControl, ALUOp, Function); Discard_Instr Discard_Instr_Block(ID_flush,IF_flush,JumpControl,bneControl,EX_JRControl); or #(50) OR_flush(flush,ID_flush,IFID_flush,Stall_flush); flush_block flush_block1(ID_RegDst,ID_ALUSrc,ID_MemtoReg,ID_RegWrite,ID_MemRead,ID_MemWrite,ID_Branch,ID_ALUOp, ID_JRControl,flush,RegDst,ALUSrc,MemtoReg,RegWrite,MemRead,MemWrite,Branch,ALUOp,JRControl); //==========EX STAGE========================= // thanh ghi ID/EX register IDEX_PC4(EX_PC4,ID_PC4,1'b1,reset,clk); register IDEX_ReadData1(EX_ReadData1,ReadData1Out,1'b1,reset,clk); register IDEX_ReadData2(EX_ReadData2,ReadData2Out,1'b1,reset,clk); register IDEX_Im16_Ext(EX_Im16_Ext,Im16_Ext,1'b1,reset,clk); register IDEX_rs_rt_rd(EX_Instruction[31:0],ID_Instruction,1'b1,reset,clk); assign EX_rs = EX_Instruction[25:21]; assign EX_rt = EX_Instruction[20:16]; assign EX_rd = EX_Instruction[15:11]; // 9 control signals via ID/EX RegBit IDEX_RegDst(EX_RegDst, ID_RegDst, 1'b1,reset, clk); RegBit IDEX_ALUSrc(EX_ALUSrc, ID_ALUSrc, 1'b1,reset, clk); RegBit IDEX_MemtoReg(EX_MemtoReg, ID_MemtoReg, 1'b1,reset, clk); RegBit IDEX_RegWrite(EX_RegWrite, ID_RegWrite, 1'b1,reset, clk); RegBit IDEX_MemRead(EX_MemRead, ID_MemRead, 1'b1,reset, clk); RegBit IDEX_MemWrite(EX_MemWrite, ID_MemWrite, 1'b1,reset, clk); RegBit IDEX_Branch(EX_Branch, ID_Branch, 1'b1,reset, clk); RegBit IDEX_JRControl(EX_JRControl, ID_JRControl, 1'b1,reset, clk); RegBit IDEX_ALUOp1(EX_ALUOp[1], ID_ALUOp[1], 1'b1,reset, clk); RegBit IDEX_ALUOp0(EX_ALUOp[0], ID_ALUOp[0], 1'b1,reset, clk); // Forwarding unit转发Unit Forwarding_Block(ForwardA,ForwardB,MEM_RegWrite,WB_RegWrite,MEM_WriteRegister,WB_WriteRegister,EX_rs,EX_rt); // mux 3 x32 to 32 to choose source of ALU (forwarding) mux3x32to32 mux3A(Bus_A_ALU,EX_ReadData1,MEM_ALUResult,WB_WriteData,ForwardA); mux3x32to32 mux3B(Bus_B_forwarded,EX_ReadData2,MEM_ALUResult,WB_WriteData,ForwardB); // mux 2x32 to 32 to select source Bus B of ALU mux2x32to32 muxALUSrc( Bus_B_ALU,Bus_B_forwarded,EX_Im16_Ext, EX_ALUSrc); // ALU Control ALUControl_Block ALUControl_Block1( ALUControl, EX_ALUOp, EX_Im16_Ext[5:0]); // EX_Im16_Ext[5:0] is function // ALU alu alu_block(EX_ALUResult, CarryFlag, ZeroFlag, OverflowFlag, NegativeFlag, Bus_A_ALU, Bus_B_ALU, ALUControl); // mux 2x5 to 5 choose shift register is Rd or Rt mux2x5to5 muxRegDst( EX_WriteRegister,EX_rt,EX_rd, EX_RegDst); //==============MEM STAGE================= // register EX/MEM register EXMEM_ALUResult(MEM_ALUResult,EX_ALUResult,1'b1,reset,clk); register EXMEM_WriteDataOfMem(WriteDataOfMem, Bus_B_forwarded,1'b1,reset,clk); RegBit EXMEM_MemtoReg(MEM_MemtoReg, EX_MemtoReg, 1'b1,reset, clk); RegBit EXMEM_RegWrite(MEM_RegWrite, EX_RegWrite, 1'b1,reset, clk); RegBit EXMEM_MemRead(MEM_MemRead, EX_MemRead, 1'b1,reset, clk); RegBit EXMEM_MemWrite(MEM_MemWrite, EX_MemWrite, 1'b1,reset, clk); RegBit EXMEM_WriteRegister4(MEM_WriteRegister[4], EX_WriteRegister[4], 1'b1,reset, clk); RegBit EXMEM_WriteRegister3(MEM_WriteRegister[3], EX_WriteRegister[3], 1'b1,reset, clk); RegBit EXMEM_WriteRegister2(MEM_WriteRegister[2], EX_WriteRegister[2], 1'b1,reset, clk); RegBit EXMEM_WriteRegister1(MEM_WriteRegister[1], EX_WriteRegister[1], 1'b1,reset, clk); RegBit EXMEM_WriteRegister0(MEM_WriteRegister[0], EX_WriteRegister[0], 1'b1,reset, clk); // Data Memory dataMem dataMem1(MEM_ReadDataOfMem, //data MEM_ALUResult, //address WriteDataOfMem, //writedata MEM_MemWrite, //writeenable MEM_MemRead, clk); //==========WB STAGE==================== // register MEM/WB register MEMWB_ReadDataOfMem(WB_ReadDataOfMem,MEM_ReadDataOfMem,1'b1,reset,clk); register MEMWB_ALUResult(WB_ALUResult,MEM_ALUResult,1'b1,reset,clk); RegBit MEMWB_WriteRegister4(WB_WriteRegister[4], MEM_WriteRegister[4], 1'b1,reset, clk); RegBit MEMWB_WriteRegister3(WB_WriteRegister[3], MEM_WriteRegister[3], 1'b1,reset, clk); RegBit MEMWB_WriteRegister2(WB_WriteRegister[2], MEM_WriteRegister[2], 1'b1,reset, clk); RegBit MEMWB_WriteRegister1(WB_WriteRegister[1], MEM_WriteRegister[1], 1'b1,reset, clk); RegBit MEMWB_WriteRegister0(WB_WriteRegister[0], MEM_WriteRegister[0], 1'b1,reset, clk); RegBit MEMWB_MemtoReg(WB_MemtoReg, MEM_MemtoReg, 1'b1,reset, clk); RegBit MEMWB_RegWrite(WB_RegWrite, MEM_RegWrite, 1'b1,reset, clk); // Select Data to WriteData for regfile mux2x32to32 muxMemtoReg( WB_WriteData, WB_ALUResult, WB_ReadDataOfMem,WB_MemtoReg); //Stalling StallControl StallControl_block(PC_WriteEn,IFID_WriteEn,Stall_flush,EX_MemRead,EX_rt,rs,rt,Opcode); //Jump,bne, JRs // bne: Branch if not equal shift_left_2 shiftleft2_bne(shiftleft2_bne_out, EX_Im16_Ext); Add Add_bne(PCbne,EX_PC4,shiftleft2_bne_out); not #(50) notZero(notZeroFlag,ZeroFlag); and #(50) andbneControl(bneControl,EX_Branch,notZeroFlag); mux2x32to32 muxbneControl( PC4bne,PC4, PCbne, bneControl); // jump shift_left_2 shiftleft2_jump(shiftleft2_jump_out, {6'b0,ID_Instruction[25:0]}); assign PCj = {ID_PC4[31:28],shiftleft2_jump_out[27:0]}; not #(50) notIFIDFlush(notIFID_flush,IFID_flush); and #(50) andJumpFlush(JumpFlush,Jump,notIFID_flush); not #(50) notbne(notbneControl,bneControl); and #(50) andJumpBNE(JumpControl,JumpFlush,notbneControl); mux2x32to32 muxJump( PC4bnej,PC4bne, PCj, JumpControl); // JR: Jump Register assign PCjr = Bus_A_ALU; mux2x32to32 muxJR( PCin,PC4bnej, PCjr, EX_JRControl); endmodule
verilog. TestBench代码为32位管道MIPS处理器:
`timescale 1 ps / 100 fs module MIPSStimulus(); // yl315.net: FPGA projects, fun88英超 Projects, VHDL projects // fun88英超 project: 32-bit 5-stage Pipelined MIPS Processor in fun88英超 // Testbench fun88英超 code for 32-bit 5-stage Pipelined MIPS Processor parameter ClockDelay = 5000; reg clk,reset; MIPSpipeline myMIPS(clk, reset); initial clk = 0; always #(ClockDelay/2) clk = ~clk; initial begin reset = 1; #(ClockDelay/4); reset = 0; end endmodule
为了验证流水线MIPS处理器的操作,我创建了一段指令,包括所有数据和控制危险。如下图所示,将说明添加到指令存储器中,然后在ModelSIM中运行仿真。

注意,指令需要转换为二进制数据并保存在其中"instr.txt..."文件。 I converted the above sample instructions into binary data and provided in part 1.
之后,只需在ModelSIM中运行模拟,并检查模拟波形和内存编辑器。以下是24个时钟周期中的正确仿真波形。
![]() |
用于前12个循环的仿真波形 |
![]() |
用于接下来的12个周期的仿真波形 |
如果您对模拟有任何混淆或困难,请留下评论。
有人指出,您需要通过所有必要的部分( Part 1, Part 2, 和 Part 3)为了充分了解设计流水线MIP处理器的过程,并收集所有所需的fun88英超代码,以便能够在仿真中运行流水线MIPS处理器。
你可能喜欢这个:微控制器的fun88英超代码
VHDL中的完整8位微控制器
verilog.中的单周期MIPS处理器
16位RISC处理器的fun88英超代码
MIPS处理器的VHDL代码
什么是fpga编程? FPGA VS软件编程
推荐和经济实惠的学生Xilinx FPGA板
推荐和负担得起的Altera FPGA董事会为学生
推荐的 fun88英超 projects:
2. FIFO记忆的fun88英超代码
3. 16位单循环MIPS处理器的fun88英超代码
4. verilog. HDL中的可编程数字延迟计时器
5. 数字电路中基本逻辑组件的fun88英超代码
6. 32位无符号分频器的fun88英超代码
7. 用于固定点矩阵乘法的fun88英超代码
8. 在fun88英超 HDL中的板牌识别
9. 携带外观前方乘法器的fun88英超代码
10。 微控制器的fun88英超代码
11. 4x4乘法器的fun88英超代码
12. 停车系统的fun88英超代码
13。 使用fun88英超 HDL对FPGA的图像处理
14。 如何使用fun88英超 HDL将文本文件加载到FPGA中
15。 交通灯控制器的fun88英超代码
16。 FPGA闹钟的fun88英超代码
17。 比较器设计的fun88英超代码
18。 VERILOG代码D触发器
19。 完整加法器的fun88英超代码
20。 与测试台的计数器的fun88英超代码
21。 16位RISC处理器的fun88英超代码
22。 FPGA上的按钮的fun88英超代码
23。 如何为双向/ inout端口编写fun88英超 TestBench
3. 16位单循环MIPS处理器的fun88英超代码
4. verilog. HDL中的可编程数字延迟计时器
5. 数字电路中基本逻辑组件的fun88英超代码
6. 32位无符号分频器的fun88英超代码
7. 用于固定点矩阵乘法的fun88英超代码
8. 在fun88英超 HDL中的板牌识别
9. 携带外观前方乘法器的fun88英超代码
10。 微控制器的fun88英超代码
11. 4x4乘法器的fun88英超代码
12. 停车系统的fun88英超代码
13。 使用fun88英超 HDL对FPGA的图像处理
14。 如何使用fun88英超 HDL将文本文件加载到FPGA中
15。 交通灯控制器的fun88英超代码
16。 FPGA闹钟的fun88英超代码
17。 比较器设计的fun88英超代码
18。 VERILOG代码D触发器
19。 完整加法器的fun88英超代码
20。 与测试台的计数器的fun88英超代码
21。 16位RISC处理器的fun88英超代码
22。 FPGA上的按钮的fun88英超代码
23。 如何为双向/ inout端口编写fun88英超 TestBench
24。 Tic Tac Toe游戏在fun88英超和Logisim
25。 verilog.中的32位5级流水线MIPS处理器(第1部分)
26。 verilog.中的32位5级流水线MIPS处理器(Part-2)
27。 verilog.中的32位5级流水线MIPS处理器(第3部分)
25。 verilog.中的32位5级流水线MIPS处理器(第1部分)
26。 verilog.中的32位5级流水线MIPS处理器(Part-2)
27。 verilog.中的32位5级流水线MIPS处理器(第3部分)
28。 解码器的fun88英超代码
29。 多路复用器的fun88英超代码
30. fun88英超中的n位加法器设计31。 verilog. vs vhdl.:通过示例解释
32。 FPGA时钟分频器的fun88英超代码
33。 如何在fun88英超中生成时钟使能信号
34。 PWM生成器的fun88英超代码
35。 verilog.编码VS软件编程
36。 使用MOORE FSM的序列检测器的fun88英超代码
注意,指令需要转换为二进制数据并保存在其中"instr.txt"
回复删除当我模拟时,ModelSim向我填充XXXXXXXXXXXXXXXXXX(不在乎)的内存,看起来像ISN'将任何东西加载到记忆中。我唐't know what I'做错了。可能不是.txt文件中的数字。也许是因为我'm打算在另一个不是测试禁止的模块中使用$ readmemb加载文件?
如果要初始化数据内存的内容,请创建"data.dat"文件并将ReadMem命令添加到数据存储器代码以初始化它。
删除运行模拟一段时间才能查看结果。确保您了解的说明"instr.txt" file.
我没有'T看到PC模块,那么那呢?
回复删除http://www.yl315.net/2017/06/32-bit-pipelined-mips-processor-in-verilog-1.html
删除它设置在流水线MIPS处理器的第1部分中。
在DatameMory模块中,我看到了$ ReadMemh("data.dat".....),所以这个目的是什么?,你能为我解释一下吗?
删除它已经评论了。它用于从.dat文件读取数据存储器,以便您要从.dat或.txt文件从.dat或.txt文件输入到数据存储器的情况下。
删除我想在这个CPU中添加异常并中断,从头开始,我应该怎么做
回复删除我想知道。你对例外或中断做了什么?你可以帮助我。谢谢
删除我的波形不一样,它只有3个条目。 CLK,RESET和CLOCKDELAY。什么's the reason?
回复删除可以为给定的程序和指令提供一些人提供数据.DAT文件格式
回复删除