目录
MIPS CPU框架图
R型指令格式、对应机器码
define.v
`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_addi 6'b001000
`define Inst_andi 6'b001100
`define Inst_xori 6'b001110
`define Inst_lui 6'b001111
`define Inst_subi 6'b001001
//R
`define Inst_r 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 Nop 6'b000000
`define Or 6'b000001
`define Add 6'b000010
`define And 6'b000011
`define Xor 6'b000100
`define Lui 6'b000101
`define Sub 6'b000110
`define Sll 6'b000111
`define Srl 6'b001000
`define Sra 6'b001001
IF.v
`include "define.v"
module IF(
input wire clk,
input wire rst,
output reg ce,
output reg [31:0] pc
);
always@(*)
if(rst == `RstEnable)
ce = `RomDisable;
else
ce = `RomEnable;
always@(posedge clk)
if(ce == `RomDisable)
pc = `Zero;
else
pc = pc + 4;
endmodule
InstMem.v
`include "define.v"
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
instmem [0] = 32'h34011100; //ori r1,r0,1100h r1--32'h0000 1100
instmem [1] = 32'h34020020; //ori r2,r0,0020h r2--32'h0000 0020
instmem [2] = 32'h3403ff00; //ori r3,r0,ff00h r3--32'h0000 ff00
instmem [3] = 32'h3404ffff; //ori r4,r0,ffffh r4--32'h0000 ffff
instmem [4] = 32'h00222820; //add r5,r1,r2 r5--32'h0000 1120
instmem [5] = 32'h00223025; //or r6,r1,r2 r6--32'h0000 1120
instmem [6] = 32'h00223822; //sub r7,r1,r2 r7--32'h0000 10e0
instmem [7] = 32'h00224024; //and r8,r1,r2 r8--32'h0000 0000
instmem [8] = 32'h00224826; //xor r9,r1,r2 r9--32'h0000 1120
instmem [9] =32'h3c0affff; //lui r10,ffff r10--32'hffff 0000
instmem [10] = 32'h000a5840; //sll r11,r10,1 r11--32'hfffe 0000
instmem [11] = 32'h000a6042; //srl,r12,r10,1 r12--32'h7fff 8000
instmem [12] = 32'h000a6843; //sra r13,r10,1 r13--32'hffff 8000
end
endmodule
ID.v
`include "define.v"
module ID (
input wire rst,
input wire [31:0] inst,
input wire [31:0] regaData_i,
input wire [31:0] regbData_i,
output reg [5:0] op,
output reg [4:0] regaAddr,
output reg [4:0] regbAddr,
output reg [4:0] regcAddr,
output reg [31:0] regaData,
output reg [31:0] regbData,
output reg regaRead,
output reg regbRead,
output reg regcWrite
);
wire [5:0] inst_op = inst[31:26];
reg [31:0] imm;
//R
wire [5:0]func = inst[5:0];
always@(*)
if(rst == `RstEnable)
begin
op = `Nop;
regaRead = `Invalid;
regbRead = `Invalid;
regcWrite = `Invalid;
regaAddr = `Zero;
regbAddr = `Zero;
regcAddr = `Zero;
imm = `Zero;
end
else
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_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_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_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 = `Invalid;
regbRead = `Invalid;
regcWrite = `Valid;
regaAddr = `Zero;
regbAddr = `Zero;
regcAddr = inst[20:16];
imm = {inst[15:0],16'h0};
end
//R
`Inst_r:
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'h0,inst[10:6]};
end
`Inst_srl:
begin
op = `Srl;
regaRead = `Invalid;
regbRead = `Valid;
regcWrite = `Valid;
regaAddr = `Zero;
regbAddr = inst[20:16];
regcAddr = inst[15:11];
imm = {27'h0,inst[10:6]};
end
`Inst_sra:
begin
op = `Sra;
regaRead = `Invalid;
regbRead = `Valid;
regcWrite = `Valid;
regaAddr = `Zero;
regbAddr = inst[20:16];
regcAddr = inst[15:11];
imm = {27'h0,inst[10:6]};
end
default:
begin
op = `Nop;
regaRead = `Invalid;
regbRead = `Invalid;
regcWrite = `Invalid;
regaAddr = `Zero;
regbAddr = `Zero;
regcAddr = `Zero;
imm = `Zero;
end
endcase
default:
begin
op = `Nop;
regaRead = `Invalid;
regbRead = `Invalid;
regcWrite = `Invalid;
regaAddr = `Zero;
regbAddr = `Zero;
regcAddr = `Zero;
imm = `Zero;
end
endcase
always@(*)
if(rst == `RstEnable)
regaData = `Zero;
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
EX.v
`include "define.v"
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
begin
case(op)
`Or:
regcData = regaData | regbData;
`Add:
regcData = regaData + regbData;
`And:
regcData = regaData & regbData;
`Xor:
regcData = regaData ^ regbData;
`Lui:
regcData = regaData;
`Sub:
regcData = regaData - regbData;
`Sll:
regcData = regbData << regaData;
`Srl:
regcData = regbData >> regaData;
`Sra:
regcData = ($signed(regbData)) >>> regaData;
default:
regcData = `Zero;
endcase
end
assign regcWrite = regcWrite_i;
assign regcAddr = regcAddr_i;
endmodule
RegFile.v
`include "define.v"
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 != `RstEnable)
if((we == `Valid) && (waddr != `Zero))
reg32[waddr] = wdata;
else ;
endmodule
MIPS.v
`include "define.v"
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;
IF if0(
.clk(clk),
.rst(rst),
.ce(romCe),
.pc(instAddr)
);
ID id0(
.rst(rst),
.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)
);
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
SoC.v
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.v
`include "define.v"
module soc_tb;
reg clk;
reg rst;
initial
begin
clk = 0;
rst = `RstEnable;
#100
rst = `RstDisable;
#10000 $stop;
end
always #10 clk = ~ clk;
SoC soc0(
.clk(clk),
.rst(rst)
);
endmodule
仿真测试
① instmem [0] = 32'h34011100;
机器码:0011 0100 0000 0001 0001 0001 0000 0000
指令:001101(ori) rs:00000(r0) rt:00001(r1)
imm:0001 0001 0000 0000(零扩展)
//ori r1,r0,1100h r1<--32'h0000 1100
②instmem [1] = 32'h34020020;
机器码:0011 0100 0000 0010 0000 0000 0010 0000
指令:001101(ori) rs:00000(r0) rt:00010(r2)
imm:0000 0000 0010 0000(零扩展)
//ori r2,r0,0020h r2<--32'h0000 0020
③instmem [2] = 32'h3403ff00;
机器码:0011 0100 0000 0011 1111 1111 0000 0000
指令:001101(ori) rs:00000(r0) rt:00011(r3)
imm:1111 1111 0000 0000(零扩展)
//ori r3,r0,ff00h r3<--32'h0000 ff00
④instmem [3] = 32'h3404ffff;机器码:0011 0100 0000 0100 1111 1111 1111 1111
指令:001101(ori) rs:00000(r0) rt:00100(r4)
imm:1111 1111 1111 1111(零扩展)
//ori r4,r0,ffffh r4<--32'h0000 ffff
⑤instmem [4] = 32'h00222820;机器码:0000 0000 0010 0010 0010 1000 0010 0000
指令:rs:00001(r1) rt:00010(r2) rd:00101(r5) sa:00000 func:100000(add)
//add r5,r1,r2 r5<--32'h0000 1120
⑥instmem [5] = 32'h00223025;机器码:0000 0000 0010 0010 0011 0000 0010 0101
指令:rs:00001(r1) rt:00010(r2) rd:00110(r6) sa:00000 func:100101(or)
//or r6,r1,r2 r6<--32'h0000 1120
⑦instmem [6] = 32'h00223822;机器码:0000 0000 0010 0010 0011 1000 0010 0010
指令:rs:00001(r1) rt:00010(r2) rd:00111(r7) sa:00000 func:100010(sub)
//sub r7,r1,r2 r7<--32'h0000 10e0
⑧instmem [7] = 32'h00224024;机器码:0000 0000 0010 0010 0100 0000 0010 0100
指令:rs:00001(r1) rt:00010(r2) rd:01000(r8) sa:00000 func:100100(and)
//and r8,r1,r2 r8<--32'h0000 0000
⑨instmem [8] = 32'h00224826;机器码:0000 0000 0010 0010 0100 1000 0010 0110
指令:rs:00001(r1) rt:00010(r2) rd:01001(r9) sa:00000 func:100110(xor)
//xor r9,r1,r2 r9<--32'h0000 1120
⑩instmem [9] = 32'h3c0affff;机器码:0011 1100 0000 1010 1111 1111 1111 1111
指令:001111(lui) rs:00000 rt:01010(r10)
imm:1111 1111 1111 1111(低位零扩展)
//lui r10,r3,ffff r10--32'hffff0000
⑪instmem [10] = 32'h000a5840;机器码:0000 0000 0000 1010 0101 1000 0100 0000
指令:rs:00000 rt:01010(r10) rd:01011(r11) sa:00001 func:000000(sll)
//sll r11,r10,1 r11<--32'hfffe 0000
⑫instmem [11] = 32'h000a6042;机器码:0000 0000 0000 1010 0110 0000 0100 0010
指令:rs:00000 rt:01010(r10) rd:01100(r12) sa:00001 func:000010(srl)
//srl r12,r10,1 r12<--32'h7fff 8000
⑬instmem [12] = 32'h000a6843;
机器码:0000 0000 0000 1010 0110 1000 0100 0011
指令:rs:00000 rt:01010(r10) rd:01101(r13) sa:00001 func:000011(sra)
//sra r13,r10,1 r12<--32'hffff 8000