实现乘除
修改框架
![](https://i-blog.csdnimg.cn/direct/554eb2bc3368437393df59068dd8e147.png)
![](https://i-blog.csdnimg.cn/direct/79cdf14a6c4444e88177ea3cd081aa9c.png)
EX:实现带符号乘除法和无符号乘除法
HiLo寄存器:用于存放乘法和除法的运算结果。Hi、Lo为32bit寄存器。电路描述与实现RegFile思想一致
仿真
![](https://i-blog.csdnimg.cn/direct/0eec0e138be94fbba5055bd83e792723.png)
代码
DataMem.v
`include "define.v";
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;
else
rdData = datamem[addr[11 : 2]];
always@(posedge clk)
if(ce == `RamEnable && we == `RamWrite)
datamem[addr[11 : 2]] = wtData;
else ;
endmodule
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
//lw sw
`define Inst_lw 6'b100011
`define Inst_sw 6'b101011
//beq bne
`define Inst_beq 6'b000100
`define Inst_bne 6'b000101
//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 Inst_jr 6'b001000
//J
`define Inst_j 6'b000010
`define Inst_jal 6'b000011
//12
`define Inst_slt 6'b101010
`define Inst_bgtz 6'b000111
`define Inst_bltz 6'b000001
`define Inst_jalr 6'b001001
`define Inst_mult 6'b011000
`define Inst_multu 6'b011001
`define Inst_div 6'b011010
`define Inst_divu 6'b011011
`define Inst_mfhi 6'b010000
`define Inst_mflo 6'b010010
`define Inst_mthi 6'b010001
`define Inst_mtlo 6'b010011
//
`define Inst_ll 6'b110000
`define Inst_sc 6'b111000
`define Inst_mfc0 6'b000000
`define Inst_mtc0 6'b000000
`define Inst_eret 6'b011000
`define syscall 6'b001100
`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
`define J 6'b001010
`define Jal 6'b001011
`define Beq 6'b001100
`define Bne 6'b001101
`define Jr 6'b001110
`define Lw 6'b010000
`define Sw 6'b010001
`define Bgtz 6'b010010
`define Bltz 6'b010011
`define Slt 6'b010100
`define Mult 6'b010101
`define Multu 6'b010110
`define Div 6'b010111
`define Divu 6'b011000
//MEM
`define RamWrite 1'b1
`define RamUnWrite 1'b0
`define RamEnable 1'b1
`define RamDisable 1'b0
EX.v
`include "define.v"
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,
input wire [31:0] rhi,
input wire [31:0] rlo,
output reg whi,
output reg wlo,
output reg [31:0] hiData,
output reg [31:0] loData
);
assign op = op_i;
assign memAddr = regaData;
assign memData = regbData;
always@(*)
if(rst == `RstEnable)
regcData = `Zero;
else
begin
//case(op)
case(op_i)
`Or:
regcData = regaData | regbData;
`Add:
regcData = regaData + regbData;
`And:
regcData = regaData & regbData;
`Xor:
regcData = regaData ^ regbData;
`Lui:
regcData = regaData;
/*`Lui:
regcData = regaData | regbData;
*/
`Sub:
regcData = regaData - regbData;
`Sll:
regcData = regbData << regaData;
`Srl:
regcData = regbData >> regaData;
`Sra:
regcData = ($signed(regbData)) >>> regaData;
`J:
regcData = `Zero;
`Jr:
regcData = `Zero;
`Jal:
regcData = regbData;
`Beq:
regcData = `Zero;
`Bne:
regcData = `Zero;
`Bltz:
regcData = `Zero;
`Bgtz:
regcData = `Zero;
`Slt:
regcData = ($signed(regaData)<$signed(regbData))?1'b1:1'b0;
`Mult:
begin
whi=`Valid;
wlo=`Valid;
{hiData,loData}=$signed(regaData)*$signed(regbData);
end
`Multu:
begin
whi=`Valid;
wlo=`Valid;
{hiData,loData}=regaData*regbData;
end
`Div:
begin
whi=`Valid;
wlo=`Valid;
hiData=$signed(regaData)%$signed(regbData);
loData=$signed(regaData)/$signed(regbData);
end
`Divu:
begin
whi=`Valid;
wlo=`Valid;
hiData=regaData%regbData;
loData=regaData/regbData;
end
default:
regcData = `Zero;
endcase
end
assign regcWrite = regcWrite_i;
assign regcAddr = regcAddr_i;
endmodule
HiLo.v
`include "define.v"
module HiLo (
input wire rst,
input wire clk ,
input wire [31:0] hiData,
input wire [31:0] loData,
input wire whi ,
input wire wlo ,
output reg [31:0] rhi,
output reg [31:0] rlo
);
reg [31:0]hi,lo;//????
always@ (*)
if(rst==`RstEnable)
begin
rhi = `Zero;
rlo = `Zero;
end
else
begin
rhi = hi;
rlo = lo;
end
always@(posedge clk)
if (rst ==`RstDisable && whi==`Valid)
hi=hiData;
else ;
always@(posedge clk)
if (rst ==`RstDisable && wlo==`Valid)
lo=loData;
else ;
endmodule
ID.v
`include "define.v";
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
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 = `Invalid;
regbRead = `Invalid;
regcWrite = `Valid;
regaAddr = `Zero;
regbAddr = `Zero;
regcAddr = inst[20:16];
imm = {inst[15:0],16'h0};
end
`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'b0,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'b0,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'b0,inst[10:6]};
end
`Inst_jr:
begin
op = `Jr;
regaRead = `Valid;//rs
regbRead = `Invalid;
regcWrite = `Invalid;
regaAddr = inst[25:21];
regbAddr = `Zero;
regcAddr = 5'b11111;
jAddr = regaData;
jCe = `Valid;
imm = `Zero;
end
`Inst_jalr:
begin
op = `Jal;
regaRead = `Valid;
regbRead = `Invalid;
regcWrite = `Valid;
regaAddr = inst[25:21];
regbAddr = `Zero;
regcAddr = inst[15:11]; //
jAddr = regaData;
jCe = `Valid;
imm = npc;
end
`Inst_slt:
begin
op = `Slt;
regaRead = `Valid;
regbRead = `Invalid;
regcWrite = `Valid;
regaAddr = inst[25:21];
regbAddr = inst[20:16];
regcAddr = inst[15:11];
imm = `Zero;
end
`Inst_mult:
begin
op = `Mult;
regaRead = `Valid;
regbRead = `Valid;
regcWrite = `Invalid;
regaAddr = inst[25:21];
regbAddr = inst[20:16];
regcAddr = `Zero;
imm = `Zero;
end
`Inst_multu:
begin
op = `Multu;
regaRead = `Valid;
regbRead = `Valid;
regcWrite = `Invalid; regaAddr = inst[25:21];
regbAddr = inst[20:16];
regcAddr = `Zero;
imm = `Zero;
end
`Inst_div:
begin
op = `Div;
regaRead = `Valid;
regbRead = `Valid;
regcWrite = `Invalid;
regaAddr = inst[25:21];
regbAddr = inst[20:16];
regcAddr = `Zero;
imm = `Zero;
end
`Inst_divu:
begin
op = `Divu;
regaRead = `Valid;
regbRead = `Valid;
regcWrite = `Invalid;
regaAddr = inst[25:21];
regbAddr = inst[20:16];
regcAddr = `Zero;
imm = `Zero;
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;
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 = npc+{
{14{inst[15]}},inst[15:0],2'b00};
jCe=(regaData==regbData)?`Valid:`Invalid;
/* if(regaData==regbData)
jCe = `Valid;
else
jCe = `Invalid;*/
imm = `Zero;
end
`Inst_bne:
begin
op = `Bne;
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};
jCe=(regaData!=regbData)?`Valid:`Invalid;
/* if(regaData!=regbData)
jCe = `Valid;
else
jCe = `Invalid;
*/
imm = `Zero;
end
`Inst_bgtz:
begin
op = `Bgtz;
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};
jCe = (regaData[31]==0)?`Valid:`Invalid;
imm = 32'b0; //
end
`Inst_bltz:
begin
op = `Bgtz;
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};
jCe = (regaData[31]==1)?`Valid:`Invalid; //
imm = 32'b0; //
end
`Inst_lw:
begin
op = `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:
begin
op = `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:
begin
op = `Nop;
regaRead = `Invalid;
regbRead = `Invalid;
regcWrite = `Invalid;
regaAddr = `Zero;
regbAddr = `Zero;
regcAddr = `Zero;
imm = `Zero;
end
endcase
end
/*
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;
*/
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
IF.v
`include "define.v"
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;
/* always@(posedge clk)
if(ce == `RomDisable)
pc = `Zero;
else
pc = pc + 4;
*/
always@(posedge clk)
if(ce == `RomDisable)
pc = `Zero;
else if(jCe == `Valid)//J
pc = jAddr;
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'b000000_00001_00010_00000_00000_011001;//multu,r1,r2 22000
instmem [5] = 32'b000000_00001_00010_00000_00000_011011;//divu,r1,r2 88
instmem [6] = 32'h2005fffc; //addi r5,r0,fffc r5--32'hffff fffc
instmem [7] = 32'h34060002; //ori r6,r0,0002h r6--32'h0000 0002
instmem [8] = 32'h3c071234; //lui r7,1234 r7--32'h1234 0000
instmem [9] = 32'b000000_00101_00110_00000_00000_011000; //mult r5,r6
instmem [10] = 32'b000000_00101_00110_00000_00000_011010; //div r5,r6
/*
instmem [4] = 32'h2005ffff; //addi r5,r0,ffff r5--32'hffff ffff
instmem [5] =32'b000000_00101_00100_00110_00000_101010; //slt r6,r5,r4
instmem [6] =32'b000000_00100_00011_00110_00000_101010; //slt r6,r4,r3
*/
/*
instmem [4] = 32'h3005ffff; //andi r5,r0,ffff r5--32'h0000 0000
instmem [5] = 32'h3806ffff; //xori r6,r0,ffff r6--32'h0000 ffff
instmem [6] = 32'h2007ffff; //addi r7,r0,ffff r7--32'hffff ffff
instmem [7] = 32'h3c081234; //lui r8,1234 r8--32'h1234 0000
instmem [8] = 32'h35095679; //ori r9,r8,5678 r9--32'h1234 5679
instmem [9] = 32'h212aa011; //addi r10,r9,a011 r10--32'h1233 f68a
instmem [10] = 32'h306b1111; //andi r11,r3,1111 r10--32'h0000 1100
instmem [11] = 32'h254C1111; //subi r12,r10,1111 r12--32'h1234 e579
*/
/*
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,ra,r10 r11--32'hfffe 0000
instmem [11] = 32'h000a6042; //srl,r12,ra,r10 r12--32'h7fff 8000
instmem [12] = 32'h000a6843; //sra r13,ra,r10 r13--32'hffff 8000
*/
/*
instmem [4] = 32'h3401001c; //ori r1,r0,1ch
instmem [5] = 32'b000000_00001_00000_11111_00000_001001;//jalr r31,r1
instmem [6] = 32'h3405ffff; //ori r5,r0,ffffh
instmem [7] = 32'b000000_00001_00010_00101_00000_100000;//add,R5,R1,R2
instmem [8] = 32'b000000_11111_00000_00000_00000_001000;//jr r31
*/
/*
instmem [4] = 32'b000000_00001_00010_00101_00000_100000;//add,R5,R1,R2
instmem [5] = 32'h3405ffff; //ori r5,r0,ffffh
instmem [6] = 32'b000000_00010_00011_00110_00000_100101;//or,R6,R2,R3
instmem [7] = 32'b000111_00101_00000_0000000000000001;//bgtz r5,1
instmem [8] = 32'b000000_00001_00010_00110_00000_100101;//or,R6,R1,R2 00001120
instmem [9] = 32'h2007ffff; //addi r7,r0,ffff r7--32'hffff ffff
instmem [10] = 32'b000000_00011_00100_00110_00000_100101;//or,R6,R3,R4
//instmem [10] = 32'b000001_00111_00000_1111111111111101;//bltz r7,-3
instmem [11] = 32'b000001_00111_00000_1111111111111010;//bltz r7,-6
*/
//(r1)=0000 1100
// +0000 0018
//addr=0000 1118
// =1000100011000
// =100 0100 0110
// =446H
// =46H
// =70
//mem[70]=(r6)
/*
instmem[6]=32'b101011_00001_00110_0000_0000_0001_1000; //sw r6,0x18(r1)
instmem[7]=32'b100011_00001_00111_0000_0000_0001_1000; //lw r7,0x18(r1)
*/
//(r7)=mem[70]
end
endmodule
MEM.v
`include "define.v";
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
else
case(op)
`Lw:
begin
wtData = `Zero;
memWr = `RamUnWrite;
memCe = `RamEnable;
end
`Sw:
begin
wtData = memData;
memWr = `RamWrite;
memCe = `RamEnable;
end
default:
begin
wtData = `Zero;
memWr = `RamUnWrite;
memCe = `RamDisable;
end
endcase
endmodule
MIPS.v
`include "define.v";
module MIPS(
input wire clk,
input wire rst,
input wire [31:0] instruction,
input wire [31:0] rdData,//ls
output wire romCe,
output wire [31:0] instAddr,
output wire [31:0] wtData,//ls
output wire [31:0] memAddr,//ls
output wire memCe,//ls
output 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;
//ls
wire [5:0] op_ex;
wire[31:0] memAddr_ex,memData_ex;
wire [5:0] regAddr_mem;
wire [31:0] regData_mem;
wire regWr_mem;
//
wire [31:0] hiData_ex;
wire [31:0] loData_ex;
wire whi_ex;
wire wlo_ex;
wire [31:0] rhi_ex;
wire [31:0] rlo_ex;
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 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
.rhi(rhi_ex),
.rlo(rlo_ex),
.whi(whi_ex),
.wlo(wlo_ex),
.hiData(hiData_ex),
.loData(loData_ex)
);
HiLo hilo0(
.rst(rst),
.clk(clk),
.rhi(rhi_ex),
.rlo(rlo_ex),
.whi(whi_ex),
.wlo(wlo_ex),
.hiData(hiData_ex),
.loData(loData_ex)
);
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 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
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
SoC.v
module SoC(
input wire clk,
input wire rst
);
wire [31:0] instAddr;
wire [31:0] instruction;
wire romCe;
//ls
wire memCe, memWr;
wire [31:0] memAddr;
wire [31:0] rdData;
wire [31:0] wtData;
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
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