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

阅读: 评论:0

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

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

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

  • 前言
  • 推荐
    • 参考
  • 2模型计算机各功能电路设计
    • 安排
    • 20条MIPS整数指令
    • 测试与结果
      • 初始化数据
      • I型指令测试
      • R型指令测试
      • J型指令测试
      • 访存指令测试
  • 附录
    • 0 框架
    • 1 define 编码
    • 2 IF 取指
    • 3 ID 译码
    • 4 EX 执行
    • 5 访存 MEM
    • 6 DataMem 数据存储器
    • 7 RegFile 存取
    • 8 MIPS 封装
    • 9 InstMem 指令存储器
    • 10 SOC 顶层
    • 11 soc_tb 测试
  • 最后

前言

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整数指令

测试与结果

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

初始化数据

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

I型指令测试

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

R型指令测试

		//R型指令测试instmem [6] = 32'b000000_00001_00010_00111_00000_100010;//sub,R7,R1,R2  000010e0instmem [7] = 32'b000000_00001_00010_01000_00000_100100;//and,R8,R1,R2  00000000instmem [8] = 32'b000000_00001_00010_01001_00000_100110;//xor,R9,R1,R2  00001120//lui  R0,ffff --R10 --ffff0000instmem [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,R10instmem [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型指令测试

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

		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=0000000Cinstmem [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

		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 --00000001instmem [7] = 32'h34070001;	//ori  R7 1//ori R8,0001 -- R8 --00000001instmem [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位置

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

跳转到相对于npc的+1位置

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

跳转到相对于npc的-2位置

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

跳转到相对于npc的+1位置

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

跳转到相对于npc的-2位置

访存指令测试

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

附录

0 框架

顶层设计

代码框架


主要对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;elsece = `RomEnable;//程序执行 pc+=4always@(posedge clk)if(ce == `RomDisable)pc = `Zero;else if(jCe == `Valid)//J型pc = jAddr;elsepc = 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)beginop = `Nop;            regaRead = `Invalid;regbRead = `Invalid;regcWrite = `Invalid;regaAddr = `Zero;regbAddr = `Zero;regcAddr = `Zero;imm    = `Zero;jCe = `Invalid;//J型jAddr = `Zero;//J型endelse begin//后面的endjCe = `Invalid;//J型jAddr = `Zero;//J型case(inst_op)`Inst_ori:beginop = `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:beginop = `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:beginop = `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:beginop = `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:beginop = `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:beginop = `Add;  regaRead = `Valid;regbRead = `Valid;regcWrite = `Valid;regaAddr = inst[25:21];regbAddr = inst[20:16];regcAddr = inst[15:11];imm = `Zero;end`Inst_or:beginop = `Or;regaRead = `Valid;regbRead = `Valid;regcWrite = `Valid;regaAddr = inst[25:21];regbAddr = inst[20:16];regcAddr = inst[15:11];imm = `Zero;end`Inst_sub:beginop = `Sub;regaRead = `Valid;regbRead = `Valid;regcWrite = `Valid;regaAddr = inst[25:21];regbAddr = inst[20:16];regcAddr = inst[15:11];imm = `Zero;end`Inst_and:beginop = `And;regaRead = `Valid;regbRead = `Valid;regcWrite = `Valid;regaAddr = inst[25:21];regbAddr = inst[20:16];regcAddr = inst[15:11];imm = `Zero;end`Inst_xor:beginop = `Xor;regaRead = `Valid;regbRead = `Valid;regcWrite = `Valid;regaAddr = inst[25:21];regbAddr = inst[20:16];regcAddr = inst[15:11];imm = `Zero;end`Inst_sll:beginop = `Sll;regaRead = `Invalid;regbRead = `Valid;regcWrite = `Valid;regaAddr = `Zero;regbAddr = inst[20:16];regcAddr = inst[15:11];imm = {27'b0,inst[10:6]};//移位复用immend`Inst_srl:beginop = `Srl;regaRead = `Invalid;regbRead = `Valid;regcWrite = `Valid;regaAddr = `Zero;regbAddr = inst[20:16];regcAddr = inst[15:11];imm = {27'b0,inst[10:6]};//移位复用immend`Inst_sra:beginop = `Sra;regaRead = `Invalid;regbRead = `Valid;regcWrite = `Valid;regaAddr = `Zero;regbAddr = inst[20:16];regcAddr = inst[15:11];imm = {27'b0,inst[10:6]};//移位复用immend//JR型指令`Inst_jr:beginop = `J;regaRead = `Valid;//需要读rsregbRead = `Invalid;regcWrite = `Invalid;regaAddr = inst[25:21];regbAddr = `Zero;regcAddr = `Zero;jAddr = regaData;//regaData=(regaAddr)jCe = `Valid;imm = `Zero;end`Inst_jalr:beginop = `Jal;regaRead = `Valid;regbRead = `Invalid;regcWrite = `Valid;regaAddr = inst[25:21];regbAddr = `Zero;regcAddr = 5'b11111;jAddr = regaData;jCe = `Valid;imm = npc;//regbData中存imm npcenddefault:beginregaRead = `Invalid;regbRead = `Invalid;regcWrite = `Invalid;regaAddr = `Zero;regbAddr = `Zero;regcAddr = `Zero;imm = `Zero;endendcase//J型指令`Inst_j:beginop = `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:beginop = `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:beginop = `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;//等于有效elsejCe = `Invalid;imm = `Zero;end		`Inst_bne:beginop = `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;//等于有效elsejCe = `Invalid;imm = `Zero;end		`Inst_bltz:beginop = `Bltz;regaRead = `Valid;regbRead = `Valid;//若regbRead无效,则regbData=imm=0regcWrite = `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;//小于有效elsejCe = `Invalid;imm = 32'b0;end		`Inst_bgtz:beginop = `Bgtz;regaRead = `Valid;//regbRead = `Valid;//若regbRead有效,则regbData=(regbAddr)regbRead = `Invalid;//若regbRead无效,则regbData=imm=0regcWrite = `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;//大于有效elsejCe = `Invalid;imm = 32'b0;end		//Load Store指令`Inst_lw:beginop = `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:beginop = `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:beginop = `Nop;                    regaRead = `Invalid;regbRead = `Invalid;regcWrite = `Invalid;regaAddr = `Zero;regbAddr = `Zero;regcAddr = `Zero;imm = `Zero;endendcase end/*//二选一 regaData= regaData_i : immalways@(*)if(rst == `RstEnable)regaData = `Zero;else if(regaRead == `Valid)regaData = regaData_i;else	regaData = imm;//二选一 regbData= regbData_i : immalways@(*)if(rst == `RstEnable)regbData = `Zero;      else if(regbRead == `Valid)regbData = regbData_i;elseregbData = 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        elsecase(op)                `Lw:                  begin                    wtData = `Zero;                        memWr = `RamUnWrite;                     memCe = `RamEnable;                    end                `Sw:                  begin                    wtData = memData;                    memWr = `RamWrite;                      memCe = `RamEnable;                   enddefault:                  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;elserdData = 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;elseregaData = 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,//lsoutput wire romCe,output wire [31:0] instAddr,output wire [31:0] wtData,//lsoutput wire [31:0] memAddr,//lsoutput wire memCe,//lsoutput 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;//lswire [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;elsedata = instmem[addr[11 : 2]];   initialbegin//初始化数据//ori R0,1100 -- R1 --00001100instmem [0] = 32'h34011100;//ori R0,0020 -- R2 --00000020instmem [1] = 32'h34020020;//ori R0,ff00 -- R3 --0000ff00instmem [2] = 32'h3403ff00;//ori R0,ffff -- R4 --0000ffffinstmem [3] = 32'h3404ffff;//I型指令测试
/*//andi R0,ffff --R5 --00000000instmem [4] = 32'h3005ffff;//xori R0,ffff --R6 --0000ffffinstmem [5] = 32'h3806ffff;//addi R0,ffff --R7 --ffffffffinstmem [6] = 32'h2007ffff;//subi R0,ffff --R8 --00000001instmem [7] = 32'h2408ffff;//lui  R0,ffff --R9 --ffff0000instmem [8] = 32'h3C09ffff;
*///R1=00001100 R2=00000020instmem [4] = 32'b000000_00001_00010_00101_00000_100000;//add,R5,R1,R2  00001120instmem [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  000010e0instmem [7] = 32'b000000_00001_00010_01000_00000_100100;//and,R8,R1,R2  00000000instmem [8] = 32'b000000_00001_00010_01001_00000_100110;//xor,R9,R1,R2  00001120//lui  R0,ffff --R10 --ffff0000instmem [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,R10instmem [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=0000000Cinstmem [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 --00000001instmem [7] = 32'h34070001;	//ori  R7 1//ori R8,0001 -- R7 --00000001instmem [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;//lswire 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;initialbeginclk = 0;rst = `RstEnable;#100rst = `RstDisable;#1000 $stop;        endalways #10 clk = ~ clk;SoC soc0(.clk(clk), .rst(rst));
endmodule

最后

2023-5-22 14:30:22

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

祝大家逢考必过
点赞收藏关注哦

本文发布于:2024-01-31 16:37:32,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170669025229902.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23