MIPS CPU R型指令扩展

目录

MIPS CPU框架图 

R型指令格式、对应机器码 

define.v 

IF.v

InstMem.v

ID.v 

EX.v 

RegFile.v  

MIPS.v

SoC.v

SoC_tb.v

仿真测试


MIPS CPU框架图 

R型指令格式、对应机器码 

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

//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 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

IF.v

`include "define.v"
module IF(
    input wire clk,
    input wire rst,
    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;
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'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,r10,1		r11--32'hfffe 0000
	    instmem [11] = 32'h000a6042;	//srl,r12,r10,1		r12--32'h7fff 8000
	    instmem [12] = 32'h000a6843;	//sra r13,r10,1		r13--32'hffff 8000

      end
endmodule

ID.v 

`include "define.v"
module  ID (
    input wire rst,    
    input wire [31:0] inst,
    input wire [31:0] regaData_i,
    input wire [31:0] regbData_i,
    output reg [5:0] op,
    output reg [4:0] regaAddr,
    output reg [4:0] regbAddr,    
    output reg [4:0] regcAddr,    
    output reg [31:0] regaData,
    output reg [31:0] regbData,
    output reg regaRead,
    output reg regbRead,
    output reg regcWrite    
);
    wire [5:0] inst_op = inst[31:26];    
    reg [31:0] imm;
    
    //R
    wire [5:0]func = inst[5:0];

    always@(*)
        if(rst == `RstEnable)
          begin
            op = `Nop;
            regaRead = `Invalid;
            regbRead = `Invalid;
            regcWrite = `Invalid;
            regaAddr = `Zero;
            regbAddr = `Zero;
            regcAddr = `Zero;
            imm = `Zero;
          end

        else  
            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_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_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_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

                //R
		        `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'h0,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'h0,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'h0,inst[10:6]};
                  		end

				        default:
                 		begin
                  		  op = `Nop;
                    	  regaRead = `Invalid;
                    	  regbRead = `Invalid;
                    	  regcWrite = `Invalid;
                    	  regaAddr = `Zero;
                    	  regbAddr = `Zero;
                    	  regcAddr = `Zero;
                    	  imm = `Zero;
                  		end
			        endcase

                 default:
                  begin
                    op = `Nop;
                    regaRead = `Invalid;
                    regbRead = `Invalid;
                    regcWrite = `Invalid;
                    regaAddr = `Zero;
                    regbAddr = `Zero;
                    regcAddr = `Zero;
                    imm = `Zero;
                  end
            endcase

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; 
 
endmodule

EX.v 

`include "define.v"
module EX(
    input wire rst,
    input wire [5:0] op,    
    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
);    
    always@(*)
        if(rst == `RstEnable)
            regcData = `Zero;
        else
          begin
            case(op)
                `Or:
                    regcData = regaData | regbData;
	     	    `Add:
		            regcData = regaData + regbData;
		        `And:
		            regcData = regaData & regbData;
		        `Xor:
		            regcData = regaData ^ regbData;
		        `Lui:
		            regcData = regaData;
		        `Sub:
		            regcData = regaData - regbData;
	        	`Sll:
		            regcData = regbData << regaData;
		        `Srl:
	          	    regcData = regbData >> regaData;
		        `Sra:
		            regcData = ($signed(regbData)) >>> regaData;
		
                default:
                    regcData = `Zero;
            endcase

          end
    assign regcWrite = regcWrite_i;
    assign regcAddr = regcAddr_i;
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

MIPS.v

`include "define.v"
module MIPS(
    input wire clk,
    input wire rst,
    input wire [31:0] instruction,
    output wire romCe,
    output wire [31:0] instAddr
);
    wire [31:0] regaData_regFile, regbData_regFile;
    wire [31:0] regaData_id, regbData_id; 
    wire [31:0] regcData_ex;
    wire [5:0] op;    
    wire regaRead, regbRead;
    wire [4:0] regaAddr, regbAddr;
    wire regcWrite_id, regcWrite_ex;
    wire [4:0] regcAddr_id, regcAddr_ex;
    IF if0(
        .clk(clk),
        .rst(rst),
        .ce(romCe), 
        .pc(instAddr)
    );
    ID id0(
        .rst(rst),        
        .inst(instruction),
        .regaData_i(regaData_regFile),
        .regbData_i(regbData_regFile),
        .op(op),
        .regaData(regaData_id),
        .regbData(regbData_id),
        .regaRead(regaRead),
        .regbRead(regbRead),
        .regaAddr(regaAddr),
        .regbAddr(regbAddr),
        .regcWrite(regcWrite_id),
        .regcAddr(regcAddr_id)
    );
    EX ex0(
        .rst(rst),
        .op(op),        
        .regaData(regaData_id),
        .regbData(regbData_id),
        .regcWrite_i(regcWrite_id),
        .regcAddr_i(regcAddr_id),


        .regcData(regcData_ex),
        .regcWrite(regcWrite_ex),
        .regcAddr(regcAddr_ex)
    );    
    RegFile regfile0(
        .clk(clk),
        .rst(rst),

        .we(regcWrite_ex),
        .waddr(regcAddr_ex),
        .wdata(regcData_ex),

        .regaRead(regaRead),
        .regbRead(regbRead),
        .regaAddr(regaAddr),
        .regbAddr(regbAddr),
        .regaData(regaData_regFile),
        .regbData(regbData_regFile)
    );
endmodule

SoC.v

module SoC(
    input wire clk,
    input wire rst
);
    wire [31:0] instAddr;
    wire [31:0] instruction;
    wire romCe;    
    MIPS mips0(
        .clk(clk),
        .rst(rst),
        .instruction(instruction),
        .instAddr(instAddr),
        .romCe(romCe)
    );    
    InstMem instrom0(
        .ce(romCe),
        .addr(instAddr),
        .data(instruction)
    );
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

仿真测试

① instmem [0] = 32'h34011100;  

机器码:0011 0100 0000 0001 0001 0001 0000 0000

指令:001101(ori)        rs:00000(r0)        rt:00001(r1)        

imm:0001 0001 0000 0000(零扩展)

//ori r1,r0,1100h         r1<--32'h0000 1100

②instmem [1] = 32'h34020020;  

机器码:0011 0100 0000 0010 0000 0000 0010 0000

指令:001101(ori)        rs:00000(r0)        rt:00010(r2)        

imm:0000 0000 0010 0000(零扩展)

//ori r2,r0,0020h        r2<--32'h0000 0020

③instmem [2] = 32'h3403ff00;  

机器码:0011 0100 0000 0011 1111 1111 0000 0000

指令:001101(ori)        rs:00000(r0)        rt:00011(r3)        

imm:1111 1111 0000 0000(零扩展)

//ori r3,r0,ff00h        r3<--32'h0000 ff00


④instmem [3] = 32'h3404ffff;  

机器码:0011 0100 0000 0100 1111 1111 1111 1111

指令:001101(ori)        rs:00000(r0)        rt:00100(r4)        

imm:1111 1111 1111 1111(零扩展)

//ori r4,r0,ffffh        r4<--32'h0000 ffff
    
⑤instmem [4] = 32'h00222820;    

机器码:0000 0000 0010 0010 0010 1000 0010 0000

指令:rs:00001(r1)        rt:00010(r2)        rd:00101(r5)        sa:00000        func:100000(add)    

//add r5,r1,r2   r5<--32'h0000 1120


⑥instmem [5] = 32'h00223025;    

机器码:0000 0000 0010 0010 0011 0000 0010 0101

指令:rs:00001(r1)        rt:00010(r2)        rd:00110(r6)        sa:00000        func:100101(or)    

//or r6,r1,r2   r6<--32'h0000 1120


⑦instmem [6] = 32'h00223822;    

机器码:0000 0000 0010 0010 0011 1000 0010 0010

指令:rs:00001(r1)        rt:00010(r2)        rd:00111(r7)        sa:00000        func:100010(sub)    

//sub r7,r1,r2   r7<--32'h0000 10e0


⑧instmem [7] = 32'h00224024;    

机器码:0000 0000 0010 0010 0100 0000 0010 0100

指令:rs:00001(r1)        rt:00010(r2)        rd:01000(r8)        sa:00000        func:100100(and)    

//and r8,r1,r2   r8<--32'h0000 0000

        
⑨instmem [8] = 32'h00224826;    

机器码:0000 0000 0010 0010 0100 1000 0010 0110

指令:rs:00001(r1)        rt:00010(r2)        rd:01001(r9)        sa:00000        func:100110(xor)    

//xor r9,r1,r2   r9<--32'h0000 1120


⑩instmem [9] = 32'h3c0affff;  

机器码:0011 1100 0000 1010 1111 1111 1111 1111

指令:001111(lui)        rs:00000        rt:01010(r10)        

imm:1111 1111 1111 1111(低位零扩展)

//lui r10,r3,ffff    r10--32'hffff0000


⑪instmem [10] = 32'h000a5840;  

机器码:0000 0000 0000 1010 0101 1000 0100 0000

指令:rs:00000        rt:01010(r10)        rd:01011(r11)        sa:00001        func:000000(sll)    

//sll r11,r10,1   r11<--32'hfffe 0000


⑫instmem [11] = 32'h000a6042;

机器码:0000 0000 0000 1010 0110 0000 0100 0010

指令:rs:00000        rt:01010(r10)        rd:01100(r12)        sa:00001        func:000010(srl)    

//srl r12,r10,1   r12<--32'h7fff 8000

⑬instmem [12] = 32'h000a6843;

机器码:0000 0000 0000 1010 0110 1000 0100 0011

指令:rs:00000        rt:01010(r10)        rd:01101(r13)        sa:00001        func:000011(sra)    

//sra r13,r10,1   r12<--32'hffff 8000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值