0
点赞
收藏
分享

微信扫一扫

实验五+ J型指令设计实验【计算机组成原理】


实验五 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

实验五+ J型指令设计实验【计算机组成原理】_fpga开发

bne

实验五+ J型指令设计实验【计算机组成原理】_fpga开发_02

bltz

实验五+ J型指令设计实验【计算机组成原理】_R3_03

bgtz

regbRead无效,就是bgtz r2,r3,0 (r1)>(r3) pc=0

实验五+ J型指令设计实验【计算机组成原理】_复用_04

regbRead无效,就是bgtz r1,0 (r1)>0 pc=0

实验五+ J型指令设计实验【计算机组成原理】_R3_05

完整代码

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

实验五+ J型指令设计实验【计算机组成原理】_R3_06

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

实验五+ J型指令设计实验【计算机组成原理】_组成原理_07

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

实验五+ J型指令设计实验【计算机组成原理】_复用_08

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

实验五+ J型指令设计实验【计算机组成原理】_组成原理_09

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

实验五+ J型指令设计实验【计算机组成原理】_组成原理_10

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

实验五+ J型指令设计实验【计算机组成原理】_组成原理_11

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

实验五+ J型指令设计实验【计算机组成原理】_复用_12

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

实验五+ J型指令设计实验【计算机组成原理】_fpga开发_13

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型指令设计实验【计算机组成原理】_fpga开发_14

测试全部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

实验五+ J型指令设计实验【计算机组成原理】_复用_15

实验五+ J型指令设计实验【计算机组成原理】_fpga开发_16


实验五+ J型指令设计实验【计算机组成原理】_fpga开发_17

完整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

这篇博客能写好的原因是:站在巨人的肩膀上

这篇博客要写好的目的是:做别人的肩膀

开源:为爱发电

学习:为我而行


举报

相关推荐

0 条评论