3模型机指令系统设计-3【FPGA模型机课程设计】

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

前言

2023-5-23 15:48:49

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

推荐

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

3模型机指令系统设计-3

安排

第一周周三:

模型机指令系统设计。学生根据搭建的模型机数据通路图,选择扩展的指令格式和指令功能。扩展指令系统的选择可以参照MIPS 32位处理器指令集,选择MIPS12条整数指令。要求能够画出指令格式和指令功能,能够画出处理器内部实现结构图,包括时序信号和控制信号,可以采用单周期方案。

MIPS 12条整数指令

上篇实现了乘除相关指令
此篇文章实现后面四条指令
3模型机指令系统设计-3【FPGA模型机课程设计】

测试与结果

		//测试剩余4条指令
		//R1=00001100 R2=00000020 
		//mthi,R1--hi=00001100
		instmem [6] = 32'b000000_00001_00000_00000_00000_010001;//mthi,R1
		//mtlo,R2--lo=00000020 
		instmem [6] = 32'b000000_00010_00000_00000_00000_010011;//mtlo,R2
		//mfhi,R7--R7=00001100
		instmem [6] = 32'b000000_00000_00000_00111_00000_010001;//mfhi,R7
		//mflo,R8--R8=00000020 
		instmem [6] = 32'b000000_00000_00000_01000_00000_010011;//mflo,R8

3模型机指令系统设计-3【FPGA模型机课程设计】

代码设计

define

//MIPS 扩展整数指令集
//表2 MIPS 12条整数指令
`define Inst_mfhi 6'b010000	 //r 
`define Inst_mflo 6'b010010	 //r 
`define Inst_mthi 6'b010001	 //r 
`define Inst_mtlo 6'b010011	 //r 

//内部供EX的编码
`define Mfhi 6'b010111
`define Mflo 6'b011000
`define Mthi 6'b011001
`define Mtlo 6'b011010

ID

R型扩展编码中添加

									//后4条指令
									`Inst_mfhi:
						 				begin
							 				op = `Mfhi;
						      				regaRead = `Invalid;
							  				regbRead = `Invalid;
							  				regcWrite = `Valid;//从HILO寄存器中,写到通用寄存器中
							  				regaAddr = `Zero;
							  				regbAddr = `Zero;
							  				regcAddr = inst[15:11];
							  				imm = `Zero;//HiLo的数据在EX中得到
						 				end		
									`Inst_mflo:
						 				begin
							 				op = `Mflo;
						      				regaRead = `Invalid;
							  				regbRead = `Invalid;
							  				regcWrite = `Valid;//从HILO寄存器中,写到通用寄存器中
							  				regaAddr = `Zero;
							  				regbAddr = `Zero;
							  				regcAddr = inst[15:11];
							  				imm = `Zero;//HiLo的数据在EX中得到
						 				end		
									`Inst_mthi:
						 				begin
							 				op = `Mthi;
						      				regaRead = `Valid;//从通用寄存器读出
							  				regbRead = `Invalid;
							  				regcWrite = `Invalid;
							  				regaAddr = inst[25:21];//写到HILO寄存器中,而不是通用寄存器中
							  				regbAddr = `Zero;
							  				regcAddr = `Zero;
							  				imm = `Zero;
						 				end		
									`Inst_mtlo:
						 				begin
							 				op = `Mtlo;
						      				regaRead = `Valid;//从通用寄存器读出
							  				regbRead = `Invalid;
							  				regcWrite = `Invalid;//写到HILO寄存器中,而不是通用寄存器中			
							  				regaAddr = inst[25:21];
							  				regbAddr = `Zero;
							  				regcAddr = `Zero;
							  				imm = `Zero;
						 				end		

EX

添加功能

				//剩余4条指令
				`Mfhi:				
					regcData = rHiData;
				`Mflo:				
					regcData = rLoData;
				`Mthi:				
					wHiData = regaData;
				`Mtlo:				
					wLoData = regaData;

InstMem

测试

		//测试剩余4条指令
		//R1=00001100 R2=00000020 
		//mthi,R1--hi=00001100
		instmem [6] = 32'b000000_00001_00000_00000_00000_010001;//mthi,R1
		//mtlo,R2--lo=00000020 
		instmem [6] = 32'b000000_00010_00000_00000_00000_010011;//mtlo,R2
		//mfhi,R7--R7=00001100
		instmem [6] = 32'b000000_00000_00000_00111_00000_010001;//mfhi,R7
		//mflo,R8--R8=00000020 
		instmem [6] = 32'b000000_00000_00000_01000_00000_010011;//mflo,R8

3模型机指令系统设计-3【FPGA模型机课程设计】

附录

其余与上篇一样

1 define 编码

//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'b101010
`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_divu 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

`define Slt  6'b010010
`define Mult 6'b010011
`define Multu 6'b010100
`define Div 6'b010101
`define Divu 6'b010110

`define Mfhi 6'b010111
`define Mflo 6'b011000
`define Mthi 6'b011001
`define Mtlo 6'b011010

3 ID 译码

`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
						
									//12条整数指令
									`Inst_slt:
						 				begin
							 				op = `Slt;
						      				regaRead = `Valid;
							  				regbRead = `Valid;
							  				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;//写到HILO寄存器中,而不是通用寄存器中
							  				regaAddr = inst[25:21];
							  				regbAddr = inst[20:16];
							  				regcAddr = `Zero;
							  				imm = `Zero;
						 				end		
									`Inst_multu:
						 				begin
							 				op = `Multu;
						      				regaRead = `Valid;
							  				regbRead = `Valid;
							  				regcWrite = `Invalid;//写到HILO寄存器中,而不是通用寄存器中
							  				regaAddr = inst[25:21];
							  				regbAddr = inst[20:16];
							  				regcAddr = `Zero;
							  				imm = `Zero;
						 				end		
									`Inst_div:
						 				begin
							 				op = `Div;
						      				regaRead = `Valid;
							  				regbRead = `Valid;
							  				regcWrite = `Invalid;//写到HILO寄存器中,而不是通用寄存器中
							  				regaAddr = inst[25:21];
							  				regbAddr = inst[20:16];
							  				regcAddr = `Zero;
							  				imm = `Zero;
						 				end		
									`Inst_divu:
						 				begin
							 				op = `Divu;
						      				regaRead = `Valid;
							  				regbRead = `Valid;
							  				regcWrite = `Invalid;//写到HILO寄存器中,而不是通用寄存器中
							  				regaAddr = inst[25:21];
							  				regbAddr = inst[20:16];
							  				regcAddr = `Zero;
							  				imm = `Zero;
						 				end		
									//后4条指令
									`Inst_mfhi:
						 				begin
							 				op = `Mfhi;
						      				regaRead = `Invalid;
							  				regbRead = `Invalid;
							  				regcWrite = `Valid;//从HILO寄存器中,写到通用寄存器中
							  				regaAddr = `Zero;
							  				regbAddr = `Zero;
							  				regcAddr = inst[15:11];
							  				imm = `Zero;//HiLo的数据在EX中得到
						 				end		
									`Inst_mflo:
						 				begin
							 				op = `Mflo;
						      				regaRead = `Invalid;
							  				regbRead = `Invalid;
							  				regcWrite = `Valid;//从HILO寄存器中,写到通用寄存器中
							  				regaAddr = `Zero;
							  				regbAddr = `Zero;
							  				regcAddr = inst[15:11];
							  				imm = `Zero;//HiLo的数据在EX中得到
						 				end		
									`Inst_mthi:
						 				begin
							 				op = `Mthi;
						      				regaRead = `Valid;//从通用寄存器读出
							  				regbRead = `Invalid;
							  				regcWrite = `Invalid;//写到HILO寄存器中,而不是通用寄存器中
							  				regaAddr = inst[25:21];	
							  				regbAddr = `Zero;
							  				regcAddr = `Zero;
							  				imm = `Zero;
						 				end		
									`Inst_mtlo:
						 				begin
							 				op = `Mtlo;
						      				regaRead = `Valid;//从通用寄存器读出
							  				regbRead = `Invalid;
							  				regcWrite = `Invalid;//写到HILO寄存器中,而不是通用寄存器中			
							  				regaAddr = inst[25:21];
							  				regbAddr = `Zero;
							  				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;//需要把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 执行

`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,
        input wire [31:0] rHiData,//乘除 读hi数据
        input wire [31:0] rLoData,//乘除 读hi数据
        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,
    	output reg whi,	//乘除 写hi使能
   		output reg wlo,	//乘除 写lo使能
   		output reg [31:0] wHiData,	//乘除 写hi数据
   		output reg [31:0] wLoData  //乘除 写lo数据
    );    

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

	always@(*)
        if(rst == `RstEnable)
			begin
              	regcData = `Zero;
				whi=`Invalid;
				wlo=`Invalid;
			  	wHiData=`Zero;
			  	wLoData=`Zero;
			end
        else
		  begin
            regcData = `Zero;
			whi=`Invalid;
		    wlo=`Invalid;
			wHiData=`Zero;
			wLoData=`Zero;
		  	  		
            //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:
					begin
		    			regcData = regaData | regbData;
					end
      
             	`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;
				//12条整数指令
				`Slt:
					begin
						if($signed(regaData)<$signed(regbData))
							regcData={{31{0}},1};
						else
							regcData={32{0}};
					end
				//乘除指令
				`Mult:
					begin
						whi=`Valid;
						wlo=`Valid;
						{wHiData,wLoData}=
							$signed(regaData)*$signed(regbData);
					end
				`Multu:
					begin
						whi=`Valid;
						wlo=`Valid;
						{wHiData,wLoData}=regaData*regbData;
					end
				`Div:
					begin
						whi=`Valid;
						wlo=`Valid;
						wHiData=$signed(regaData)%$signed(regbData);
						wLoData=$signed(regaData)/$signed(regbData);
					end
				`Divu:
					begin
						whi=`Valid;
						wlo=`Valid;
						wHiData=regaData%regbData;
						wLoData=regaData/regbData;
					end
				//剩余4条指令
				`Mfhi:				
					regcData = rHiData;
				`Mflo:				
					regcData = rLoData;
				`Mthi:		
					begin		
						whi=`Valid;
						wHiData = regaData;
					end
				`Mtlo:		
					begin		
						wlo=`Valid;		
						wLoData = regaData;
					end
                default:
                    regcData = `Zero;
            endcase   
		  end   
	assign regcWrite = regcWrite_i;
	assign regcAddr = regcAddr_i;
endmodule

9 InstMem 指令存储器

`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	r31=npc001c
*/

/*
		//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 -- R8 --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)
*/


		//测试12条MIPS指令

/*
		//测试slt
		//R1=00001100 R2=00000020
	  	instmem [6] = 32'b000000_00001_00010_00111_00000_101010;//slt,R7,R1,R2   00000000
		//lui  R0,ffff --R8 --ffff0000
		instmem [7] = 32'h3C08ffff;
		//ori R8,ffff --R8 --ffffffff
		instmem [8] = 32'b001101_01000_01000_1111_1111_1111_1111;
		//lui  R0,ffff --R9 --ffff0000
		instmem [9] = 32'h3C09ffff;
		//ori R9,ffff --R9 --fffffffe
		instmem [10] = 32'b001101_01001_01001_1111_1111_1111_1110;
		//R8=ffffffff(-1) R9=fffffffe(-2)
	  	instmem [11] = 32'b000000_01001_01000_01010_00000_101010;//slt,R10,R9,R8   00000001
*/

/*
		//测试乘除
		//R1=00001100 R2=00000020 
		//multu,R1,R2 0_22000
		instmem [6] = 32'b000000_00001_00010_00111_00000_011001;//multu,R1,R2
		//ori R7,ffff -- R7 --0000ffff
        instmem [7] = 32'h3407ffff;	//ori  R7 ffff
		//sll R7,R7,10h -- R7 --ffff0000
        instmem [8] = 32'b000000_00000_00111_00111_10000_000000;//sll R7,R7,10h
		//mult R7,R2  	ffffffff_ffe00000
        instmem [9] = 32'b000000_00111_00010_00000_00000_011000;//mult R7,R2
		//divu r1,r2	88_0
        instmem [10] = 32'b000000_00001_00010_00000_00000_011011;//divu r1,r2
		//div r3,r2 	fffff800_0
        instmem [11] = 32'b000000_00111_00010_00000_00000_011010;//div r7,r2
*/
		//测试剩余4条指令
		//R1=00001100 R2=00000020 
		//mthi,R1--hi=00001100
		instmem [6] = 32'b000000_00001_00000_00000_00000_010001;//mthi,R1
		//mtlo,R2--lo=00000020 
		instmem [7] = 32'b000000_00010_00000_00000_00000_010011;//mtlo,R2
		//mfhi,R7--R7=00001100
		instmem [8] = 32'b000000_00000_00000_00111_00000_010000;//mfhi,R7
		//mflo,R8--R8=00000020 
		instmem [9] = 32'b000000_00000_00000_01000_00000_010010;//mflo,R8

      end
endmodule

最后

2023-5-23 16:41:01

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

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

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

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

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

相关文章

  • 4实现中断异常相关指令-1【FPGA模型机课程设计】

    2023-5-23 16:43:50 以下内容源自《【FPGA模型机课程设计】》 仅供学习交流使用 0集中实践环节计划书【FPGA模型机课程设计】 修改于2023-5-26 14:45:16 此处SC功能实现有问题 SC的 rt-1 不能在EX中实现 需要放入到MEM中 需要知道操作是否成功 得到rt-1(成功)或者rt-0(失败) 而不是在

    2024年02月11日
    浏览(33)
  • 5模型机整体的联调【FPGA模型机课程设计】

    2023-5-25 08:15:05 以下内容源自《【FPGA模型机课程设计】》 仅供学习交流使用 0集中实践环节计划书【FPGA模型机课程设计】 第一周周五: 模型机整体的联调。完成模型机指令系统实现。学生根据设计好的指令系统实现方案,在Modelsim上进行功能仿真。要求将所有设计的机器指令

    2024年02月08日
    浏览(29)
  • 2模型计算机各功能电路设计【FPGA模型机课程设计】

    2023-5-22 10:18:30 以下内容源自《【FPGA模型机课程设计】》 仅供学习交流使用 0集中实践环节计划书【FPGA模型机课程设计】 简单的指令设计 MIPS CPU 设计【计算机组成原理】 详细的指令设计 MIPS CPU 设计+【计算机组成原理】 测试结果具体分析可以查看: 实验三+ I型指令设计实验

    2024年02月07日
    浏览(29)
  • 单周期-开发过程【FPGA模型机课程设计】

    2023-5-25 08:24:28 以下内容源自《【FPGA模型机课程设计】》 仅供学习交流使用 0集中实践环节计划书【FPGA模型机课程设计】 工程迭代过程 README.txt 1FPGA模型计算机整体方案设计【FPGA模型机课程设计】 2模型计算机各功能电路设计【FPGA模型机课程设计】 实现基本20条指令 3模型机

    2024年02月09日
    浏览(31)
  • 数字系统设计(FPGA)课程设计: 多功能数字钟

    一、目的: 实现多功能数字钟,具备下列功能: 1、数字钟:能计时,实现小时、分钟、秒的显示; 2、数字跑表:精度至0.01秒 比如显示12.97秒; 3、闹钟: 可以设定闹钟,用试验箱上的蜂鸣器作为闹铃; 4、调时:可以对时间进行设定; 5、日期设定:能设定日期并显示当前

    2023年04月18日
    浏览(31)
  • FPGA课程设计--电子门锁的设计

      这是一个关于FPGA的课程设计【只是一个简单的课程设计,并没有涉及很深的FPGA技术知识】,实物测试结果可以参考 FPGA课程设计-电子门锁   视频中使用的板子是睿智助学的开发板,芯片型号为 EP4CE6E22C8 。大家如果用的是其他开发板也可以参考本文章。除了芯片的资源

    2024年02月04日
    浏览(25)
  • 课程学习前言

    app 抓包分析可以看到有签名有加固,毕竟需要 APK 去访问服务、获取数据,都需要 APK 有完整的信息,而这些信息、代码经过各种加密,还是放在 APK 里面。说白了,就是门锁紧了,钥匙藏在门口某个地方,也许就是地垫下面 逆向流程 拿到 App 应用的 apk ; 使用工具进行查壳

    2024年02月06日
    浏览(31)
  • 【FPGA】课程设计:简单计时器闹钟

    本文是EDA实验的课程设计 完整源码文件获取方式见文末 少废话,先看东西。 EDA实验-闹钟演示视频 设计一个电子闹钟。要求电路上电后自动计时,到达预置的闹响时刻后,由蜂鸣器发出音乐报警。闹响时刻可利用按键设置,设置范围0~999999。 此次实验除了满足上述基本功能

    2024年02月04日
    浏览(32)
  • 【免费】【前言】Stable Diffusion WebUI 课程简介

    欢迎来到  聚梦小课堂  的 Stable Diffusion系统图文课堂。 在这里,会详细介绍 免费的本地版AI绘画软件 —— Stable Diffusion(WebUI+Fooocus) 的方方面面,包括但不限于:如何安装,如何使用,参数含义,常见问题,使用技巧、综合商业案例... 使用中若发现有错误或者任何建议,

    2024年02月02日
    浏览(34)
  • 电子技术课程设计基于FPGA的音乐硬件演奏电路的设计与实现

    【ChatGPT】前些天发现了一个巨牛的人工智能学习电子书,通俗易懂,风趣幽默,无广告,忍不住分享一下给大家。(点击查看学习资料) wx供重浩:创享日记 对话框发送:乐曲电路 免费获取完整无水印论文报告(包含电路图) 1、课程设计题目 设计一个乐曲演奏电路,能够

    2024年02月05日
    浏览(43)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包