2023-5-23 08:02:23
以下内容源自《【FPGA模型机课程设计】》
仅供学习交流使用
0集中实践环节计划书【FPGA模型机课程设计】
第一周周三:
模型机指令系统设计。学生根据搭建的模型机数据通路图,选择扩展的指令格式和指令功能。扩展指令系统的选择可以参照MIPS 32位处理器指令集,选择MIPS12条整数指令。要求能够画出指令格式和指令功能,能够画出处理器内部实现结构图,包括时序信号和控制信号,可以采用单周期方案。
实现了前4条指令
其中234上篇文章已实现
此篇文章实现slt
slt指令 --比较运算用法:slt rd,rs,rt作用:rd <- (rs<rt)将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值按照有符号数进行比较,
若前者小于后者,那么将1保存到地址为rd的通用寄存器;若前者大于后者,则将0保存到地址为rd的通用寄存器中。
//测试12条MIPS指令//测试slt//R1=00001100 R2=00000020instmem [6] = 32'b000000_00001_00010_00111_00000_101010;//slt,R7,R1,R2 00000000//lui R0,ffff --R8 --ffff0000instmem [7] = 32'h3C08ffff;//ori R8,ffff --R8 --ffffffffinstmem [8] = 32'b001101_01000_01000_1111_1111_1111_1111;//lui R0,ffff --R9 --ffff0000instmem [9] = 32'h3C09ffff;//ori R9,ffff --R9 --fffffffeinstmem [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
添加编码
//MIPS 扩展整数指令集
//表2 MIPS 12条整数指令
`define Inst_slt 6'b101010 //上一个文章此处少写个b//内部供EX的编码
`define Slt 6'b010010
在R型扩展编码中加入
//12条整数指令`Inst_slt:beginop = `Slt;regaRead = `Valid;regbRead = `Valid;regcWrite = `Valid;regaAddr = inst[25:21];regbAddr = inst[20:16];regcAddr = inst[15:11];im
加入
//12条整数指令`Slt:beginif($signed(regaData)<$signed(regbData))regcData={{31{0}},1};elseregcData={32{0}};end
添加测试指令
//测试12条MIPS指令//测试slt//R1=00001100 R2=00000020instmem [6] = 32'b000000_00001_00010_00111_00000_101010;//slt,R7,R1,R2 00000000//lui R0,ffff --R8 --ffff0000instmem [7] = 32'h3C08ffff;//ori R8,ffff --R8 --ffffffffinstmem [8] = 32'b001101_01000_01000_1111_1111_1111_1111;//lui R0,ffff --R9 --ffff0000instmem [9] = 32'h3C09ffff;//ori R9,ffff --R9 --fffffffeinstmem [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
其余与上篇一样
//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_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`define Slt 6'b010010
`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 npcend//12条整数指令`Inst_slt:beginop = `Slt;regaRead = `Valid;regbRead = `Valid;regcWrite = `Valid;regaAddr = inst[25:21];regbAddr = inst[20:16];regcAddr = inst[15:11];imm = `Zero;end default: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
`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:beginregcData = 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:beginif($signed(regaData)<$signed(regbData))regcData={{31{0}},1};elseregcData={32{0}};enddefault:regcData = `Zero;endcase assign regcWrite = regcWrite_i;assign regcAddr = regcAddr_i;
endmodule
`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 --00000001
// instmem [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 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
*//*//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
*//*//(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=00000020instmem [6] = 32'b000000_00001_00010_00111_00000_101010;//slt,R7,R1,R2 00000000//lui R0,ffff --R8 --ffff0000instmem [7] = 32'h3C08ffff;//ori R8,ffff --R8 --ffffffffinstmem [8] = 32'b001101_01000_01000_1111_1111_1111_1111;//lui R0,ffff --R9 --ffff0000instmem [9] = 32'h3C09ffff;//ori R9,ffff --R9 --fffffffeinstmem [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 00000001end
endmodule
2023-5-22 10:11:05
你对我百般注视,
并不能构成万分之一的我,
却是一览无余的你。
祝大家逢考必过
点赞收藏关注哦
本文发布于:2024-01-31 16:37:22,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170669024229901.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |