基于FPGA设计的MIPS指令集CPU

本文详述了一种基于FPGA的MIPS单周期指令集CPU设计过程,包括开发语言Verilog和使用Modelsim进行验证。已验证的指令包括加减运算、逻辑操作、内存访问等。通过Mars和Modelsim进行对比仿真,确保结果正确,并提供了测试代码和汇编注释。
摘要由CSDN通过智能技术生成

基于FPGA设计的MIPS指令集CPU

导读:网上已经有很多MIPS设计资料和方法,这里就开门见山的了,直接说明从设计到验证的过程。

  • 内容:支持单周期\多周期\流水线 冒泡法和字符串统计算法已经验证 本文主要是单周期、其他后面整理发布中
  • 开发语言:verilog 开发环境:modelsim
  • 已经验证以下指令
    add/sub/and/or/slt/sltu/addu/subu/addi/ori/lw/sw/beqj/jal/sll/nor/lui/slti/bne/andi/srl/sllv/srlv/jr/jalr
  • 采用对比验证方法 Mars与Modelsim对比验证
  • 仿真结果正确

对比寄存器和内存仿真图

Mars仿真结果,Mars断点
Mars仿真
在这里插入图片描述

Modelsim仿真结果,Modelsim断点,r是寄存器数据,dmem是内存数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面是MIPS各个模块代码

仿真testbench代码和汇编测试代码在最后

module sccomp(clk, rstn, reg_sel, reg_data); 
   input          clk;
   input          rstn;
   input [4:0]    reg_sel;
   output [31:0]  reg_data;
   
   wire [31:0]    instr;
   wire [31:0]    PC;
   wire           MemWrite;
   wire [31:0]    dm_addr, dm_din, dm_dout;
   
   wire rst = ~rstn;
       
  // instantiation of single-cycle CPU   
   sccpu U_SCCPU(
         .clk(clk),                 // input:  cpu clock
         .rst(rst),                 // input:  reset
         .instr(instr),             // input:  instruction
         .readdata(dm_dout),        // input:  data to cpu  
         .MemWrite(MemWrite),       // output: memory write signal
         .PC(PC),                   // output: PC
         .aluout(dm_addr),          // output: address from cpu to memory
         .writedata(dm_din),        // output: data from cpu to memory
         .reg_sel(reg_sel),         // input:  register selection
         .reg_data(reg_data)        // output: register data
         );
         
  // instantiation of data memory  
   dm    U_DM(
         .clk(clk),           // input:  cpu clock
         .DMWr(MemWrite),     // input:  ram write
         .addr(dm_addr[8:2]), // input:  ram address
         .din(dm_din),        // input:  data to ram
         .dout(dm_dout)       // output: data from ram
         );
         
  // instantiation of intruction memory (used for simulation)
   im    U_IM ( 
      .addr(PC[8:2]),     // input:  rom address
      .dout(instr)        // output: instruction
   );
        
endmodule

module sccpu( clk, rst, instr, readdata, PC, MemWrite, aluout, writedata, reg_sel, reg_data);
         
   input      clk;          // clock
   input      rst;          // reset
   
   input [31:0]  instr;     // instruction
   input [31:0]  readdata;  // data from data memory
   
   output [31:0] PC;        // PC address
   output        MemWrite;  // memory write
   output [31:0] aluout;    // ALU output
   output [31:0] writedata; // data to data memory
   
   input  [4:0] reg_sel;    // register selection (for debug use)
   output [31:0] reg_data;  // selected register data (for debug use)
   
   wire        RegWrite;    // control signal to register write
   wire        EXTOp;       // control signal to signed extension
   wire [4:0]  ALUOp;       // ALU opertion
   wire [1:0]  NPCOp;       // next PC operation

   wire [1:0]  WDSel,MDSel;       // (register) write data selection
   wire [1:0]  GPRSel;      // general purpose register selection
   
   wire        ALUSrc;      // ALU source for A
   wire        Zero;        // ALU ouput zero

   wire [31:0] NPC;         // next PC

   wire [4:0]  rs;          // rs
   wire [4:0]  rt;          // rt
   wire [4:0]  rd;          // rd
   wire [5:0]  Op;          // opcode
   wire [5:0]  Funct;       // funct
   wire [15:0] Imm16;       // 16-bit immediate
   wire [31:0] Imm32;       // 32-bit immediate
   wire [25:0] IMM;         // 26-bit immediate (address)
   wire [4:0]  A3;          // register address for write
   wire [31:0] WD;          // register write data
   wire [31:0] RD1,RD2;         // register data specified by rs
   wire [31:0] B;           // operator for ALU B
   wire [4:0]  move_s;
   wire  ShiftSlt;
   assign Op = instr[31:26];  // instruction
   assign Funct = instr[5:0]; // funct
   assign rs = instr[25:21];  // rs
   assign rt = instr[20:16];  // rt
   assign rd = instr[15:11];  // rd
   assign Imm16 = instr[15:0];// 16-bit immediate
   assign IMM = instr[25:0];  // 26-bit immediate
   
   // instantiation of control unit
   ctrl U_CTRL ( 
      .Op(Op), .Funct(Funct), .Zero(Zero),
      .RegWrite(RegWrite), .MemWrite(MemWrite),
      .EXTOp(EXTOp), .ALUOp(ALUOp), .NPCOp(NPCOp), .ShiftSlt(ShiftSlt),
      .ALUSrc(ALUSrc), .GPRSel(GPRSel),.MDSel(MDSel), .WDSel(WDSel)
   );
   
   // instantiation of PC
   PC U_PC (
      .clk(clk), .rst(rst), .NPC(NPC), .PC(PC)
   ); 
   
   // instantiation of NPC
   NPC U_NPC ( 
      .PC(PC), .NPCOp(NPCOp), .IMM(IMM), .RS(RD1), .NPC(NPC)
   );
   
   // instantiation of register file
   RF U_RF (
      .clk(clk), .rst(rst), .RFWr(RegWrite), 
      .A1(rs), .A2(rt), .A3(A3
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VincentRunning

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值