2模型计算机各功能电路设计【FPGA模型机课程设计】

这篇具有很好参考价值的文章主要介绍了2模型计算机各功能电路设计【FPGA模型机课程设计】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

2023-5-22 10:18:30

以下内容源自《【FPGA模型机课程设计】》
仅供学习交流使用

推荐

0集中实践环节计划书【FPGA模型机课程设计】

参考

简单的指令设计
MIPS CPU 设计【计算机组成原理】

详细的指令设计
MIPS CPU 设计+【计算机组成原理】

测试结果具体分析可以查看:

  • 实验三+ I型指令设计实验【计算机组成原理】
  • 实验四+ R型指令设计实验【计算机组成原理】
  • 实验五+ J型指令设计实验【计算机组成原理】
  • 实验六+ Load和Store指令设计实验【计算机组成原理】

2模型计算机各功能电路设计

安排

第一周周二:
模型计算机各功能电路设计。学生根据总体方案,自行运用VerilogHDL语言进行运算器设计、存储器设计、输入\输出端口设计、总线接口设计等。即要求完成20条MIPS整数指令,基本能够在Modelsim上进行功能仿真,运算、转移和访存功能需测试正确。

20条MIPS整数指令

2模型计算机各功能电路设计【FPGA模型机课程设计】

测试与结果

在InstMem模块中
指令存储器存储以下测试指令
进行仿真测试,查看波形,检查是否正确

初始化数据

		//初始化数据
		//ori R0,1100 -- R1 --00001100
        instmem [0] = 32'h34011100;
		//ori R0,0020 -- R2 --00000020
        instmem [1] = 32'h34020020;
		//ori R0,ff00 -- R3 --0000ff00
        instmem [2] = 32'h3403ff00;
		//ori R0,ffff -- R4 --0000ffff
        instmem [3] = 32'h3404ffff;

2模型计算机各功能电路设计【FPGA模型机课程设计】

I型指令测试

		//I型指令测试
		
		//andi R0,ffff --R5 --00000000
		instmem [4] = 32'h3005ffff;
		//xori R0,ffff --R6 --0000ffff
		instmem [5] = 32'h3806ffff;
		//addi R0,ffff --R7 --ffffffff
		instmem [6] = 32'h2007ffff;
//		//subi R0,ffff --R8 --00000001
//		instmem [7] = 32'h2408ffff;
		//lui  R0,ffff --R9 --ffff0000
		instmem [8] = 32'h3C09ffff;


2模型计算机各功能电路设计【FPGA模型机课程设计】

R型指令测试

		//R型指令测试

		instmem [6] = 32'b000000_00001_00010_00111_00000_100010;//sub,R7,R1,R2  000010e0
		instmem [7] = 32'b000000_00001_00010_01000_00000_100100;//and,R8,R1,R2  00000000
		instmem [8] = 32'b000000_00001_00010_01001_00000_100110;//xor,R9,R1,R2  00001120

		//lui  R0,ffff --R10 --ffff0000
		instmem [9] = 32'h3C0Affff;

		
		//R11=fffe0000 R12=7fff8000  R13=ffff8000
		// Ra=sa={25'b0,imm[10:6]}
		instmem [10] = 32'b000000_00000_01010_01011_00001_000000;//sll,R11,Ra,R10
		instmem [11] = 32'b000000_00000_01010_01100_00001_000010;//srl,R12,Ra,R10  		
		instmem [12] = 32'b000000_00000_01010_01101_00001_000011;//sra,R13,Ra,R10


2模型计算机各功能电路设计【FPGA模型机课程设计】

J型指令测试

		//J- JR型指令测试
/*
		//pc=jaddr=npc(4) offset(26) 00(2)
		//instmem [6] = 32'h08000001;  	//j 1		编码000010  pc=0004 	
		instmem [6] = 32'h0C000002; 	//jal 2		编码000011  pc=0008	r31=npc001c
*/
		instmem [6] = 32'h08000001;  	//j 1		编码000010  pc=0004 	

2模型计算机各功能电路设计【FPGA模型机课程设计】

		instmem [6] = 32'h0C000002; 	//jal 2		编码000011  pc=0008	r31=npc001c

2模型计算机各功能电路设计【FPGA模型机课程设计】

		//pc=jaddr=(rs)
		instmem [6] = 32'h3407000C;//ori,R7,000C
		//instmem [7] = 32'b000000_00111_00000_00000_00000_001000; //jr R7		编码001000 pc=0000000C
		instmem [7] = 32'b000000_00111_00000_00000_00000_001001; //jalr R7 编码001001 pc=0000000C R31=00000020

		instmem [7] = 32'b000000_00111_00000_00000_00000_001000; //jr R7		编码001000 pc=0000000C

2模型计算机各功能电路设计【FPGA模型机课程设计】

		instmem [7] = 32'b000000_00111_00000_00000_00000_001001; //jalr R7 编码001001 pc=0000000C R31=00000020

2模型计算机各功能电路设计【FPGA模型机课程设计】


		//J+型指令测试
		//pc=jaddr=npc+S14 offset(16) 00(2)
		//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
		//instmem [6] = 32'b000100_00101_00110_0000_0000_0000_0000;  //beq r5,r6,0 		编码000100  pc=001C 
		//instmem [6] = 32'b000100_00101_00110_0000_0000_0000_0001;  //beq r5,r6,1 		编码000100  pc=0020 
		//instmem [6] = 32'b000101_00001_00110_1111_1111_1111_1110;  //bne r5,r6,-2 		编码000101  pc=0014 
				
		//instmem [6] = 32'b000001_00010_00000_0000_0000_0000_0001;  //bltz r2,r0,1 		编码000001 pc=0020 
		instmem [6] = 32'b000111_00001_00000_1111_1111_1111_1110;  //bgtz r1,r0,-2 		编码010011 pc=0014 		

		//ori R7,0001 -- R7 --00000001
        instmem [7] = 32'h34070001;	//ori  R7 1
		//ori R8,0001 -- R8 --00000001
        instmem [8] = 32'h34080001;	//ori  R8 1

		instmem [6] = 32'b000100_00101_00110_0000_0000_0000_0000;  //beq r5,r6,0 		编码000100  pc=001C 

跳转到相对于npc的0位置
2模型计算机各功能电路设计【FPGA模型机课程设计】

		instmem [6] = 32'b000100_00101_00110_0000_0000_0000_0001;  //beq r5,r6,1 		编码000100  pc=0020 

跳转到相对于npc的+1位置
2模型计算机各功能电路设计【FPGA模型机课程设计】

		instmem [6] = 32'b000101_00001_00110_1111_1111_1111_1110;  //bne r5,r6,-2 		编码000101  pc=0014 

跳转到相对于npc的-2位置
2模型计算机各功能电路设计【FPGA模型机课程设计】

		instmem [6] = 32'b000001_00010_00000_0000_0000_0000_0001;  //bltz r2,r0,1 		编码000001 pc=0020 

跳转到相对于npc的+1位置
2模型计算机各功能电路设计【FPGA模型机课程设计】

		instmem [6] = 32'b000111_00001_00000_1111_1111_1111_1110;  //bgtz r1,r0,-2 		编码010011 pc=0014 		

跳转到相对于npc的-2位置
2模型计算机各功能电路设计【FPGA模型机课程设计】

访存指令测试

		//(r1)=0000 1100
		//    +0000 0018
		//addr=0000 1118  
		//    =1000100011000 字节地址
		//    =100 0100 0110 字地址
		//	  =446H	         只有1K空间
		//    =46H		     丢掉了高位的1位
		//    =70
		//mem[70]=(r6)
		instmem[6]=32'b101011_00001_00110_0000_0000_0001_1000; //sw r6,0x18(r1)
		//(r7)=mem[70]
		instmem[7]=32'b100011_00001_00111_0000_0000_0001_1000; //lw r7,0x18(r1)

2模型计算机各功能电路设计【FPGA模型机课程设计】

附录

0 框架

顶层设计
2模型计算机各功能电路设计【FPGA模型机课程设计】

代码框架

2模型计算机各功能电路设计【FPGA模型机课程设计】


主要对ID进行设计,如何把数据传入到EX执行模块
另外对InstMem添加对功能的测试
可以结合这两个模块进行功能分析
另外需要熟悉顶层设计的数据通路


1 define 编码

对上面指令进行编码

最好对全部指令进行统一编码,以防编码重复
全部编码可见:0集中实践环节计划书【FPGA模型机课程设计】- 附录

不重复的说明:指的是I型指令之间不重复、R型指令之间不重复、J型指令之间不重复
其余不算重复:I型与R型、外部编码与内部编码
另外:内部编码按二进制递增即可

下面:
对全部指令进行外部编码
内部编码部分给出

define.v

//0、宏定义文件
`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

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

//指令外部编码

//MIPS 基本整数指令集
//表1 20条MIPS整数指令

//R型编码
`define Inst_reg 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

//I型编码
`define Inst_addi 6'b001000
`define Inst_andi 6'b001100
`define Inst_ori  6'b001101
`define Inst_xori 6'b001110
`define Inst_lw 6'b100011
`define Inst_sw 6'b101011
`define Inst_beq  6'b000100	
`define Inst_bne  6'b000101	
`define Inst_lui  6'b001111

//J型编码
`define Inst_j 	 6'b000010	
`define Inst_jal 6'b000011	


//MIPS 扩展整数指令集
//表2 MIPS 12条整数指令
`define Inst_slt 6'101010
`define Inst_bgtz 6'b000111	//j i	
`define Inst_bltz 6'b000001	//j i 	
`define Inst_jalr 6'b001001	//r 
`define Inst_mult 6'b011000	 //r 
`define Inst_multu 6'b011001 //r 
`define Inst_div 6'b011010	 //r 
`define Inst_divtu 6'b011011 //r 
`define Inst_mfhi 6'b010000	 //r 
`define Inst_mflo 6'b010010	 //r 
`define Inst_mthi 6'b010001	 //r 
`define Inst_mtlo 6'b010011	 //r 

//表3 MIPS与中断异常相关6条指令
`define Inst_ll 6'b010011	 //i
`define Inst_sc 6'b010011	 //i

`define Inst_mfc0 6'b000000	 //010000扩展编码
`define Inst_mtc0 6'b000000	 //010000扩展编码
`define Inst_eret 6'b011000	 //010000扩展编码
`define Inst_eret 6'b001100	 //r

//另外
//`define Inst_subi 6'b001001	//i


//内部供EX的编码
`define Nop 6'b000000
`define Or  6'b000001
`define And 6'b000010
`define Xor 6'b000011
`define Add 6'b000100
`define Sub 6'b000101
`define Lui 6'b100000 //此处重新修改了
`define Sll 6'b000110
`define Srl 6'b000111
`define Sra 6'b001000


`define J   6'b001001
`define Jal 6'b001010
`define Jr  6'b001011
`define Beq 6'b001100
`define Bne 6'b001101
`define Bgtz 6'b001110
`define Bltz 6'b001111

`define Lw  6'b010000
`define Sw  6'b010001

2 IF 取指

IF.v

`include "define.v";
//IF 取指模块
//1、控制PC,程序计数器

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;

    //程序执行 pc+=4
    always@(posedge clk)
        if(ce == `RomDisable)
            pc = `Zero;
 		else if(jCe == `Valid)//J型
            pc = jAddr;

        else
            pc = pc + 4;
endmodule

3 ID 译码

ID.v

`include "define.v";

//ID 译码模块
//2、为操作数做准备

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//后面的end
			    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 = `Valid;
		                    regbRead = `Invalid;
		                    regcWrite = `Valid;
		                    regaAddr = inst[25:21];
		                    regbAddr = `Zero;
		                    regcAddr = inst[20:16];
		                    imm = {inst[15:0],16'h0};
	                  	end
					`Inst_reg:
	        		    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]};//移位复用imm
								        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]};//移位复用imm
								        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]};//移位复用imm
								        end
	
	
								//JR型指令
								`Inst_jr:
					 					begin
					   						op = `J;
					   						regaRead = `Valid;//需要读rs
					   						regbRead = `Invalid;
					   						regcWrite = `Invalid;
				   							regaAddr = inst[25:21];
					  	 					regbAddr = `Zero;
					 	 					regcAddr = `Zero;
				   							jAddr = regaData;//regaData=(regaAddr)
			        	        			jCe = `Valid;
				   							imm = `Zero;
				 						end
	
								`Inst_jalr:
					 					begin
					   						op = `Jal;
					   						regaRead = `Valid;
					   						regbRead = `Invalid;
					   						regcWrite = `Valid;
				   							regaAddr = inst[25:21];
					   						regbAddr = `Zero;
					  						regcAddr = 5'b11111;
				   							jAddr = regaData;
			                				jCe = `Valid;
				   							imm = npc;//regbData中存imm npc
				 						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;//需要把npc写入R31中
				   			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};
										
							if(regaData==regbData)
					            jCe = `Valid;//等于有效
							else
								jCe = `Invalid;
						   	imm = `Zero;
					 	end		
					`Inst_bne:
						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};
									
							if(regaData!=regbData)
				                jCe = `Valid;//等于有效
							else
								jCe = `Invalid;
					   		imm = `Zero;
					 	end		
					`Inst_bltz:
						begin
						   	op = `Bltz;
						   	regaRead = `Valid;
						   	regbRead = `Valid;//若regbRead无效,则regbData=imm=0
						   	regcWrite = `Invalid;
					   		regaAddr = inst[25:21];
						   	regbAddr = inst[20:16];
						  	regcAddr = `Zero;
					   		jAddr = npc+{{14{inst[15]}},inst[15:0], 2'b00};
									
							if(regaData<regbData)
				                jCe = `Valid;//小于有效
							else
								jCe = `Invalid;
					   		imm = 32'b0;
					 	end		
		
					`Inst_bgtz:
						begin
						   	op = `Bgtz;
						   	regaRead = `Valid;
						   	//regbRead = `Valid;//若regbRead有效,则regbData=(regbAddr)
							regbRead = `Invalid;//若regbRead无效,则regbData=imm=0
						   	regcWrite = `Invalid;
					   		regaAddr = inst[25:21];
						   	regbAddr = inst[20:16];
						  	regcAddr = `Zero;
					   		jAddr = npc+{{14{inst[15]}},inst[15:0], 2'b00};
									
							if(regaData>regbData)
				               	jCe = `Valid;//大于有效
							else
								jCe = `Invalid;
					   		imm = 32'b0;
					 	end		
				 	//Load Store指令
				    `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
   
	/*
	//二选一 regaData= regaData_i : imm
	always@(*)
      if(rst == `RstEnable)
          regaData = `Zero;
      else if(regaRead == `Valid)
          regaData = regaData_i;
      else	
          regaData = imm;
	
   //二选一 regbData= regbData_i : 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

4 EX 执行

EX.v

`include "define.v";
//3、执行指令模块

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

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

	always@(*)
        if(rst == `RstEnable)
              regcData = `Zero;
        else
            //case(op)
            case(op_i)
                `Or:
                    regcData = regaData | regbData;
				`And:
		    		regcData = regaData & regbData;
				`Xor:
		    		regcData = regaData ^ regbData;
				`Add:
		    		regcData = regaData + regbData;
				`Sub:
		    		regcData = regaData - regbData;
				`Lui:
		    		regcData = regaData | regbData;
      
             	`Sll:
                	regcData = regbData << regaData;
              	`Srl:
                	regcData = regbData >> regaData;
				`Sra:
					regcData = ($signed(regbData)) >>> regaData;
				
				//J- JR型
				`J:
					regcData = `Zero;
				`Jal:
                    regcData = regbData;//regaData有其他用处  jr给pc=jaddr=(rs)

				//J+型
				`Beq:
					regcData = `Zero;
				`Bne:
					regcData = `Zero;
				`Bltz:
					regcData = `Zero;
				`Bgtz:
					regcData = `Zero;


                default:
                    regcData = `Zero;
            endcase      
	assign regcWrite = regcWrite_i;
	assign regcAddr = regcAddr_i;
endmodule

5 访存 MEM

MEM.v

`include "define.v";
//访存(mem)模块设计
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

6 DataMem 数据存储器

DataMem.v

`include "define.v";
//数据存储器(DataMem)模块设计
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

7 RegFile 存取

RegFile .v

`include "define.v";
//4、为操作数取值存值模块
//取值 regaData regbData
//存值 wdata
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 == `RstDisable)
            if((we == `Valid) && (waddr != `Zero))
                reg32[waddr] = wdata;
	    	else ;
        else ;
          
endmodule

8 MIPS 封装

MIPS.v

`include "define.v";
//5、MIPS封装
//修改EX实例化,新增Mem实例化

//新增端口rdData wtData memAddr memCe memWr
//原op变为op_i
//新增ls内部变量
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;

    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实例化
    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
    );    

	//新增Mem实例化
	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实例化
    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

9 InstMem 指令存储器

InstMem.v

`include "define.v";
//6、指令存储器
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
		//初始化数据
		//ori R0,1100 -- R1 --00001100
        instmem [0] = 32'h34011100;
		//ori R0,0020 -- R2 --00000020
        instmem [1] = 32'h34020020;
		//ori R0,ff00 -- R3 --0000ff00
        instmem [2] = 32'h3403ff00;
		//ori R0,ffff -- R4 --0000ffff
        instmem [3] = 32'h3404ffff;
		
		//I型指令测试
/*
		//andi R0,ffff --R5 --00000000
		instmem [4] = 32'h3005ffff;
		//xori R0,ffff --R6 --0000ffff
		instmem [5] = 32'h3806ffff;
		//addi R0,ffff --R7 --ffffffff
		instmem [6] = 32'h2007ffff;
		//subi R0,ffff --R8 --00000001
		instmem [7] = 32'h2408ffff;
		//lui  R0,ffff --R9 --ffff0000
		instmem [8] = 32'h3C09ffff;
*/
		
		//R1=00001100 R2=00000020
		instmem [4] = 32'b000000_00001_00010_00101_00000_100000;//add,R5,R1,R2  00001120
		instmem [5] = 32'b000000_00001_00010_00110_00000_100101;//or,R6,R1,R2   00001120

		//R型指令测试
/*
		instmem [6] = 32'b000000_00001_00010_00111_00000_100010;//sub,R7,R1,R2  000010e0
		instmem [7] = 32'b000000_00001_00010_01000_00000_100100;//and,R8,R1,R2  00000000
		instmem [8] = 32'b000000_00001_00010_01001_00000_100110;//xor,R9,R1,R2  00001120

		//lui  R0,ffff --R10 --ffff0000
		instmem [9] = 32'h3C0Affff;

		
		//R11=fffe0000 R12=7fff8000  R13=ffff8000
		// Ra=sa={25'b0,imm[10:6]}
		instmem [10] = 32'b000000_00000_01010_01011_00001_000000;//sll,R11,Ra,R10
		instmem [11] = 32'b000000_00000_01010_01100_00001_000010;//srl,R12,Ra,R10  		
		instmem [12] = 32'b000000_00000_01010_01101_00001_000011;//sra,R13,Ra,R10
*/

		//J- JR型指令测试
/*
		//pc=jaddr=npc(4) offset(26) 00(2)
		//instmem [6] = 32'h08000001;  	//j 1		编码000010  pc=0004 	
		instmem [6] = 32'h0C000002; 	//jal 2		编码000011  pc=0008	
*/

/*
		//pc=jaddr=(rs)
		instmem [6] = 32'h3407000C;//ori,R7,000C
		//instmem [7] = 32'b000000_00111_00000_00000_00000_001000; //jr R7		编码001000 pc=0000000C
		instmem [7] = 32'b000000_00111_00000_00000_00000_001001; //jalr R7 编码001001 pc=0000000C R31=00000020
*/

/*
		//J+型指令测试
		//pc=jaddr=npc+S14 offset(16) 00(2)
		//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
		//instmem [6] = 32'b000100_00101_00110_0000_0000_0000_0000;  //beq r5,r6,0 		编码000100  pc=001C 
		//instmem [6] = 32'b000100_00101_00110_0000_0000_0000_0001;  //beq r5,r6,1 		编码000100  pc=0020 
		//instmem [6] = 32'b000101_00001_00110_1111_1111_1111_1110;  //bne r5,r6,-2 		编码000101  pc=0014 
				
		//instmem [6] = 32'b000001_00010_00000_0000_0000_0000_0001;  //bltz r2,r0,1 		编码000001 pc=0020 
		instmem [6] = 32'b000111_00001_00000_1111_1111_1111_1110;  //bgtz r1,r0,-2 		编码010011 pc=0014 			

		//ori R7,0001 -- R7 --00000001
        instmem [7] = 32'h34070001;	//ori  R7 1
		//ori R8,0001 -- R7 --00000001
        instmem [8] = 32'h34080001;	//ori  R8 1
*/



		//(r1)=0000 1100
		//    +0000 0018
		//addr=0000 1118  
		//    =1000100011000 字节地址
		//    =100 0100 0110 字地址
		//	  =446H	         只有1K空间
		//    =46H		     丢掉了高位的1位
		//    =70
		//mem[70]=(r6)
		instmem[6]=32'b101011_00001_00110_0000_0000_0001_1000; //sw r6,0x18(r1)
		//(r7)=mem[70]
		instmem[7]=32'b100011_00001_00111_0000_0000_0001_1000; //lw r7,0x18(r1)



      end
endmodule

10 SOC 顶层

SOC.v

//7、系统封装
//整合MIPS DataMem InstMem
//端口信号只需clk rst,其余信号在MIPS中增加,并且新增使用内部信号连线
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实例
    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

11 soc_tb 测试

soc_tb.v

`include "define.v";
//8、测试系统
module soc_tb;
    reg clk;
    reg rst;
    initial
      begin
        clk = 0;
        rst = `RstEnable;
        #100
        rst = `RstDisable;
        #1000 $stop;        
      end
    always #10 clk = ~ clk;
    SoC soc0(
        .clk(clk), 
        .rst(rst)
    );
endmodule

最后

2023-5-22 14:30:22

你对我百般注视,
并不能构成万分之一的我,
却是一览无余的你。

祝大家逢考必过
点赞收藏关注哦文章来源地址https://www.toymoban.com/news/detail-467067.html

到了这里,关于2模型计算机各功能电路设计【FPGA模型机课程设计】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包