实验五 JR指令设计实验【计算机组成原理】
- 前言
- 推荐
- 实验五+ J型指令设计实验
- 修改代码
- define
- ID
- EX
- InstMem
- 结果
- beq
- bne
- bltz
- bgtz
- 完整代码
- define
- IF
- ID
- EX
- RegFile
- MIPS
- InstMem
- SoC
- soc_tb
- 最新测试
- ID
- InstMem
- j 1
- jal 2
- jr R7
- jalr R7
- beq r5,r6 0
- beq r5,r6 1
- bne r1,r6 -2
- bltz r2,r3 1
- bgtz r1,-2
- 测试全部J型指令
- 完整InstMem
- 最后
前言
2022/12/6 15:19
以下内容源自计算机组成原理实验
仅供学习交流使用
有能力可以自己做或者参考修改代码
推荐
实验四+ R型指令设计实验【计算机组成原理】
//J型编码
`define Inst_j 6'b000110
`define Inst_jal 6'b000101
`define Inst_jr 6'b001000
`define Inst_jalr 6'b001001
实验五 JR指令设计实验【计算机组成原理】
//实现J+指令
`define Inst_beq 6'b010000
`define Inst_bne 6'b010001
`define Inst_bltz 6'b010010
`define Inst_bgtz 6'b010011
实验五+ J型指令设计实验
修改代码
define
//实现J+指令
`define Inst_beq 6'b010000
`define Inst_bne 6'b010001
`define Inst_bltz 6'b010010
`define Inst_bgtz 6'b010011
//内部供EX的编码
`define Beq 6'b001100
`define Bne 6'b001101
`define Bgtz 6'b001110
`define Bltz 6'b001111
ID
`include "define.v";
//J型指令 添加jAddr jCe pc
module ID (
...
);
...
always@(*)
if(rst == `RstEnable)
...
else
begin//后面的end
jCe = `Invalid;//J型
jAddr = `Zero;//J型
case(inst_op)
`Inst_ori:
...
`Inst_andi:
...
`Inst_xori:
...
`Inst_addi:
...
`Inst_subi:
...
`Inst_lui:
...
`Inst_reg:
case(func)
`Inst_add:
...
`Inst_or:
...
`Inst_sub:
...
`Inst_and:
...
`Inst_xor:
...
`Inst_sll:
...
`Inst_srl:
...
`Inst_sra:
...
//JR型指令
`Inst_jr:
...
`Inst_jalr:
...
default:
...
endcase
//J型指令
`Inst_j:
...
`Inst_jal:
...
//J+型指令
`Inst_beq:
begin
op = `Beq;
regaRead = `Valid;
regbRead = `Valid;
regcWrite = `Invalid;
regaAddr = inst[25:21];
regbAddr = inst[20:16];
regcAddr = `Zero;
jAddr = {14'b000000000000000,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 = {14'b000000000000000,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 = {14'b000000000000000,inst[15:0], 2'b00};
if(regaData<regbData)
jCe = `Valid;//小于有效
else
Ce = `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 = {14'b000000000000000,inst[15:0], 2'b00};
if(regaData>regbData)
jCe = `Valid;//大于有效
else
jCe = `Invalid;
imm = 32'b0;
end
default:
...
endcase
end
//二选一 regaData= regaData_i : imm
always@(*)
...
//二选一 regbData= regbData_i : imm
always@(*)
...
endmodule
EX
`include "define.v";
//3、执行指令模块
module EX (
...
);
always@(*)
if(rst == `RstEnable)
...
else
case(op)
...
//J- JR型
`J:
regcData = `Zero;
`Jal:
regcData = regbData;//regaData有其他用处
//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
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型指令测试
/*
...
*/
//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型指令测试
/*
...
*/
//J- JR型指令测试
/*
...
*/
//J+型指令测试
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
instmem [6] = 32'b010000_00101_00110_0000_0000_0000_0000; //beq r5,r6,0 编码010000
//instmem [6] = 32'b010001_00001_00110_0000_0000_0000_0000; //bne r5,r6,0 编码010001
//instmem [6] = 32'b010010_00010_00011_0000_0000_0000_0000; //bltz r2,r3,0 编码010010
//instmem [6] = 32'b010011_00001_00000_0000_0000_0000_0000; //bgtz r1,0 编码010011
end
endmodule
结果
beq
bne
bltz
bgtz
regbRead无效,就是bgtz r2,r3,0 (r1)>(r3) pc=0
regbRead无效,就是bgtz r1,0 (r1)>0 pc=0
完整代码
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
//指令外部编码
//I型编码
`define Inst_ori 6'b001101
`define Inst_andi 6'b001100
`define Inst_xori 6'b001110
`define Inst_addi 6'b001000
`define Inst_subi 6'b001001
`define Inst_lui 6'b001111
//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
//J型编码
`define Inst_j 6'b000110
`define Inst_jal 6'b000101
`define Inst_jr 6'b001000
`define Inst_jalr 6'b001001
`define Inst_beq 6'b010000
`define Inst_bne 6'b010001
`define Inst_bltz 6'b010010
`define Inst_bgtz 6'b010011
//内部供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
IF
`include "define.v";
//1、控制PC,程序计数器
//J型指令 添加jAddr jCe 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
ID
`include "define.v";
//相比于ID 仿照老师修改了移位的操作
//ID 自己实现移位操作有点繁琐
//2、为操作数做准备
//把指令32的i型指令inst
//6op 5rega 5regc 16imm
//regaData regbData
//J型指令 添加jAddr jCe pc
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 = `Zero;
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 = {14'b000000000000000,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 = {14'b000000000000000,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 = {14'b000000000000000,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 = {14'b000000000000000,inst[15:0], 2'b00};
if(regaData>regbData)
jCe = `Valid;//大于有效
else
jCe = `Invalid;
imm = 32'b0;
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;
endmodule
EX
`include "define.v";
//3、执行指令模块
module EX (
input wire rst,
input wire [5:0] op,
input wire [31:0] regaData,
input wire [31:0] regbData,
input wire regcWrite_i,
input wire [4:0] regcAddr_i,
output reg [31:0] regcData,
output wire regcWrite,
output wire [4:0] regcAddr
);
always@(*)
if(rst == `RstEnable)
regcData = `Zero;
else
case(op)
`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有其他用处
//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
RegFile
`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
MIPS
`include "define.v";
//5、MIPS封装
module MIPS(
input wire clk,
input wire rst,
input wire [31:0] instruction,
output wire romCe,
output wire [31:0] instAddr
);
wire [31:0] regaData_regFile, regbData_regFile;
wire [31:0] regaData_id, regbData_id;
wire [31:0] regcData_ex;
wire [5:0] op;
wire regaRead, regbRead;
wire [4:0] regaAddr, regbAddr;
wire regcWrite_id, regcWrite_ex;
wire [4:0] regcAddr_id, regcAddr_ex;
//J型
wire [31:0] jAddr;
wire jCe;
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),
.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 ex0(
.rst(rst),
.op(op),
.regaData(regaData_id),
.regbData(regbData_id),
.regcWrite_i(regcWrite_id),
.regcAddr_i(regcAddr_id),
.regcData(regcData_ex),
.regcWrite(regcWrite_ex),
.regcAddr(regcAddr_ex)
);
RegFile regfile0(
.clk(clk),
.rst(rst),
.we(regcWrite_ex),
.waddr(regcAddr_ex),
.wdata(regcData_ex),
.regaRead(regaRead),
.regbRead(regbRead),
.regaAddr(regaAddr),
.regbAddr(regbAddr),
.regaData(regaData_regFile),
.regbData(regbData_regFile)
);
endmodule
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型指令测试
/*
//instmem [6] = 32'h18000000; //j 0 编码000110
//instmem [6] = 32'h14000000; //jal 0 编码000101
instmem [6] = 32'h34070000;//ori,R7,0000
//instmem [7] = 32'b000000_00111_00000_00000_001000; //jr R7 编码001000
instmem [7] = 32'b000000_00111_00000_00000_001001; //jalr R0 编码001001
*/
//J+型指令测试
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
instmem [6] = 32'b010000_00101_00110_0000_0000_0000_0000; //beq r5,r6,0 编码010000
//instmem [6] = 32'b010001_00001_00110_0000_0000_0000_0000; //bne r5,r6,0 编码010001
//instmem [6] = 32'b010010_00010_00011_0000_0000_0000_0000; //bltz r2,r3,0 编码010010
//instmem [6] = 32'b010011_00001_00000_0000_0000_0000_0000; //bgtz r1,0 编码010011
end
endmodule
SoC
//7、系统封装
module SoC(
input wire clk,
input wire rst
);
wire [31:0] instAddr;
wire [31:0] instruction;
wire romCe;
MIPS mips0(
.clk(clk),
.rst(rst),
.instruction(instruction),
.instAddr(instAddr),
.romCe(romCe)
);
InstMem instrom0(
.ce(romCe),
.addr(instAddr),
.data(instruction)
);
endmodule
soc_tb
`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
最新测试
2022-12-13 13:35:46
ID有个错误
`Inst_jalr:
regaAddr = inst[25:21];
理解jaddr的值
修改ID中赋值给J+型jaddr的值
jaddr=npc+S14 offset 00
总结
J-型指令测试 j jal
pc=jaddr=npc(4) offset(26) 00(2)
pc=offset左移2位,即乘以4
JR型指令测试 jr jalr
pc=jaddr=(rs)
pc=寄存器中的值
J+型指令测试 beq bne bltz bgtz
pc=jaddr=npc+S14 offset(16) 00(2)
pc=下一条指令+相对指令偏移
ID
//修改beq bne bgtz bltz J+型
jAddr = npc+{{14{inst[15]}},inst[15:0], 2'b00};
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;
//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
end
endmodule
j 1
//J-型指令测试
//pc=jaddr=npc(4) offset(26) 00(2)
instmem [6] = 32'h18000001; //j 1 编码000110 pc=0004
波形分析
j 1
pc=jaddr=npc(4) offset(26) 00(2)
pc=offset左移2位,即乘以4
跳转到pc=0004
jal 2
//J-型指令测试
//pc=jaddr=npc(4) offset(26) 00(2)
instmem [6] = 32'h14000002; //jal 2 编码000101 pc=0008 R31=0000001C
波形分析
jal 2
pc=jaddr=npc(4) offset(26) 00(2)
pc=offset左移2位,即乘以4
跳转到pc=0008
并且(R31)=npc=001C
jr R7
//JR型指令测试
//pc=jaddr=(rs)
instmem [6] = 32'h3407000C;//ori,R7,000C
instmem [7] = 32'b000000_00111_00000_00000_00000_001000; //jr R7 编码001000 pc=0000000C
波形分析
jr R7
pc=jaddr=(R7)=000C
跳转到pc=000C
jalr R7
//JR型指令测试
//pc=jaddr=(rs)
instmem [6] = 32'h3407000C;//ori,R7,000C
instmem [7] = 32'b000000_00111_00000_00000_00000_001001; //jalr R7 编码001001 pc=0000000C R31=00000020
波形分析
jalr R7
pc=jaddr=(R7)=000C
跳转到pc=000C
并且(R31)=npc=0020
beq r5,r6 0
//J+型指令测试
//pc=jaddr=npc+S14 offset(16) 00(2)
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
instmem [6] = 32'b010000_00101_00110_0000_0000_0000_0000; //beq r5,r6,0 编码010000 pc=001C
波形分析
beq r5,r6 0
pc=jaddr=npc+S14 offset(16) 00(2)
pc=下一条指令+相对指令偏移
跳转到pc=001C
beq r5,r6 1
//J+型指令测试
//pc=jaddr=npc+S14 offset(16) 00(2)
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
instmem [6] = 32'b010000_00101_00110_0000_0000_0000_0001; //beq r5,r6,1 编码010000 pc=0020
//ori R7,0001 -- R7 --00000001
instmem [7] = 32'h34070001; //ori R7 1
//ori R8,0001 -- R7 --00000001
instmem [8] = 32'h34080001; //ori R8 1
波形分析
beq r5,r6 1
pc=jaddr=npc+S14 offset(16) 00(2)
pc=下一条指令+相对指令偏移
跳转到pc=0020
bne r1,r6 -2
//J+型指令测试
//pc=jaddr=npc+S14 offset(16) 00(2)
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
instmem [6] = 32'b010001_00001_00110_1111_1111_1111_1110; //bne r5,r6,-2 编码010001 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
波形分析
bne r1,r6 -2
pc=jaddr=npc+S14 offset(16) 00(2)
pc=下一条指令+相对指令偏移
跳转到pc=0014
bltz r2,r3 1
//J+型指令测试
//pc=jaddr=npc+S14 offset(16) 00(2)
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
instmem [6] = 32'b010010_00010_00011_0000_0000_0000_0001; //bltz r2,r3,1 编码010010 pc=0020
//ori R7,0001 -- R7 --00000001
instmem [7] = 32'h34070001; //ori R7 1
//ori R8,0001 -- R7 --00000001
instmem [8] = 32'h34080001; //ori R8 1
波形分析
bltz r2,r3 1
pc=jaddr=npc+S14 offset(16) 00(2)
pc=下一条指令+相对指令偏移
跳转到pc=0020
bgtz r1,-2
//J+型指令测试
//pc=jaddr=npc+S14 offset(16) 00(2)
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
instmem [6] = 32'b010011_00001_00000_1111_1111_1111_1110; //bgtz r1,-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
波形分析
bgtz r1,-2
pc=jaddr=npc+S14 offset(16) 00(2)
pc=下一条指令+相对指令偏移
跳转到pc=0014
测试全部J型指令
`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;
//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
//测试全部J型指令
//把R7,R8初始值为1
//每次跳过R7的加1操作 执行R8的加1操作
//ori R7,0001 -- R7 --00000001
instmem [6] = 32'h34070001; //ori R7 1
//ori R8,0001 -- R7 --00000001
instmem [7] = 32'h34080001; //ori R8 1
instmem [8] = 32'h1800000A; //j 10 编码000110 10*4 40--28H
//addi R7,R7,0001
instmem [9] = 32'h20E70001;
//addi R8,R8,0001
instmem [10] = 32'h21080001;//2
instmem [11] = 32'h1400000D; //jal 13 编码000101 13*4 52--34H
//addi R7,0001
instmem [12] = 32'h20E70001;
//addi R8,0001
instmem [13] = 32'h21080001;//3
//R9为下面的jr提供跳转位置
instmem [14] = 32'h34090044;//ori,R9,0044H pc<--(rs)
instmem [15] = 32'b000000_01001_00000_00000_00000_001000; //jr R9 编码001000 17*4 68--44H
//addi R7,0001
instmem [16] = 32'h20E70001;
//addi R8,0001
instmem [17] = 32'h21080001;//4
//R10为下面的jalr提供跳转位置
instmem [18] = 32'h340A0054;//ori,R10,0054 pc<--(rs)
instmem [19] = 32'b000000_01010_00000_00000_00000_001001; //jalr R10 编码001001 84--54H
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
//addi R7,0001
instmem [20] = 32'h20E70001;
//addi R8,0001
instmem [21] = 32'h21080001;//5
instmem [22] = 32'b010000_00101_00110_0000_0000_0000_0001; //beq r5,r6,18H 编码010000 24*4 96--60H
//addi R7,0001
instmem [23] = 32'h20E70001;
//addi R8,0001
instmem [24] = 32'h21080001;//6
instmem [25] = 32'b010001_00001_00110_0000_0000_0000_0001; //bne r1,r6,0 编码010001 27*4 108--6C
//addi R7,0001
instmem [26] = 32'h20E70001;
//addi R8,0001
instmem [27] = 32'h21080001;//7
instmem [28] = 32'b010010_00010_00011_0000_0000_0000_0001; //bltz r2,r3,1E 编码010010 30*4 120--68H
//addi R7,0001
instmem [29] = 32'h20E70001;
//addi R8,0001
instmem [30] = 32'h21080001;//8
instmem [31] = 32'b010011_00001_00000_0000_0000_0000_0001; //bgtz r1,21 编码010011 33
//addi R7,0001
instmem [32] = 32'h20E70001;
//addi R8,0001
instmem [33] = 32'h21080001;//9
end
endmodule
波形结果分析
初始赋值(R7)=0 (R8)=0
每一次跳过addi R7,R7 1的指令,执行addi R8,R8 1的指令
最终(R7)=1,(R8)=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'h18000001; //j 1 编码000110 pc=0004
//instmem [6] = 32'h14000002; //jal 2 编码000101 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'b010000_00101_00110_0000_0000_0000_0000; //beq r5,r6,0 编码010000 pc=001C
//instmem [6] = 32'b010000_00101_00110_0000_0000_0000_0001; //beq r5,r6,1 编码010000 pc=0020
//instmem [6] = 32'b010001_00001_00110_1111_1111_1111_1110; //bne r5,r6,-2 编码010001 pc=0014
//instmem [6] = 32'b010010_00010_00011_0000_0000_0000_0001; //bltz r2,r3,1 编码010010 pc=0020
instmem [6] = 32'b010011_00001_00000_1111_1111_1111_1110; //bgtz r1,-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
*/
//测试全部J型指令
//把R7,R8初始值为1
//每次跳过R7的加1操作 执行R8的加1操作
//ori R7,0001 -- R7 --00000001
instmem [6] = 32'h34070001; //ori R7 1
//ori R8,0001 -- R7 --00000001
instmem [7] = 32'h34080001; //ori R8 1
instmem [8] = 32'h1800000A; //j 10 编码000110 10*4 40--28H
//addi R7,R7,0001
instmem [9] = 32'h20E70001;
//addi R8,R8,0001
instmem [10] = 32'h21080001;//2
instmem [11] = 32'h1400000D; //jal 13 编码000101 13*4 52--34H
//addi R7,0001
instmem [12] = 32'h20E70001;
//addi R8,0001
instmem [13] = 32'h21080001;//3
//R9为下面的jr提供跳转位置
instmem [14] = 32'h34090044;//ori,R9,0044H pc<--(rs)
instmem [15] = 32'b000000_01001_00000_00000_00000_001000; //jr R9 编码001000 17*4 68--44H
//addi R7,0001
instmem [16] = 32'h20E70001;
//addi R8,0001
instmem [17] = 32'h21080001;//4
//R10为下面的jalr提供跳转位置
instmem [18] = 32'h340A0054;//ori,R10,0054 pc<--(rs)
instmem [19] = 32'b000000_01010_00000_00000_00000_001001; //jalr R10 编码001001 84--54H
//R1=00001100 R2=00000020 R3=000000ff R4=0000ffff R5=00001120 R6=00001120
//addi R7,0001
instmem [20] = 32'h20E70001;
//addi R8,0001
instmem [21] = 32'h21080001;//5
instmem [22] = 32'b010000_00101_00110_0000_0000_0000_0001; //beq r5,r6,18H 编码010000 24*4 96--60H
//addi R7,0001
instmem [23] = 32'h20E70001;
//addi R8,0001
instmem [24] = 32'h21080001;//6
instmem [25] = 32'b010001_00001_00110_0000_0000_0000_0001; //bne r1,r6,0 编码010001 27*4 108--6C
//addi R7,0001
instmem [26] = 32'h20E70001;
//addi R8,0001
instmem [27] = 32'h21080001;//7
instmem [28] = 32'b010010_00010_00011_0000_0000_0000_0001; //bltz r2,r3,1E 编码010010 30*4 120--68H
//addi R7,0001
instmem [29] = 32'h20E70001;
//addi R8,0001
instmem [30] = 32'h21080001;//8
instmem [31] = 32'b010011_00001_00000_0000_0000_0000_0001; //bgtz r1,21 编码010011 33
//addi R7,0001
instmem [32] = 32'h20E70001;
//addi R8,0001
instmem [33] = 32'h21080001;//9
end
endmodule
2022-12-13 15:30:45
最后
2022/12/6 20:12
这篇博客能写好的原因是:站在巨人的肩膀上
这篇博客要写好的目的是:做别人的肩膀
开源:为爱发电
学习:为我而行