【FPGA】 MIPS 12条整数指令 【3】

实现乘除

修改框架

EX:实现带符号乘除法和无符号乘除法

HiLo寄存器:用于存放乘法和除法的运算结果。Hi、Lo为32bit寄存器。电路描述与实现RegFile思想一致

仿真

代码

DataMem.v

复制代码
`include "define.v";
module DataMem(
        input wire clk,
        input wire ce,
        input wire we,
        input wire [31:0] addr,
        input wire [31:0] wtData,
        output reg [31:0] rdData
);

    reg [31:0] datamem [1023 : 0];
    always@(*)      
        if(ce == `RamDisable)
          rdData = `Zero;
        else
          rdData = datamem[addr[11 : 2]]; 
    always@(posedge clk)
        if(ce == `RamEnable && we == `RamWrite)
            datamem[addr[11 : 2]] = wtData;
        else ;

endmodule

define.v

复制代码
`define RstEnable       1'b1
`define RstDisable      1'b0
`define RomEnable       1'b1 
`define RomDisable      1'b0
`define Zero	        0
`define Valid	        1'b1
`define Invalid	        1'b0
//I
`define Inst_ori   	6'b001101
`define Inst_addi  	6'b001000
`define Inst_andi  	6'b001100
`define Inst_xori  	6'b001110
`define Inst_lui   	6'b001111
`define Inst_subi  	6'b001001

//lw sw
`define Inst_lw 	6'b100011
`define Inst_sw 	6'b101011

//beq bne
`define Inst_beq  	6'b000100
`define Inst_bne  	6'b000101

//R
`define Inst_r    	6'b000000
`define Inst_add  	6'b100000
`define Inst_sub  	6'b100010
`define Inst_and	6'b100100
`define Inst_or    	6'b100101
`define Inst_xor   	6'b100110
`define Inst_sll   	6'b000000
`define Inst_srl   	6'b000010
`define Inst_sra   	6'b000011

`define Inst_jr    	6'b001000
//J
`define Inst_j   	6'b000010
`define Inst_jal 	6'b000011

//12
`define Inst_slt	6'b101010
`define Inst_bgtz	6'b000111
`define Inst_bltz	6'b000001
`define Inst_jalr	6'b001001
`define Inst_mult	6'b011000
`define Inst_multu	6'b011001
`define Inst_div	6'b011010
`define Inst_divu	6'b011011
`define Inst_mfhi	6'b010000
`define Inst_mflo	6'b010010
`define Inst_mthi	6'b010001
`define Inst_mtlo	6'b010011

//
`define Inst_ll		6'b110000
`define Inst_sc		6'b111000
`define Inst_mfc0	6'b000000
`define Inst_mtc0	6'b000000
`define Inst_eret	6'b011000
`define syscall		6'b001100

`define Nop     	6'b000000
`define Or      	6'b000001
`define Add		6'b000010
`define And		6'b000011
`define Xor		6'b000100
`define Lui		6'b000101
`define Sub     	6'b000110
`define Sll     	6'b000111
`define Srl     	6'b001000
`define Sra		6'b001001
`define J		6'b001010
`define Jal		6'b001011
`define Beq		6'b001100
`define Bne		6'b001101
`define Jr		6'b001110
`define Lw  		6'b010000
`define Sw  		6'b010001
`define Bgtz		6'b010010
`define Bltz		6'b010011
`define Slt		6'b010100
`define Mult		6'b010101
`define Multu		6'b010110
`define Div		6'b010111
`define Divu		6'b011000

//MEM
`define RamWrite 	1'b1
`define RamUnWrite 	1'b0
`define RamEnable 	1'b1
`define RamDisable 	1'b0

EX.v

复制代码
`include "define.v"
module EX(
    input wire rst,
    //input wire [5:0] op,
    input wire [5:0] op_i,     
    input wire [31:0] regaData,
    input wire [31:0] regbData,
    input wire regcWrite_i,
    input wire [4:0]regcAddr_i,
    output reg [31:0] regcData,
    output wire regcWrite,
    output wire [4:0] regcAddr,

    output wire [5:0] op,
    output wire [31:0] memAddr,
    output wire [31:0] memData,
	
    input wire [31:0] rhi,
    input wire [31:0] rlo,
    output reg whi,	
    output reg wlo,	
    output reg [31:0] hiData,	
    output reg [31:0] loData  

);    
    assign op = op_i;
    assign memAddr = regaData;
    assign memData = regbData;

    always@(*)
        if(rst == `RstEnable)
            regcData = `Zero;
	    
        else
          begin
		
            //case(op)
		case(op_i)
                `Or:
                    	regcData = regaData | regbData;
	     	`Add:
		    	regcData = regaData + regbData;
		`And:
		    	regcData = regaData & regbData;
		`Xor:
		    	regcData = regaData ^ regbData;
		`Lui:
		    	regcData = regaData;
		/*`Lui:
		    	regcData = regaData | regbData;
		*/
		`Sub:
		   	regcData = regaData - regbData;
		`Sll:
		    	regcData = regbData << regaData;
		`Srl:
		    	regcData = regbData >> regaData;
		`Sra:
		    	regcData = ($signed(regbData)) >>> regaData;
		`J:
                    	regcData = `Zero;
		`Jr:
                    	regcData = `Zero;
                `Jal:
                    	regcData = regbData;
		`Beq:
                    	regcData = `Zero;
                `Bne:
                    	regcData = `Zero;
		`Bltz:
		    	regcData = `Zero;
		`Bgtz:
		    	regcData = `Zero;
              
		`Slt:
		    	regcData = ($signed(regaData)<$signed(regbData))?1'b1:1'b0;

		`Mult:
			begin
				whi=`Valid;
				wlo=`Valid;
				{hiData,loData}=$signed(regaData)*$signed(regbData);
			end
		`Multu:
			begin
				whi=`Valid;
				wlo=`Valid;
				{hiData,loData}=regaData*regbData;
			end
		`Div:
			begin
				whi=`Valid;
				wlo=`Valid;
				hiData=$signed(regaData)%$signed(regbData);
				loData=$signed(regaData)/$signed(regbData);
			end
		`Divu:
			begin
				whi=`Valid;
				wlo=`Valid;
				hiData=regaData%regbData;
				loData=regaData/regbData;
			end


                default:
                    regcData = `Zero;
            endcase

          end
    assign regcWrite = regcWrite_i;
    assign regcAddr = regcAddr_i;
endmodule

HiLo.v

复制代码
`include "define.v"
module HiLo (
	input wire rst,
	input wire clk ,
	input wire [31:0] hiData,
	input wire [31:0] loData,
	input wire whi ,
	input wire wlo ,
	output reg [31:0] rhi,
	output reg [31:0] rlo
);
	reg [31:0]hi,lo;//????
	always@ (*)
		if(rst==`RstEnable)
			begin
				rhi = `Zero;
				rlo = `Zero;
			end
		else
			begin
				rhi = hi;
				rlo = lo;
			end
	always@(posedge clk)
		if (rst ==`RstDisable && whi==`Valid)
			hi=hiData;
		else ;

	always@(posedge clk)
		if (rst ==`RstDisable && wlo==`Valid)
			lo=loData;
		else ;
endmodule

ID.v

复制代码
`include "define.v";
module  ID (
    input wire rst,    
   input wire [31:0] pc,   //J
    input wire [31:0] inst,
    input wire [31:0] regaData_i,
    input wire [31:0] regbData_i,
    output reg [5:0] op,    
    output reg [31:0] regaData,
    output reg [31:0] regbData,
    output reg regaRead,
    output reg regbRead,
    output reg regcWrite,
    output reg [4:0] regaAddr,
    output reg [4:0] regbAddr,    
    output reg [4:0] regcAddr,
    output reg [31:0] jAddr,   //J
    output reg jCe//J

);

    wire [5:0] inst_op = inst[31:26];   
  
    reg [31:0] imm;
   //R
    wire[5:0] func = inst[5:0]; 
   //J
   wire [31:0] npc = pc + 4;

    always@(*)
        if(rst == `RstEnable)
             begin
               op = `Nop;            
               regaRead = `Invalid;
               regbRead = `Invalid;
               regcWrite = `Invalid;
               regaAddr = `Zero;
               regbAddr = `Zero;
               regcAddr = `Zero;
               imm    = `Zero;
            jCe = `Invalid;//J
               jAddr = `Zero;//J
             end
      else 
         begin
             jCe = `Invalid;//J
              jAddr = `Zero;//J
               case(inst_op)
                     `Inst_ori:
                     begin
                          op = `Or;                    
                          regaRead = `Valid;
                          regbRead = `Invalid;
                          regcWrite = `Valid;
                          regaAddr = inst[25:21];
                          regbAddr = `Zero;
                          regcAddr = inst[20:16];
                          imm = {16'h0, inst[15:0]};
                        end
                `Inst_andi:
                  begin
                          op = `And;                    
                          regaRead = `Valid;
                          regbRead = `Invalid;
                          regcWrite = `Valid;
                          regaAddr = inst[25:21];
                          regbAddr = `Zero;
                          regcAddr = inst[20:16];
                          imm = {16'h0, inst[15:0]};
                      end
               `Inst_xori:
                  begin
                          op = `Xor;                    
                          regaRead = `Valid;
                          regbRead = `Invalid;
                          regcWrite = `Valid;
                          regaAddr = inst[25:21];
                          regbAddr = `Zero;
                          regcAddr = inst[20:16];
                          imm = {16'h0, inst[15:0]};
                        end
   
               `Inst_addi:
                  begin
                          op = `Add;                    
                          regaRead = `Valid;
                          regbRead = `Invalid;
                          regcWrite = `Valid;
                          regaAddr = inst[25:21];
                          regbAddr = `Zero;
                          regcAddr = inst[20:16];
                          imm = {
  
  {16{inst[15]}}, inst[15:0]};
                      end
               `Inst_subi:
                  begin
                          op = `Sub;                    
                          regaRead = `Valid;
                          regbRead = `Invalid;
                          regcWrite = `Valid;
                          regaAddr = inst[25:21];
                          regbAddr = `Zero;
                          regcAddr = inst[20:16];
                          imm = {
  
  {16{inst[15]}}, inst[15:0]};
                       end
                `Inst_lui:
                  begin
                          op = `Lui;                    
                          regaRead = `Invalid;
                          regbRead = `Invalid;
                          regcWrite = `Valid;
                          regaAddr = `Zero;
                          regbAddr = `Zero;
                          regcAddr = inst[20:16];
                          imm = {inst[15:0],16'h0};
                        end

               `Inst_r:
                   case(func)
                        `Inst_add:
                             begin
                                 op = `Add;  
                                regaRead = `Valid;
                                regbRead = `Valid;
                                regcWrite = `Valid;
                                regaAddr = inst[25:21];
                                regbAddr = inst[20:16];
                            regcAddr = inst[15:11];
                                imm = `Zero;
                             end
   
                     `Inst_or:
                        begin
                            op = `Or;
                            regaRead = `Valid;
                            regbRead = `Valid;
                            regcWrite = `Valid;
                            regaAddr = inst[25:21];
                                    regbAddr = inst[20:16];
                                    regcAddr = inst[15:11];
                                    imm = `Zero;
                                end
   
                        `Inst_sub:
                                begin
                                    op = `Sub;
                                    regaRead = `Valid;
                                    regbRead = `Valid;
                                    regcWrite = `Valid;
                                    regaAddr = inst[25:21];
                                    regbAddr = inst[20:16];
                                    regcAddr = inst[15:11];
                                    imm = `Zero;
                                end
   
                        `Inst_and:
                                begin
                                    op = `And;
                                    regaRead = `Valid;
                                    regbRead = `Valid;
                                    regcWrite = `Valid;
                                    regaAddr = inst[25:21];
                                    regbAddr = inst[20:16];
                                    regcAddr = inst[15:11];
                                    imm = `Zero;
                                end
   
   
                        `Inst_xor:
                                begin
                                    op = `Xor;
                                    regaRead = `Valid;
                                    regbRead = `Valid;
                                    regcWrite = `Valid;
                                    regaAddr = inst[25:21];
                                    regbAddr = inst[20:16];
                                    regcAddr = inst[15:11];
                                    imm = `Zero;
                                end
   
   
                        `Inst_sll:
                                begin
                                    op = `Sll;
                                    regaRead = `Invalid;
                                    regbRead = `Valid;
                                    regcWrite = `Valid;
                                    regaAddr = `Zero;
                                    regbAddr = inst[20:16];
                                    regcAddr = inst[15:11];
                                    imm = {27'b0,inst[10:6]};
                                end
   
                        `Inst_srl:
                                begin
                                    op = `Srl;
                                    regaRead = `Invalid;
                                    regbRead = `Valid;
                                    regcWrite = `Valid;
                                    regaAddr = `Zero;
                                    regbAddr = inst[20:16];
                                    regcAddr = inst[15:11];
                                    imm = {27'b0,inst[10:6]};
                                end
   
                        `Inst_sra:
                                begin
                                    op = `Sra;
                                    regaRead = `Invalid;
                                    regbRead = `Valid;
                                    regcWrite = `Valid;
                                    regaAddr = `Zero;
                                    regbAddr = inst[20:16];
                                    regcAddr = inst[15:11];
                                    imm = {27'b0,inst[10:6]};
                                end
   
   
                        
                        `Inst_jr:
                              begin
                                    op = `Jr;
                                    regaRead = `Valid;//rs
                                    regbRead = `Invalid;
                                    regcWrite = `Invalid;
                                    regaAddr = inst[25:21];
                                    regbAddr = `Zero;
                                    regcAddr = 5'b11111;
                                    jAddr = regaData;
                                    jCe = `Valid;
                                    imm = `Zero;
                              end
			`Inst_jalr:
                              begin
                                    op = `Jal;
                                    regaRead = `Valid;
                                    regbRead = `Invalid;
                                    regcWrite = `Valid;
                                    regaAddr = inst[25:21];
                                    regbAddr = `Zero;
                                    regcAddr = inst[15:11];  //
                                    jAddr = regaData;
                                    jCe = `Valid;
                                    imm = npc;
                              end

			`Inst_slt:
                              begin
                                    op = `Slt;
                                    regaRead = `Valid;
                                    regbRead = `Invalid;
                                    regcWrite = `Valid;
                                    regaAddr = inst[25:21];
                                    regbAddr = inst[20:16];
                                    regcAddr = inst[15:11];  
                                    imm = `Zero;
                              end
   			`Inst_mult:
			      begin
					op = `Mult;
					regaRead = `Valid;
					regbRead = `Valid;
					regcWrite = `Invalid;
					regaAddr = inst[25:21];
					regbAddr = inst[20:16];
					regcAddr = `Zero;
					imm = `Zero;
				end		
			`Inst_multu:
				begin
					op = `Multu;
					regaRead = `Valid;
					regbRead = `Valid;
					regcWrite = `Invalid;							  				regaAddr = inst[25:21];
					regbAddr = inst[20:16];
					regcAddr = `Zero;
					imm = `Zero;
				end		
			`Inst_div:
				begin
					op = `Div;
					regaRead = `Valid;
					regbRead = `Valid;
					regcWrite = `Invalid;
					regaAddr = inst[25:21];
					regbAddr = inst[20:16];
					regcAddr = `Zero;
					imm = `Zero;
				end		
			`Inst_divu:
				begin
					op = `Divu;
					regaRead = `Valid;
					regbRead = `Valid;
					regcWrite = `Invalid;
					regaAddr = inst[25:21];
					regbAddr = inst[20:16];
					regcAddr = `Zero;
					imm = `Zero;
				end		



                       
                        default:
                                begin
                                    regaRead = `Invalid;
                                    regbRead = `Invalid;
                                    regcWrite = `Invalid;
                                    regaAddr = `Zero;
                                    regbAddr = `Zero;
                                  regcAddr = `Zero;
                                    imm = `Zero;
                                 
                                end
                           endcase
   
               //J
               `Inst_j:
                  begin
                        op = `J;
                        regaRead = `Invalid;
                        regbRead = `Invalid;
                        regcWrite = `Invalid;
                        regaAddr = `Zero;
                        regbAddr = `Zero;
                     	regcAddr = `Zero;
                        jAddr = {npc[31:28], inst[25:0], 2'b00};
                         jCe = `Valid;
                        imm = `Zero;
                  end            
               `Inst_jal:
                  begin
                        op = `Jal;
                        regaRead = `Invalid;
                        regbRead = `Invalid;
                        regcWrite = `Valid;
                        regaAddr = `Zero;
                        regbAddr = `Zero;
                     	regcAddr = 5'b11111;
                        jAddr = {npc[31:28], inst[25:0], 2'b00};
                           jCe = `Valid;
                        imm = npc;
                     end
                //J 
               `Inst_beq:
                  begin
                     op = `Beq;
                     regaRead = `Valid;
                     regbRead = `Valid;
                     regcWrite = `Invalid;
                     regaAddr = inst[25:21];
                     regbAddr = inst[20:16];
                     regcAddr = `Zero;
                     jAddr = npc+{
  
  {14{inst[15]}},inst[15:0],2'b00};
                     jCe=(regaData==regbData)?`Valid:`Invalid; 
                    /* if(regaData==regbData)
                           jCe = `Valid;
                     else
                        jCe = `Invalid;*/
                        imm = `Zero;
                  end      
               `Inst_bne:
                  begin
                        op = `Bne;
                        regaRead = `Valid;
                        regbRead = `Valid;
                        regcWrite = `Invalid;
                        regaAddr = inst[25:21];
                        regbAddr = inst[20:16];
                     	regcAddr = `Zero;
                        jAddr = npc+{
  
  {14{inst[15]}},inst[15:0],2'b00};
                        jCe=(regaData!=regbData)?`Valid:`Invalid;   
                    /* if(regaData!=regbData)
                            jCe = `Valid;
                     else
                        jCe = `Invalid;
			*/
                        imm = `Zero;
                  end      
		
		`Inst_bgtz:
			begin
			op = `Bgtz;
			regaRead = `Valid;
			regbRead = `Valid;//
			regcWrite = `Invalid;
			regaAddr = inst[25:21];
			regbAddr = inst[20:16];
			regcAddr = `Zero;
			jAddr = npc+{
  
  {14{inst[15]}},inst[15:0],2'b00};
			jCe = (regaData[31]==0)?`Valid:`Invalid;
			imm = 32'b0;  //
			end

		`Inst_bltz:
			begin
			op = `Bgtz;
			regaRead = `Valid;
			regbRead = `Valid;//
			regcWrite = `Invalid;
			regaAddr = inst[25:21];
			regbAddr = inst[20:16];
			regcAddr = `Zero;
			jAddr = npc+{
  
  {14{inst[15]}},inst[15:0],2'b00};

			jCe = (regaData[31]==1)?`Valid:`Invalid;  //
			imm = 32'b0;  //
			end

			
     
               	`Inst_lw:
			begin
			op = `Lw;
			regaRead = `Valid;
			regbRead = `Invalid;
			regcWrite = `Valid;
			regaAddr = inst[25:21];
			regbAddr = `Zero;
			regcAddr = inst[20:16];
			imm = {
  
  {16{inst[15]}},inst[15:0]};
			end
					
		`Inst_sw:
			begin
			op = `Sw;
			regaRead = `Valid;
			regbRead = `Valid;
			regcWrite = `Invalid;
			regaAddr = inst[25:21];
			regbAddr = inst[20:16];
			regcAddr = `Zero;
			imm = {
  
  {16{inst[15]}},inst[15:0]};
			end	
      
               default:
                        begin
                          op = `Nop;                    
                          regaRead = `Invalid;
                          regbRead = `Invalid;
                          regcWrite = `Invalid;
                          regaAddr = `Zero;
                          regbAddr = `Zero;
                          regcAddr = `Zero;
                          imm = `Zero;
                      end
               endcase 
         end
   
 /*
   always@(*)
      if(rst == `RstEnable)
          regaData = `Zero;
      else if(regaRead == `Valid)
          regaData = regaData_i;
      else  
          regaData = imm;
   
 
    always@(*)
      if(rst == `RstEnable)
          regbData = `Zero;      
      else if(regbRead == `Valid)
          regbData = regbData_i;
      else
          regbData = imm; 

*/
always@(*)      
	    if(rst == `RstEnable)          
	        regaData = `Zero;      
	    else if(op == `Lw || op == `Sw)               
	        regaData = regaData_i + imm;      
	    else if(regaRead == `Valid)          
	        regaData = regaData_i;      
	    else          
	        regaData = imm;    
	always@(*)      
	    if(rst == `RstEnable)          
	        regbData = `Zero;      
	    else if(regbRead == `Valid)          
	        regbData = regbData_i;      
	    else          
	    	regbData = imm;

   
endmodule

IF.v

复制代码
`include "define.v"
module IF(
    input wire clk,
    input wire rst,

    input wire [31:0] jAddr,//J
    input wire jCe,//J

    output reg ce, 
output reg [31:0] pc
);
    always@(*)
        if(rst == `RstEnable)
            ce = `RomDisable;
        else
            ce = `RomEnable;
/*    always@(posedge clk)
        if(ce == `RomDisable)
            pc = `Zero;
        else
            pc = pc + 4;
*/
      always@(posedge clk)
        if(ce == `RomDisable)
            pc = `Zero;
        else if(jCe == `Valid)//J
            pc = jAddr;
        else
            pc = pc + 4;
endmodule

InstMem.v

复制代码
`include "define.v"
module InstMem(
    input wire ce,
    input wire [31:0] addr,
    output reg [31:0] data
);
    reg [31:0] instmem [1023 : 0];    
    always@(*)      
        if(ce == `RomDisable)
          data = `Zero;
        else
          data = instmem[addr[11 : 2]];   
    initial
      begin
        instmem [0] = 32'h34011100;   //ori r1,r0,1100h         r1--32'h0000 1100
        instmem [1] = 32'h34020020;   //ori r2,r0,0020h		r2--32'h0000 0020
        instmem [2] = 32'h3403ff00;   //ori r3,r0,ff00h		r3--32'h0000 ff00
        instmem [3] = 32'h3404ffff;   //ori r4,r0,ffffh		r4--32'h0000 ffff
	instmem [4] = 32'b000000_00001_00010_00000_00000_011001;//multu,r1,r2         22000
	instmem [5] = 32'b000000_00001_00010_00000_00000_011011;//divu,r1,r2         88
	instmem [6] = 32'h2005fffc;	//addi r5,r0,fffc	r5--32'hffff fffc
	instmem [7] = 32'h34060002;   //ori r6,r0,0002h         r6--32'h0000 0002
	instmem [8] = 32'h3c071234;     //lui r7,1234		r7--32'h1234 0000
	instmem [9] = 32'b000000_00101_00110_00000_00000_011000; //mult r5,r6
	instmem [10] = 32'b000000_00101_00110_00000_00000_011010; //div r5,r6


	

/*
	instmem [4] = 32'h2005ffff;	//addi r5,r0,ffff	r5--32'hffff ffff
	instmem [5] =32'b000000_00101_00100_00110_00000_101010;	  //slt r6,r5,r4
	instmem [6] =32'b000000_00100_00011_00110_00000_101010;	  //slt r6,r4,r3
*/

/*	
	instmem [4] = 32'h3005ffff;	//andi r5,r0,ffff	r5--32'h0000 0000
	instmem [5] = 32'h3806ffff;	//xori r6,r0,ffff	r6--32'h0000 ffff
	instmem [6] = 32'h2007ffff;	//addi r7,r0,ffff	r7--32'hffff ffff
	instmem [7] = 32'h3c081234;     //lui r8,1234		r8--32'h1234 0000
		
	instmem [8] = 32'h35095679;     //ori r9,r8,5678	r9--32'h1234 5679
	instmem [9] = 32'h212aa011;     //addi r10,r9,a011	r10--32'h1233 f68a
	instmem [10] = 32'h306b1111;	//andi r11,r3,1111	r10--32'h0000 1100
	instmem [11] = 32'h254C1111;    //subi r12,r10,1111     r12--32'h1234 e579
*/
/*
	instmem [4] = 32'h00222820;     //add r5,r1,r2		r5--32'h0000 1120
	instmem [5] = 32'h00223025;	//or r6,r1,r2		r6--32'h0000 1120
	instmem [6] = 32'h00223822;	//sub r7,r1,r2		r7--32'h0000 10e0
	instmem [7] = 32'h00224024;	//and r8,r1,r2		r8--32'h0000 0000
	instmem [8] = 32'h00224826;	//xor r9,r1,r2		r9--32'h0000 1120

	instmem [9] =32'h3c0affff;	//lui r10,ffff		r10--32'hffff 0000
	instmem [10] = 32'h000a5840;	//sll r11,ra,r10	r11--32'hfffe 0000
	instmem [11] = 32'h000a6042;	//srl,r12,ra,r10	r12--32'h7fff 8000
	instmem [12] = 32'h000a6843;	//sra r13,ra,r10	r13--32'hffff 8000

*/	

/*


	instmem [4] = 32'h3401001c;     //ori r1,r0,1ch
	instmem [5] = 32'b000000_00001_00000_11111_00000_001001;//jalr r31,r1
	instmem [6] = 32'h3405ffff;   //ori r5,r0,ffffh		
	instmem [7] = 32'b000000_00001_00010_00101_00000_100000;//add,R5,R1,R2  
	instmem [8] = 32'b000000_11111_00000_00000_00000_001000;//jr r31
*/
/*
	instmem [4] = 32'b000000_00001_00010_00101_00000_100000;//add,R5,R1,R2  
	instmem [5] = 32'h3405ffff;   //ori r5,r0,ffffh		
      

	instmem [6] = 32'b000000_00010_00011_00110_00000_100101;//or,R6,R2,R3   
	instmem [7] = 32'b000111_00101_00000_0000000000000001;//bgtz r5,1
	instmem [8] = 32'b000000_00001_00010_00110_00000_100101;//or,R6,R1,R2   00001120
	instmem [9] = 32'h2007ffff;	//addi r7,r0,ffff	r7--32'hffff ffff
	instmem [10] = 32'b000000_00011_00100_00110_00000_100101;//or,R6,R3,R4  
	

	//instmem [10] = 32'b000001_00111_00000_1111111111111101;//bltz r7,-3  
	instmem [11] = 32'b000001_00111_00000_1111111111111010;//bltz r7,-6
	
*/
	
	
	//(r1)=0000 1100
		//    +0000 0018
		//addr=0000 1118  
		//    =1000100011000 
		//    =100 0100 0110 
		//	  =446H	        
		//    =46H		    
		//    =70
		//mem[70]=(r6)
	/*
	instmem[6]=32'b101011_00001_00110_0000_0000_0001_1000; //sw r6,0x18(r1)
		
	instmem[7]=32'b100011_00001_00111_0000_0000_0001_1000; //lw r7,0x18(r1)
	*/
	//(r7)=mem[70]
      end
endmodule

MEM.v

复制代码
`include "define.v";
module MEM(
	input wire rst,		
	input wire [5:0] op,
	input wire [31:0] regcData,
	input wire [4:0] regcAddr,
	input wire regcWr,
	input wire [31:0] memAddr_i,
	input wire [31:0] memData,	
	input  wire [31:0] rdData,
	output wire [4:0]  regAddr,
	output wire regWr,
	output wire [31:0] regData,	
	output wire [31:0] memAddr,
	output reg [31:0] wtData,
	output reg memWr,	
	output reg memCe
);

	assign regAddr = regcAddr;    
	assign regWr = regcWr;    
	assign regData = (op == `Lw) ? rdData : regcData;    
	assign memAddr = memAddr_i;
	
	always @(*)        
	    if(rst == `RstEnable)          
	      begin            
	          wtData = `Zero;            
	          memWr = `RamUnWrite;            
	          memCe = `RamDisable;          
	      end        
		else
			case(op)                
			    `Lw:                  
			      begin                    
			         wtData = `Zero;                        
			         memWr = `RamUnWrite;                     
			         memCe = `RamEnable;                    
			      end                
			    `Sw:                  
			      begin                    
			         wtData = memData;                    
			         memWr = `RamWrite;                      
			         memCe = `RamEnable;                   
			     end
			default:                  
			    begin                    
			        wtData = `Zero;                    
			        memWr = `RamUnWrite;                    
			        memCe = `RamDisable;                  
			    end            
			endcase
endmodule

MIPS.v

复制代码
`include "define.v";
module MIPS(
    	input wire clk,
    	input wire rst,
    	input wire [31:0] instruction,
    	input wire [31:0] rdData,//ls
	output wire romCe,
	output wire [31:0] instAddr,
	output wire [31:0] wtData,//ls
	output wire [31:0] memAddr,//ls
	output wire memCe,//ls
	output wire memWr//ls
);
    	wire [31:0] regaData_regFile, regbData_regFile;
    	wire [31:0] regaData_id, regbData_id; 
    	wire [31:0] regcData_ex;
   	 //wire [5:0] op; 
    	wire [5:0] op_id; //ls  
    	wire regaRead, regbRead;
    	wire [4:0] regaAddr, regbAddr;
    	wire regcWrite_id, regcWrite_ex;
    	wire [4:0] regcAddr_id, regcAddr_ex;

	//J
	wire [31:0] jAddr;
    	wire jCe;

	//ls
	wire [5:0] op_ex;
	wire[31:0] memAddr_ex,memData_ex;
	wire [5:0] regAddr_mem;
	wire [31:0] regData_mem;
	wire regWr_mem;

	//
	wire [31:0] hiData_ex;
	wire [31:0] loData_ex;
	wire whi_ex;
	wire wlo_ex;
	wire [31:0] rhi_ex;
	wire [31:0] rlo_ex;
    IF if0(
        .clk(clk),
        .rst(rst),
	.jAddr(jAddr),//J
	.jCe(jCe),//J
        .ce(romCe), 
        .pc(instAddr)
    );
    ID id0(
        .rst(rst), 
       	.pc(instAddr),//J
        .inst(instruction),
        .regaData_i(regaData_regFile),
        .regbData_i(regbData_regFile),
        //.op(op),
	.op(op_id),//ls
        .regaData(regaData_id),
        .regbData(regbData_id),
        .regaRead(regaRead),
        .regbRead(regbRead),
        .regaAddr(regaAddr),
        .regbAddr(regbAddr),
        .regcWrite(regcWrite_id),
        .regcAddr(regcAddr_id),
	.jAddr(jAddr),//J
	.jCe(jCe)//J

    );

    EX ex0(
        .rst(rst),
        //.op(op),    
	.op_i(op_id),    
        .regaData(regaData_id),
        .regbData(regbData_id),
        .regcWrite_i(regcWrite_id),
        .regcAddr_i(regcAddr_id),
        .regcData(regcData_ex),
        .regcWrite(regcWrite_ex),
        .regcAddr(regcAddr_ex),
	.op(op_ex),//ls
	.memAddr(memAddr_ex),//ls
	.memData(memData_ex),//ls


	.rhi(rhi_ex),
	.rlo(rlo_ex),
	.whi(whi_ex),
	.wlo(wlo_ex),
	.hiData(hiData_ex),
	.loData(loData_ex) 
    );    
	HiLo hilo0(
		.rst(rst),
		.clk(clk),
		.rhi(rhi_ex),
		.rlo(rlo_ex),
		.whi(whi_ex),
		.wlo(wlo_ex),
		.hiData(hiData_ex),
		.loData(loData_ex) 
	);

	
	MEM mem0(
        	.rst(rst),		
	        .op(op_ex),
	 	.regcData(regcData_ex),
		.regcAddr(regcAddr_ex),
		.regcWr(regcWrite_ex),
		.memAddr_i(memAddr_ex),
		.memData(memData_ex),	
		.rdData(rdData),
		.regAddr(regAddr_mem),
		.regWr(regWr_mem),
		.regData(regData_mem),	
		.memAddr(memAddr),
		.wtData(wtData),
		.memWr(memWr),	
		.memCe(memCe)
	);

	
    RegFile regfile0(
        	.clk(clk),
        	.rst(rst),
        	//.we(regcWrite_ex),
		.we(regWr_mem),
        	//.waddr(regcAddr_ex),
		.waddr(regAddr_mem),
        	//.wdata(regcData_ex),
		.wdata(regData_mem),
        	.regaRead(regaRead),
        	.regbRead(regbRead),
        	.regaAddr(regaAddr),
        	.regbAddr(regbAddr),
        	.regaData(regaData_regFile),
        	.regbData(regbData_regFile)
    );

endmodule

RegFile.v

复制代码
`include "define.v"
module RegFile(
    input wire clk,
    input wire rst,
    input wire we,
    input wire [4:0] waddr,
    input wire [31:0] wdata,
    input wire regaRead,
    input wire regbRead,
    input wire [4:0] regaAddr,
    input wire [4:0] regbAddr,
    output reg [31:0] regaData,
    output reg [31:0] regbData
);
    reg [31:0] reg32 [31 : 0];    
    always@(*)
        if(rst == `RstEnable)
            regaData = `Zero;
        else if(regaAddr == `Zero)
            regaData = `Zero;
        else
            regaData = reg32[regaAddr];
    always@(*)
        if(rst == `RstEnable)          
            regbData = `Zero;
        else if(regbAddr == `Zero)
            regbData = `Zero;
        else
            regbData = reg32[regbAddr];
    always@(posedge clk)
        if(rst != `RstEnable)
            if((we == `Valid) && (waddr != `Zero))
                reg32[waddr] = wdata;
        else ;          
endmodule

SoC.v

复制代码
module SoC(
    input wire clk,
    input wire rst
);
    wire [31:0] instAddr;
    wire [31:0] instruction;
    wire romCe;

   //ls
    wire memCe, memWr;    
    wire [31:0] memAddr;
    wire [31:0] rdData;
    wire [31:0] wtData;

    MIPS mips0(
        .clk(clk),
        .rst(rst),
        .instruction(instruction),
        .instAddr(instAddr),
        .romCe(romCe),
		.rdData(rdData),        
    	.wtData(wtData),        
    	.memAddr(memAddr),        
    	.memCe(memCe),        
    	.memWr(memWr) 
    );	
    
    InstMem instrom0(
        .ce(romCe),
        .addr(instAddr),
        .data(instruction)
    );

	//DataMem
	DataMem datamem0(       
    	.ce(memCe),        
    	.clk(clk),        
    	.we(memWr),        
    	.addr(memAddr),        
    	.wtData(wtData),        
    	.rdData(rdData)  
	);
endmodule

soc_tb.v

复制代码
`include "define.v"
module soc_tb;
    reg clk;
    reg rst;
    initial
      begin
        clk = 0;
        rst = `RstEnable;
        #100
        rst = `RstDisable;
        #10000 $stop;        
      end
    always #10 clk = ~ clk;
    SoC soc0(
        .clk(clk), 
        .rst(rst)
    );
endmodule
相关推荐
Terasic友晶科技1 小时前
【教程】Agilex 5 SoC 的两种启动模式的开发演示(一)(FPGA Configuration First)
fpga开发·agilex 5 soc
ALINX技术博客1 小时前
【黑金云课堂】FPGA技术教程Vitis开发:SD卡WAV文件读取音频播放实验
fpga开发·音视频
仲南音2 天前
Xilinx FPGA——时钟IP核MMCM、PLL
fpga开发
I'm a winner3 天前
基于Xilinx FPGA的LVDS高速串行通信系统(三)--数据训练及握手机制【文末源码】
fpga开发
upper20203 天前
coremark移植坑之-nostartfiles -nostdlib参数
学习·fpga开发·coremark移植·riscv设计
Eloudy3 天前
Vivado 纯命令行构建 FPGA 项目教程
fpga开发
Rambo.xia3 天前
AXI跨时钟域与数据一致性——CDC FIFO深度不够、写后读冒险、多Master仲裁、乱序返回,出了Bug根本查不出来
fpga开发·bug
upper20203 天前
FPGA部署卷积神经网络识别MINST图片
fpga开发·卷积神经网络·minst·minst识别·部署神经网络·神经网络识别图片
你是我的解忧王子4 天前
嵌入式 ADC采样 原始数据分析上层(平均值 波动率 正态分布 线性补偿 系统误差)
fpga开发·数据挖掘·数据分析
9527华安4 天前
FPGA纯verilog代码ISP图像处理培训教程,基于IMX214,提供工程源码+视频教程+FPGA开发板
图像处理·fpga开发·isp·imx214·mipi