您的位置:首页 > 其它

Verilog 数字电路设计之带hazard的五级流水线CPU

2017-02-23 15:40 786 查看

设计目标



指令组成

一条指令由16bits组成,高5位是操作码,代表不同的操作类型;低11位是操作数,分为3部分,10:8位作为标号,代表寄存器堆里的某一个寄存器;3:0位与7:4位既可以像10:8位一样作为寄存器标号,也可以作为具体的某一个数值(称为立即数),具体根据指令来区分。



数据访问



简易CPU指令集







五级流水线



框图



Hazard

Data Hazard

Arithmetic



Solution: Data forwarding



LOAD



Solution: Stall+Data forwarding



Control Hazard

During the time from branch instruction fetch to branch address generate (from IF to ID to EX to MEM, 3 stages), the 3 instructions followed by branch are in pipeline.

Solution: Flush

Verilog代码

顶层模块cpu.v

module cpu( input wire clk, enable, reset, start
);

wire [15:0] d_datain; //data from memory
wire [15:0] i_datain; //instruction
wire [7:0] d_addr;    //address for data memory
wire [15:0] d_dataout;//output data to data memory
wire d_we;            //write dm enable
wire [7:0] i_addr;    //pc

PCPU pcpu(
.clock(clk),
.enable(enable),
.reset(reset),
.start(start),
.d_datain(d_datain),
.i_datain(i_datain),
.d_addr(d_addr),
.d_dataout(d_dataout),
.d_we(d_we),
.i_addr(i_addr)
);

I_mem i_mem(
.addra(i_addr),
.douta(i_datain)
);

D_mem d_mem(
.wea(d_we),
.addra(d_addr),
.dina(d_dataout),
.douta(d_datain)
);

endmodule


头文件headfile.v

`ifndef HEADFILE_H_

`define idle 1'b0
`define exec 1'b1
`define NOP 5'b00000
`define HALT 5'b00001
`define LOAD 5'b00010
`define STORE 5'b00011
`define SLL 5'b00100
`define SLA 5'b00101
`define SRL 5'b00110
`define SRA 5'b00111
`define ADD 5'b01000
`define ADDI 5'b01001
`define SUB 5'b01010
`define SUBI 5'b01011
`define CMP 5'b01100
`define AND 5'b01101
`define OR 5'b01110
`define XOR 5'b01111
`define LDIH 5'b10000
`define ADDC 5'b10001
`define SUBC 5'b10010
`define JUMP 5'b11000
`define JMPR 5'b11001
`define BZ 5'b11010
`define BNZ 5'b11011
`define BN 5'b11100
`define BNN 5'b11101
`define BC 5'b11110
`define BNC 5'b11111
`define gr0 3'b000
`define gr1 3'b001
`define gr2 3'b010
`define gr3 3'b011
`define gr4 3'b100
`define gr5 3'b101
`define gr6 3'b110
`define gr7 3'b111

`endif


流水线cpu代码pcpu.v

`include "headfile.v"

module PCPU(input wire reset, enable, clock, start,
input wire [15:0] d_datain,  //data from memory
i_datain,                    //instruction
output wire [7:0] d_addr,    //address for data memory
output wire [7:0] i_addr,    //pc
output wire [15:0] d_dataout,//output data to data memory
output wire d_we             //write enable
);
reg state,next_state;  //to control the CPU
reg [7:0] pc;
reg [15:0] id_ir,ex_ir,mem_ir,wb_ir;
reg [15:0] reg_A, reg_B, reg_C, reg_C1, smdr, smdr1, ALUo;
reg dw, zf, nf, cf, cin;
reg [15:0] gr[0:7];
assign d_dataout = smdr1;
assign d_we = dw;
assign d_addr = reg_C[7:0];
assign i_addr = pc;
//************* CPU control *************//
always @(posedge clock or negedge reset)
begin
if (!reset)
state <= `idle;
else
state <= next_state;
end
always @(*)
begin
case (state)
`idle :
if ((enable == 1'b1) && (start == 1'b1)) // on
next_state <= `exec;
else
next_state <= `idle;
`exec :
if ((enable == 1'b0) || (wb_ir[15:11] == `HALT))//pause
next_state <= `idle;
else
next_state <= `exec;
endcase
end

//************* IF *************// 取址
always @(posedge clock or negedge reset)
begin
if (!reset)
begin
id_ir <= 16'b0000_0000_0000_0000;
pc <= 8'b0000_0000;
end

else if (state ==`exec)
begin
if((ex_ir[15:11] == `BZ && zf == 1'b1) || (ex_ir[15:11] == `BN && nf == 1'b1)
||(ex_ir[15:11] == `BNZ && zf == 1'b0) || (ex_ir[15:11] == `BNN && nf == 1'b0)
||(ex_ir[15:11] == `BC && cin == 1'b1) || (ex_ir[15:11] == `BNC && cin == 1'b0)
|| ex_ir[15:11] == `JMPR)
begin
pc <= ALUo[7:0];
id_ir <= 16'bx;//flush
end
else if(id_ir[15:11] == `JUMP)
begin
pc <= id_ir[7:0]; //jump to {val2,val3}
id_ir <= 16'bx;
end
else if(id_ir[15:11] == `HALT) // STOP
begin
pc <= pc;
id_ir <= id_ir;
end
//Load hazard  Stall
else if((id_ir[15:11] == `LOAD)&&(i_datain[15:11]!=`JUMP)&&(i_datain[15:11]!=`NOP)&&(i_datain[15:11]!=`HALT)
&&(i_datain[15:11]!=`LOAD))
begin
//r1
if((id_ir[10:8]==i_datain[2:0])&&((i_datain[15:11]==`ADD)||(i_datain[15:11]==`ADDC)
||(i_datain[15:11]==`SUB)||(i_datain[15:11]==`SUBC)||(i_datain[15:11]==`CMP)||(i_datain[15:11]==`AND)
||(i_datain[15:11]==`OR)||(i_datain[15:11]==`XOR)))
begin
pc <= pc;
id_ir <= 16'bx;
end
//r2
else if((id_ir[10:8]==i_datain[6:4])&&((i_datain[15:11]==`STORE)||(i_datain[15:11]==`ADD)
||(i_datain[15:11]==`ADDC)||(i_datain[15:11]==`SUB)||(i_datain[15:11]==`SUBC)||(i_datain[15:11]==`AND)
||(i_datain[15:11]==`OR)||(i_datain[15:11]==`XOR)||(i_datain[15:11]==`CMP)||(i_datain[15:11]==`SLL)
||(i_datain[15:11]==`SRL)||(i_datain[15:11]==`SLA)||(i_datain[15:11]==`SRA)))
begin
pc <= pc;
id_ir <= 16'bx;
end
//r3
else if((id_ir[10:8]==i_datain[10:8])&&((i_datain[15:11]==`STORE)||(i_datain[15:11]==`LDIH)
||(i_datain[15:11]==`SUBI)||(i_datain[15:11]==`JMPR)||(i_datain[15:11]==`BZ)||(i_datain[15:11]==`BNZ)
||(i_datain[15:11]==`BN)||(i_datain[15:11]==`BNN)||(i_datain[15:11]==`BNC)||(i_datain[15:11]==`BNC)))
begin
pc <= pc;
id_ir <= 16'bx;
end
else
begin
pc <= pc + 1'b1;
id_ir <= i_datain;
end
end
else
begin
pc <= pc + 1'b1;
id_ir <= i_datain;
end
end
else if(state==`idle)
begin
id_ir <= id_ir;
pc <= pc;
end
end
//************* ID *************//译码
always @(posedge clock or negedge reset)
begin
if (!reset)
begin
ex_ir <= 16'b0000_0000_0000_0000;
reg_A <= 16'b0000_0000_0000_0000;
reg_B <= 16'b0000_0000_0000_0000;
smdr <= 16'b0000_0000_0000_0000;
end
//flush
else if(state == `exec && ((ex_ir[15:11]==`BZ && zf==1'b1) ||(ex_ir[15:11]==`BNZ && zf==1'b0)
||(ex_ir[15:11]==`BN && nf==1'b1) || (ex_ir[15:11]==`BNN && nf==1'b0) ||(ex_ir[15:11]==`BC && cin==1'b1)
||(ex_ir[15:11]==`BNC && cin==1'b0) || ex_ir[15:11]==`JMPR))
ex_ir <= 16'bx;

else if (state == `exec)
begin
ex_ir <= id_ir;
//regA
//r1=r1+{val2,val3}
if ((id_ir[15:11] == `BZ) || (id_ir[15:11] == `BNZ) || (id_ir[15:11] == `BN) || (id_ir[15:11] == `BNN)
|| (id_ir[15:11] == `BC) || (id_ir[15:11] == `BNC) || (id_ir[15:11] == `LDIH) || (id_ir[15:11] == `ADDI)
|| (id_ir[15:11] == `SUBI) || (id_ir[15:11] == `JMPR))
begin
//r1未写回
if(id_ir[10:8]==ex_ir[10:8]&&(ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI || ex_ir[15:11] == `SUB
|| ex_ir[15:11] == `SUBI || ex_ir[15:11] == `ADDC || ex_ir[15:11] == `SUBC || ex_ir[15:11] == `AND
|| ex_ir[15:11] == `OR || ex_ir[15:11] == `XOR || ex_ir[15:11] == `SLL || ex_ir[15:11] == `SRL
|| ex_ir[15:11] == `SLA || ex_ir[15:11] == `SRA ))
reg_A <= ALUo;
else if(id_ir[10:8] == mem_ir[10:8]&&(mem_ir[15:11] == `ADD || mem_ir[15:11] == `LDIH || mem_ir[15:11] == `ADDI
|| mem_ir[15:11] == `SUB || mem_ir[15:11] == `SUBI || mem_ir[15:11] == `ADDC
|| mem_ir[15:11] == `SUBC || mem_ir[15:11] == `AND || mem_ir[15:11] == `OR || mem_ir[15:11] == `XOR
|| mem_ir[15:11] == `SLL || mem_ir[15:11] == `SRL || mem_ir[15:11] == `SLA || mem_ir[15:11] == `SRA
|| mem_ir[15:11] == `LOAD))
begin
if(mem_ir[15:11]==`LOAD)  //load是否出结果
reg_A <= d_datain;
else
reg_A <= reg_C;
end
else if(wb_ir[10:8] == id_ir[10:8]&&(wb_ir[15:11] == `ADD || wb_ir[15:11] == `LDIH || wb_ir[15:11] == `ADDI
|| wb_ir[15:11] == `SUB || wb_ir[15:11] == `SUBI || wb_ir[15:11] == `ADDC || wb_ir[15:11] == `SUBC
|| wb_ir[15:11] == `AND || wb_ir[15:11] == `OR || wb_ir[15:11] == `XOR || wb_ir[15:11] == `SLL
|| wb_ir[15:11] == `SRL || wb_ir[15:11] == `SLA || wb_ir[15:11] == `SRA || wb_ir[15:11] == `LOAD ))
reg_A <= reg_C1;
else
reg_A <= gr[(id_ir[10:8])];//gr1
end
//r1=r2#r3 or r1=r2#val
else if(id_ir[15:11] == `LOAD || id_ir[15:11] == `STORE || id_ir[15:11] == `ADD || id_ir[15:11] == `SUB
|| id_ir[15:11] == `ADDC || id_ir[15:11] == `SUBC || id_ir[15:11] == `CMP || id_ir[15:11] == `AND
|| id_ir[15:11] == `OR || id_ir[15:11] == `XOR || id_ir[15:11] == `SLL || id_ir[15:11] == `SRL
|| id_ir[15:11] == `SLA || id_ir[15:11] == `SRA)
begin
//r2未写回
if( (ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI || ex_ir[15:11] == `SUB
|| ex_ir[15:11] == `SUBI || ex_ir[15:11] == `ADDC || ex_ir[15:11] == `SUBC || ex_ir[15:11] == `AND
|| ex_ir[15:11] == `OR || ex_ir[15:11] == `XOR || ex_ir[15:11] == `SLL || ex_ir[15:11] == `SRL
|| ex_ir[15:11] == `SLA || ex_ir[15:11] == `SRA )&& ex_ir[10:8] == id_ir[6:4])
reg_A <= ALUo;
else if( (mem_ir[15:11] == `ADD || mem_ir[15:11] == `LDIH || mem_ir[15:11] == `ADDI
|| mem_ir[15:11] == `SUB || mem_ir[15:11] == `SUBI || mem_ir[15:11] == `ADDC
|| mem_ir[15:11] == `SUBC || mem_ir[15:11] == `AND || mem_ir[15:11] == `OR || mem_ir[15:11] == `XOR
|| mem_ir[15:11] == `SLL || mem_ir[15:11] == `SRL || mem_ir[15:11] == `SLA || mem_ir[15:11] == `SRA
|| mem_ir[15:11] == `LOAD)&& mem_ir[10:8] == id_ir[6:4])
if(mem_ir[15:11]==`LOAD)
reg_A <= d_datain;
else
reg_A <= reg_C;
else if( (wb_ir[15:11] == `ADD || wb_ir[15:11] == `LDIH || wb_ir[15:11] == `ADDI || wb_ir[15:11] == `SUB
|| wb_ir[15:11] == `SUBI || wb_ir[15:11] == `ADDC || wb_ir[15:11] == `SUBC || wb_ir[15:11] == `AND
|| wb_ir[15:11] == `OR || wb_ir[15:11] == `XOR || wb_ir[15:11] == `SLL || wb_ir[15:11] == `SRL
|| wb_ir[15:11] == `SLA || wb_ir[15:11] == `SRA || wb_ir[15:11] == `LOAD )&& wb_ir[10:8] == id_ir[6:4])
reg_A <= reg_C1;
else
reg_A <= gr[id_ir[6:4]];//gr2
end
//flush
else if((mem_ir[15:11]==`BZ && zf==1'b1) ||(mem_ir[15:11]==`BNZ && zf==1'b0)
||(mem_ir[15:11]==`BN && nf==1'b1) || (mem_ir[15:11]==`BNN && nf==1'b0) ||(mem_ir[15:11]==`BC && cin==1'b1)
||(mem_ir[15:11]==`BNC && cin==1'b0) || mem_ir[15:11]==`JMPR)
reg_A <= 16'bx;
else if(id_ir[15:11] == `JUMP)
reg_A <= 16'bx;
else
reg_A <= gr[id_ir[6:4]];//gr2
//regB
if (id_ir[15:11] == `LOAD || id_ir[15:11] == `STORE || id_ir[15:11] == `SLL || (id_ir[15:11] == `SRL)
|| (id_ir[15:11] == `SLA) || (id_ir[15:11] == `SRA))
reg_B <= {12'b0000_0000_0000, id_ir[3:0]};//val3
else if ((id_ir[15:11] == `BZ) || (id_ir[15:11] == `BNZ) || (id_ir[15:11] == `BN) || (id_ir[15:11] == `BNN)
|| (id_ir[15:11] == `BC) || (id_ir[15:11] == `BNC)
|| (id_ir[15:11] == `ADDI) || (id_ir[15:11] == `SUBI) || (id_ir[15:11] == `JMPR))
reg_B <= {8'b0000_0000, id_ir[7:0]};//{00000000, value2,value3}
else if(id_ir[15:11] == `LDIH)
reg_B <= {id_ir[7:0], 8'b0000_0000};//{val2,val3,00000000)
//r1=r2#r3
else if(id_ir[15:11] == `ADD || id_ir[15:11] == `SUB || id_ir[15:11] == `ADDC || id_ir[15:11] == `SUBC
|| id_ir[15:11] == `CMP || id_ir[15:11] == `AND || id_ir[15:11] == `OR || id_ir[15:11] == `XOR)
begin
if( (ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI || ex_ir[15:11] == `SUB
|| ex_ir[15:11] == `SUBI || ex_ir[15:11] == `ADDC || ex_ir[15:11] == `SUBC || ex_ir[15:11] == `AND
|| ex_ir[15:11] == `OR || ex_ir[15:11] == `XOR || ex_ir[15:11] == `SLL || ex_ir[15:11] == `SRL
|| ex_ir[15:11] == `SLA || ex_ir[15:11] == `SRA )&& ex_ir[10:8] == id_ir[2:0])
reg_B <= ALUo;
else if( (mem_ir[15:11] == `ADD || mem_ir[15:11] == `LDIH || mem_ir[15:11] == `ADDI
|| mem_ir[15:11] == `LOAD || mem_ir[15:11] == `SUB || mem_ir[15:11] == `SUBI || mem_ir[15:11] == `ADDC
|| mem_ir[15:11] == `SUBC || mem_ir[15:11] == `AND || mem_ir[15:11] == `OR || mem_ir[15:11] == `XOR
|| mem_ir[15:11] == `SLL || mem_ir[15:11] == `SRL || mem_ir[15:11] == `SLA || mem_ir[15:11] == `SRA )
&& mem_ir[10:8] == id_ir[2:0])
begin
if(mem_ir[15:11]==`LOAD)
reg_B <= d_datain;
else
reg_B <= reg_C;
end
else if( (wb_ir[15:11] == `ADD || wb_ir[15:11] == `LDIH || wb_ir[15:11] == `ADDI || wb_ir[15:11] == `SUB
|| wb_ir[15:11] == `SUBI || wb_ir[15:11] == `ADDC || wb_ir[15:11] == `SUBC || wb_ir[15:11] == `AND
|| wb_ir[15:11] == `OR || wb_ir[15:11] == `XOR || wb_ir[15:11] == `SLL || wb_ir[15:11] == `SRL
|| wb_ir[15:11] == `SLA || wb_ir[15:11] == `SRA || wb_ir[15:11] == `LOAD)&& wb_ir[10:8] == id_ir[2:0])
reg_B <= reg_C1;
else
reg_B <= gr[id_ir[2:0]];//gr2
end
//flush
else if((mem_ir[15:11]==`BZ && zf==1'b1) ||(mem_ir[15:11]==`BNZ && zf==1'b0)
||(mem_ir[15:11]==`BN && nf==1'b1) || (mem_ir[15:11]==`BNN && nf==1'b0) ||(mem_ir[15:11]==`BC && cin==1'b1)
||(mem_ir[15:11]==`BNC && cin==1'b0) || mem_ir[15:11]==`JMPR)
reg_B <= 16'bx;
else if(id_ir[15:11] == `JUMP)
reg_B <= 16'bx;
else
reg_B <= gr[id_ir[2:0]];//gr3
//STORE
if (id_ir[15:11] == `STORE)
begin
//r1未写回
if(id_ir[10:8] == ex_ir[10:8] && (ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI
|| ex_ir[15:11] == `SUB || ex_ir[15:11] == `SUBI || ex_ir[15:11] == `ADDC || ex_ir[15:11] == `SUBC
|| ex_ir[15:11] == `AND || ex_ir[15:11] == `OR || ex_ir[15:11] == `XOR || ex_ir[15:11] == `SLL
|| ex_ir[15:11] == `SRL || ex_ir[15:11] == `SLA || ex_ir[15:11] == `SRA ))
smdr <= ALUo;
else if(id_ir[10:8] == mem_ir[10:8] && (mem_ir[15:11] == `ADD || mem_ir[15:11] == `LDIH
|| mem_ir[15:11] == `ADDI || mem_ir[15:11] == `SUB || mem_ir[15:11] == `SUBI || mem_ir[15:11] == `ADDC
|| mem_ir[15:11] == `SUBC || mem_ir[15:11] == `AND || mem_ir[15:11] == `OR || mem_ir[15:11] == `XOR
|| mem_ir[15:11] == `SLL || mem_ir[15:11] == `SRL || mem_ir[15:11] == `SLA || mem_ir[15:11] == `SRA
|| mem_ir[15:11] == `LOAD))
begin
if(mem_ir[15:11]==`LOAD)
smdr <= d_datain;
else
smdr <= reg_C;
end
else if(id_ir[10:8] == wb_ir[10:8] && (wb_ir[15:11] == `ADD || wb_ir[15:11] == `LDIH
|| wb_ir[15:11] == `LOAD || wb_ir[15:11] == `ADDI || wb_ir[15:11] == `SUB || wb_ir[15:11] == `SUBI
|| wb_ir[15:11] == `ADDC || wb_ir[15:11] == `SUBC || wb_ir[15:11] == `AND || wb_ir[15:11] == `OR
|| wb_ir[15:11] == `XOR || wb_ir[15:11] == `SLL || wb_ir[15:11] == `SRL || wb_ir[15:11] == `SLA
|| wb_ir[15:11] == `SRA ))
smdr <= reg_C1;
else
smdr <= gr[id_ir[10:8]];
end
else
smdr <= gr[id_ir[10:8]];

end
end
//************* ALU *************//计算
reg signed [15:0] reg_A1;// for SRA 算术右移
always @(*)
begin
reg_A1 <= reg_A;
end

always @(*)
begin
//加减
if(ex_ir[15:11] == `ADD || ex_ir[15:11] == `LDIH || ex_ir[15:11] == `ADDI)
{cf, ALUo} <= reg_A + reg_B;
else if(ex_ir[15:11] == `CMP || (ex_ir[15:11] == `SUB) || (ex_ir[15:11] == `SUBI))
{cf, ALUo} <= reg_A - reg_B;
else if(ex_ir[15:11] == `ADDC)
{cf, ALUo} <= reg_A + reg_B + cin;
else if(ex_ir[15:11] == `SUBC)
{cf, ALUo} <= reg_A - reg_B - cin;
//逻辑
else if(ex_ir[15:11] == `AND)
{cf, ALUo} <= reg_A & reg_B;
else if(ex_ir[15:11] == `OR)
{cf, ALUo} <= reg_A | reg_B;
else if(ex_ir[15:11] == `XOR)
{cf, ALUo} <= reg_A ^ reg_B;
//移位
else if(ex_ir[15:11] == `SLL)
{cf, ALUo} <= reg_A << reg_B;
else if(ex_ir[15:11] == `SRL)
{cf, ALUo} <= reg_A >> reg_B;
else if(ex_ir[15:11] == `SLA)
{cf, ALUo} <= reg_A <<< reg_B;
else if(ex_ir[15:11] == `SRA)
{cf, ALUo} <= reg_A1 >>> reg_B;
//存取、跳转
else if(ex_ir[15:11] == `LOAD || ex_ir[15:11] == `STORE
|| ex_ir[15:11] == `BN || ex_ir[15:11] == `BNN || ex_ir[15:11] == `BZ || ex_ir[15:11] == `BNZ
|| ex_ir[15:11] == `BC || ex_ir[15:11] == `BNC || ex_ir[15:11] == `JMPR)
{cf, ALUo} <= reg_A + reg_B;
else
{cf, ALUo} <= 17'b0;
end
//************* EX *************//  执行
always @(posedge clock or negedge reset)
begin
if (!reset)
begin
mem_ir <= 16'b0000_0000_0000_0000;
reg_C <= 16'b0000_0000_0000_0000;
smdr1 <= 16'b0000_0000_0000_0000;
zf <= 1'b0;
nf <= 1'b0;
cin <= 1'b0;
dw <= 1'b0;
end
else if (state == `exec)
begin
mem_ir <= ex_ir;
reg_C <= ALUo;

if ((ex_ir[15:11] == `ADD) || (ex_ir[15:11] == `CMP) || (ex_ir[15:11] == `LDIH) || (ex_ir[15:11] == `ADDI)
|| (ex_ir[15:11] == `ADDC) || (ex_ir[15:11] == `SUB) || (ex_ir[15:11] == `SUBI) || (ex_ir[15:11] == `SUBC))
begin
if (ALUo == 16'b0000_0000_0000_0000)
zf <= 1'b1;//if zero
else
zf <= 1'b0;
if (ALUo[15] == 1'b1)//if negative
nf <= 1'b1;
else
nf <= 1'b0;
end
else
begin
zf <= zf;
nf <= nf;
end
//carry
if ((ex_ir[15:11] == `ADD) || (ex_ir[15:11] == `LDIH) || (ex_ir[15:11] == `ADDI) || (ex_ir[15:11] == `ADDC)
|| (ex_ir[15:11] == `SUB) || (ex_ir[15:11] == `SUBI) || (ex_ir[15:11] == `SUBC))
cin <= cf;
else
cin <= cin;
//STORE
if (ex_ir[15:11] == `STORE)
begin
dw <= 1'b1;//data wire enable
smdr1 <= smdr;
end
else
begin
dw <= 1'b0;
smdr1 <= 16'b0;
end

end
end
//************* MEM *************// 存储器访问
always @(posedge clock or negedge reset)
begin
if (!reset)
begin
wb_ir <= 16'b0000_0000_0000_0000;
reg_C1 <= 16'b0000_0000_0000_0000;
end
else if (state == `exec)
begin
wb_ir <= mem_ir;
if (mem_ir[15:11] == `LOAD)
reg_C1 <= d_datain;
else
reg_C1 <= reg_C;
end
end
//************* WB *************//
always @(posedge clock or negedge reset)//写回
begin
if (!reset)
begin
gr[7] <= 16'b0000_0000_0000_0000;
gr[6] <= 16'b0000_0000_0000_0000;
gr[5] <= 16'b0000_0000_0000_0000;
gr[4] <= 16'b0000_0000_0000_0000;
gr[3] <= 16'b0000_0000_0000_0000;
gr[2] <= 16'b0000_0000_0000_0000;
gr[1] <= 16'b0000_0000_0000_0000;
gr[0] <= 16'b0000_0000_0000_0000;
end
else if (state == `exec)
begin
if ((wb_ir[15:11] == `LOAD) || (wb_ir[15:11] == `ADD) || (wb_ir[15:11] == `LDIH) || (wb_ir[15:11] == `ADDI)
|| (wb_ir[15:11] == `ADDC) || (wb_ir[15:11] == `SUB) || (wb_ir[15:11] == `SUBI) || (wb_ir[15:11] == `SUBC)
||(wb_ir[15:11] == `AND) ||(wb_ir[15:11] == `OR) ||(wb_ir[15:11] == `XOR) || (wb_ir[15:11] == `SLL)
||(wb_ir[15:11] == `SRL) ||(wb_ir[15:11] == `SLA) || (wb_ir[15:11] == `SRA))
gr[wb_ir[10:8]] <= reg_C1;//write back to gr1
else
gr[wb_ir[10:8]] <= gr[wb_ir[10:8]];
end
end

endmodule


测试

Instruction Memory: I_mem.v

`include "headfile.v"
module I_mem(input wire [7:0] addra, output reg [15:0] douta
);
reg [15:0] i_mem[255:0];
always @(*)
begin
douta <= i_mem[addra];
end

initial begin

//init test
/*
i_mem[0]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h0010 for store address
i_mem[1]={`LDIH,`gr1,4'b1011,4'b0110};        // test for LDIH  gr1<="16'hb600"
i_mem[2]={`STORE,`gr1,1'b0,`gr7,4'h0};        // store to mem10
i_mem[3]={`LOAD,`gr1,1'b0,`gr0,4'h0};         // gr1 <= fffd
i_mem[4]={`LOAD,`gr2,1'b0,`gr0,4'h1};         // gr2 <= 4
i_mem[5]={`ADDC,`gr3,1'b0,`gr1,1'b0,`gr2};    // gr3 <= fffd + 4 + cf(=0) = 1, cf<=1
i_mem[6]={`STORE,`gr3,1'b0,`gr7,4'h1};        // store to mem11
i_mem[7]={`ADDC,`gr3,1'b0,`gr0,1'b0,`gr2};    // gr3 <= 0 + 4 + cf(=1) = 5, cf<=0
i_mem[8]={`STORE,`gr3,1'b0,`gr7,4'h2};        // store to mem12
i_mem[9]={`LOAD,`gr1,1'b0,`gr0,4'h2};          // gr1 <= 5
i_mem[10]={`SUBC,`gr3,1'b0,`gr1,1'b0,`gr2};    // gr3 <= 5 - 4 + cf(=0) =1, cf<=0
i_mem[11]={`STORE,`gr3,1'b0,`gr7,4'h3};        // store to mem13
i_mem[12]={`SUB,`gr3,1'b0,`gr2,1'b0,`gr1};     // gr3 <= 4 - 5 = -1, cf<=1
i_mem[13]={`STORE,`gr3,1'b0,`gr7,4'h4};        // store to mem14
i_mem[14]={`SUBC,`gr3,1'b0,`gr2,1'b0,`gr1};    // gr3 <= 5 - 4 - cf(=1) =2, cf<=0
i_mem[15]={`STORE,`gr3,1'b0,`gr7,4'h5};        // store to mem15
i_mem[16]={`LOAD,`gr1,1'b0,`gr0,4'h3};         // gr1 <= c369
i_mem[17]={`LOAD,`gr2,1'b0,`gr0,4'h4};         // gr2 <= 69c3
i_mem[18]={`AND,`gr3,1'b0,`gr1,1'b0,`gr2};     // gr3 <= gr1 & gr2 = 4141
i_mem[19]={`STORE,`gr3,1'b0,`gr7,4'h6};        // store to mem16
i_mem[20]={`OR,`gr3,1'b0,`gr1,1'b0,`gr2};      // gr3 <= gr1 | gr2 = ebeb
i_mem[21]={`STORE,`gr3,1'b0,`gr7,4'h7};        // store to mem17
i_mem[22]={`XOR,`gr3,1'b0,`gr1,1'b0,`gr2};     // gr3 <= gr1 ^ gr2 = aaaa
i_mem[23]={`STORE,`gr3,1'b0,`gr7,4'h8};        // store to mem18
i_mem[24]={`SLL,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 < 0
i_mem[25]={`STORE,`gr3,1'b0,`gr7,4'h9};        // store to mem19
i_mem[26]={`SLL,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 < 1
i_mem[27]={`STORE,`gr3,1'b0,`gr7,4'ha};        // store to mem1a
i_mem[28]={`SLL,`gr3,1'b0,`gr1,4'h4};          // gr3 <= gr1 < 8
i_mem[29]={`STORE,`gr3,1'b0,`gr7,4'hb};        // store to mem1b
i_mem[30]={`SLL,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 < 15
i_mem[31]={`STORE,`gr3,1'b0,`gr7,4'hc};        // store to mem1c
i_mem[32]={`SRL,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 > 0
i_mem[33]={`STORE,`gr3,1'b0,`gr7,4'hd};        // store to mem1d
i_mem[34]={`SRL,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 > 1
i_mem[35]={`STORE,`gr3,1'b0,`gr7,4'he};        // store to mem1e
i_mem[36]={`SRL,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 > 8
i_mem[37]={`STORE,`gr3,1'b0,`gr7,4'hf};        // store to mem1f
i_mem[38]={`SRL,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 > 15
i_mem[39]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h20 for store address
i_mem[40]={`STORE,`gr3,1'b0,`gr7,4'h0};        // store to mem20
i_mem[41]={`SLA,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 < 0
i_mem[42]={`STORE,`gr3,1'b0,`gr7,4'h1};        // store to mem21
i_mem[43]={`SLA,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 < 1
i_mem[44]={`STORE,`gr3,1'b0,`gr7,4'h2};        // store to mem22
i_mem[45]={`SLA,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 < 8
i_mem[46]={`STORE,`gr3,1'b0,`gr7,4'h3};        // store to mem23
i_mem[47]={`SLA,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 < 15
i_mem[48]={`STORE,`gr3,1'b0,`gr7,4'h4};        // store to mem24
i_mem[49]={`SLA,`gr3,1'b0,`gr2,4'h0};          // gr3 <= gr1 < 0
i_mem[50]={`STORE,`gr3,1'b0,`gr7,4'h5};        // store to mem25
i_mem[51]={`SLA,`gr3,1'b0,`gr2,4'h1};          // gr3 <= gr1 < 1
i_mem[52]={`STORE,`gr3,1'b0,`gr7,4'h6};        // store to mem26
i_mem[53]={`SLA,`gr3,1'b0,`gr2,4'h8};          // gr3 <= gr1 < 8
i_mem[54]={`STORE,`gr3,1'b0,`gr7,4'h7};        // store to mem27
i_mem[55]={`SLA,`gr3,1'b0,`gr2,4'hf};          // gr3 <= gr1 < 15
i_mem[56]={`STORE,`gr3,1'b0,`gr7,4'h8};        // store to mem28
i_mem[57]={`SRA,`gr3,1'b0,`gr1,4'h0};          // gr3 <= gr1 > 0
i_mem[58]={`STORE,`gr3,1'b0,`gr7,4'h9};        // store to mem29
i_mem[59]={`SRA,`gr3,1'b0,`gr1,4'h1};          // gr3 <= gr1 > 1
i_mem[60]={`STORE,`gr3,1'b0,`gr7,4'ha};        // store to mem2a
i_mem[61]={`SRA,`gr3,1'b0,`gr1,4'h8};          // gr3 <= gr1 > 8
i_mem[62]={`STORE,`gr3,1'b0,`gr7,4'hb};        // store to mem2b
i_mem[63]={`SRA,`gr3,1'b0,`gr1,4'hf};          // gr3 <= gr1 > 15
i_mem[64]={`STORE,`gr3,1'b0,`gr7,4'hc};        // store to mem2c
i_mem[65]={`SRA,`gr3,1'b0,`gr2,4'h0};          // gr3 <= gr1 > 0
i_mem[66]={`STORE,`gr3,1'b0,`gr7,4'hd};        // store to mem2d
i_mem[67]={`SRA,`gr3,1'b0,`gr2,4'h1};          // gr3 <= gr1 > 1
i_mem[68]={`STORE,`gr3,1'b0,`gr7,4'he};        // store to mem2e
i_mem[69]={`SRA,`gr3,1'b0,`gr2,4'h8};          // gr3 <= gr1 > 8
i_mem[70]={`STORE,`gr3,1'b0,`gr7,4'hf};        // store to mem2f
i_mem[71]={`ADDI,`gr7,4'd1,4'd0};              // gr7 <= 16'h30 for store address
i_mem[72]={`SRA,`gr3,1'b0,`gr2,4'hf};          // gr3 <= gr1 > 15
i_mem[73]={`STORE,`gr3,1'b0,`gr7,4'h0};        // store to mem30
i_mem[74]={`LOAD,`gr1,1'b0,`gr0,4'h5};         // gr1 <= 41
i_mem[75]={`LOAD,`gr2,1'b0,`gr0,4'h6};         // gr2 <= ffff
i_mem[76]={`LOAD,`gr3,1'b0,`gr0,4'h7};         // gr3 <= 1
i_mem[77]={`JUMP, 3'd0,8'h4f};                 // jump to 4f
i_mem[78]={`STORE,`gr7,1'b0,`gr7,4'h1};        // store to mem31
i_mem[79]={`JMPR, `gr1,8'h10};                 // jump to 41+10 = 51
i_mem[80]={`STORE,`gr7,1'b0,`gr7,4'h2};        // store to mem32
i_mem[81]={`ADD, `gr4,1'b0,`gr2,1'b0,`gr3};    // gr4<= ffff + 1,cf<=1
i_mem[82]={`BNC,`gr1,8'h28};                   // if(cf==0) jump to 69
i_mem[83]={`BC,`gr1,8'h14};                    // if(cf==1) jump to 55
i_mem[84]={`STORE,`gr7,1'b0,`gr7,4'h3};        // store to mem33
i_mem[85]={`ADD, `gr4,1'b0,`gr3,1'b0,`gr3};    // gr4<= 1 + 1 , cf<=0
i_mem[86]={`BC,`gr1,8'h28};                    // if(cf==1) jump to 69
i_mem[87]={`BNC,`gr1,8'h18};                   // if(cf==0) jump to 59
i_mem[88]={`STORE,`gr7,1'b0,`gr7,4'h4};        // store to mem34
i_mem[89]={`CMP, 3'd0,1'b0,`gr3,1'b0,`gr3};    // 1-1=0 , zf<=1,nf<=0
i_mem[90]={`BNZ,`gr1,8'h28};                   // if(zf==0) jump to 69
i_mem[91]={`BZ,`gr1,8'h1c};                    // if(zf==1) jump to 5d
i_mem[92]={`STORE,`gr7,1'b0,`gr7,4'h5};        // store to mem35
i_mem[93]={`CMP, 3'd0,1'b0,`gr4,1'b0,`gr3};    // 2-1=1 , zf<=0,nf<=0
i_mem[94]={`BZ,`gr1,8'h28};                    // if(zf==1) jump to 69
i_mem[95]={`BNZ,`gr1,8'h20};                   // if(zf==0) jump to 61
i_mem[96]={`STORE,`gr7,1'b0,`gr7,4'h6};        // store to mem36
i_mem[97]={`CMP, 3'd0,1'b0,`gr3,1'b0,`gr4};    // 1-2=-1, nf<=1,zf<=0
i_mem[98]={`BNN,`gr1,8'h28};                   // if(nf==0) jump to 69
i_mem[99]={`BN,`gr1,8'h24};                    // if(nf==1) jump to 65
i_mem[100]={`STORE,`gr7,1'b0,`gr7,4'h7};       // store to mem37
i_mem[101]={`CMP, 3'd0,1'b0,`gr4,1'b0,`gr3};   // 2-1=1, nf<=0,zf<=0
i_mem[102]={`BN,`gr1,8'h28};                   // if(nf==1) jump to 69
i_mem[103]={`BNN,`gr1,8'h27};                  // if(nf==0) jump to 68
i_mem[104]={`STORE,`gr7,1'b0,`gr7,4'h8};       // store to mem38
i_mem[105]={`HALT, 11'd0};                     // STOP*/

//最大公因数 最小公倍数:gcm

i_mem[0] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0001};  //gr1=0009
i_mem[1] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0010};  //gr2 = 0003
i_mem[2] <= {`ADD, `gr3, 1'b0, `gr0, 1'b0, `gr1}; //gr3=0009  0006  0003
i_mem[3] <= {`SUB, `gr1, 1'b0, `gr1, 1'b0, `gr2}; //gr1=0006  0003  0
i_mem[4] <= {`BZ, `gr0, 8'b0000_1001}; //no no jump to 09
i_mem[5] <= {`BNN, `gr0,  8'b0000_0010}; //jump to 2  jump to 2
i_mem[6] <= {`ADD, `gr1, 1'b0, `gr0, 1'b0, `gr2};
i_mem[7] <= {`ADD, `gr2, 1'b0, `gr0, 1'b0, `gr3};
i_mem[8] <= {`JUMP, 11'b000_0000_0010};
i_mem[9] <= {`STORE, `gr2, 1'b0, `gr0, 4'b0011}; //d[3]=0003
i_mem[10] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0001}; //gr1 = 0009
i_mem[11] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0010}; //gr2 = 0003
i_mem[12] <= {`ADDI, `gr4, 8'h1}; // gr4=1
i_mem[13] <= {`SUB, `gr2, 1'b0, `gr2, 1'b0, `gr3}; //gr2 = 0
i_mem[14] <= {`BZ, `gr0, 8'b0001_0000}; //jump to 16
i_mem[15] <= {`JUMP, 11'b000_0000_1100}; //
i_mem[16] <= {`SUBI, `gr4, 8'h1}; // gr4 = 0  -1
i_mem[17] <= {`BN, `gr0, 8'b0001_0100}; //no  jump to 20
i_mem[18] <= {`ADD, `gr5, 1'b0, `gr5, 1'b0, `gr1};  //gr5 = 0009
i_mem[19] <= {`JUMP, 11'b000_0001_0000}; //jump to 16
i_mem[20] <= {`STORE, `gr5, 1'b0, `gr0, 4'b0100}; //d[4]=0009
i_mem[21] <= {`LOAD, `gr1, 1'b0, `gr0, 4'b0011};//gr1=0003
i_mem[22] <= {`LOAD, `gr2, 1'b0, `gr0, 4'b0100};//gr2=0009
i_mem[23] <= {`HALT, 11'b000_0000_0000};

//64位加法:64badder
/*
i_mem[0]=16'h4c04 ; //{`ADDI,`gr4,8'h04};  gr4=0004
i_mem[1]=16'h1100 ; //{`LOAD, `gr1, 1'b0, `gr0, 4'b0000};  gr1 = fffe
i_mem[2]=16'h1204 ; //{`LOAD, `gr2, 1'b0, `gr0, 4'b0100};  gr2 = ffff
i_mem[3]=16'h4312 ; //{`ADD, `gr3, 1'b0, `gr1, 1'b0, `gr2};  gr3 = fffd
i_mem[4]=16'hfd06 ; //{`BNC, `gr5, 8'b0000_0110};  no
i_mem[5]=16'h4e01 ; //{`ADDI,`gr6,8'h01};  gr6=0001
i_mem[6]=16'h4337 ; //{`ADD, `gr3, 1'b0, `gr3, 1'b0, `gr7};  gr3 = fffd
i_mem[7]=16'hfd0b ; //{`BNC, `gr5, 8'b0000_1011};jump to 11
i_mem[8]=16'h5e00 ;  //{`SUBI, `gr6, 8'h0};
i_mem[9]=16'hdd0b ;   //{`BNZ, `gr5, 8'h0b};
i_mem[10]=16'h4e01 ;  //{`ADDI,`gr6,8'h01};
i_mem[11]=16'h5777 ;    //{`SUB, `gr7, 1'b0, `gr7, 1'b0, `gr7};  gr7 = 0
i_mem[12]=16'h4776 ;  //{`ADD, `gr7, 1'b0, `gr7, 1'b0, `gr6};  gr7 = 0001
i_mem[13]=16'h5666 ;    //{`SUB, `gr6, 1'b0, `gr6, 1'b0, `gr6};  gr6 = 0
i_mem[14]=16'h1b08 ;  //{`STORE, `gr3, 1'b0, `gr0, 4'b1000};  d[8]=fffd
i_mem[15]=16'h4801 ;     //{`ADDI,`gr0,8'h01};  gr0=0001
i_mem[16]=16'h6004 ;  //{`CMP, 3'b0,1'b0,`gr0,1'b0,`gr4}; 1<4
i_mem[17]=16'he501 ; //{`BN, `gr5, 8'b0000_0001};  jump to 1
i_mem[18]=16'h0800 ; //halt*/

//冒泡排序
/*
i_mem[0] <= {`LOAD, `gr3, 1'b0, `gr0, 4'b0000};  //gr3=000a;
i_mem[1] <= {`SUBI, `gr3, 4'd0, 4'd2};   //gr3=0008
i_mem[2] <= {`ADD, `gr1, 1'b0, `gr0, 1'b0, `gr0};  //gr1=0
i_mem[3] <= {`ADD, `gr2, 1'b0, `gr3, 1'b0, `gr0}; //gr2=0008
i_mem[4] <= {`LOAD, `gr4, 1'b0, `gr2, 4'd1}; //gr4=d[9]=1057
i_mem[5] <= {`LOAD, `gr5, 1'b0, `gr2, 4'd2}; //gr5=d[10]=2895
i_mem[6] <= {`CMP, 3'd0, 1'b0, `gr5, 1'b0, `gr4}; //d[10] > d[9]
i_mem[7] <= {`BN, `gr0, 4'b0000, 4'b1010};  //no
i_mem[8] <= {`STORE, `gr4, 1'b0, `gr2, 4'd2}; //d[10]=gr4
i_mem[9] <= {`STORE, `gr5, 1'b0, `gr2, 4'd1}; //d[9]=gr5;
i_mem[10] <= {`SUBI, `gr2, 4'd0, 4'd1};  //gr2=0007
i_mem[11] <= {`CMP, 3'd0, 1'b0, `gr2, 1'b0, `gr1}; //gr2>gr1
i_mem[12] <= {`BNN, `gr0, 4'h0, 4'b0100}; //
i_mem[13] <= {`ADDI, `gr1, 4'd0, 4'd1};
i_mem[14] <= {`CMP, 3'd0, 1'b0, `gr3, 1'b0, `gr1};
i_mem[15] <= {`BNN, `gr0, 4'h0, 4'b0011};
i_mem[16] <= {`HALT, 11'd0};
*/

//sort
/*
i_mem[0] <= {`ADDI, `gr1, 4'b0000,  4'b1001};
i_mem[1] <= {`ADDI, `gr2, 4'b0000,  4'b1001};
i_mem[2] <= {`JUMP, 11'b000_0000_0101};//jump to start
i_mem[3] <= {`SUBI, `gr1, 4'd0, 4'd1};//new_round
i_mem[4] <= {`BZ, `gr7, 4'b0001, 4'b0010};//jump to end
i_mem[5] <= {`LOAD, `gr3, 1'b0, `gr0, 4'd0};//start
i_mem[6] <= {`LOAD, `gr4, 1'b0, `gr0, 4'd1};
i_mem[7] <= {`CMP, 3'd0, 1'b0, `gr3, 1'b0, `gr4};
i_mem[8] <= {`BN, `gr7, 4'h0, 4'b1011};//jump to NO_op
i_mem[9] <= {`STORE, `gr3, 1'b0, `gr0, 4'd1};
i_mem[10] <= {`STORE, `gr4, 1'b0, `gr0, 4'd0};
i_mem[11] <= {`ADDI, `gr0, 4'b0000, 4'b0001};//NO_OP
i_mem[12] <= {`CMP, 3'd0, 1'b0, `gr0, 1'b0, `gr2};
i_mem[13] <= {`BN, `gr7, 4'b0001, 4'b0001};//jump to continue
i_mem[14] <= {`SUBI, `gr2, 4'd0, 4'd1};
i_mem[15] <= {`SUB, `gr0, 1'b0,`gr0, 1'b0,`gr0};
i_mem[16] <= {`JUMP, 11'b000_0000_0011};//jump to new round
i_mem[17] <= {`JUMP, 11'b000_0000_0101};//jump to start,continue
i_mem[18] <= {`HALT, 11'd0};//end
*/

end

endmodule


Data Memory : D_mem.v

module D_mem(input wire wea, input wire [7:0] addra, input wire [15:0] dina, output wire [15:0] douta
);
reg [15:0] d_mem[255:0];

assign  douta = d_mem[addra];

always @(*)
begin
if(wea == 1'b1)
d_mem[addra] <= dina;
end

initial begin
//init_test
/*
d_mem[0] <= 16'hfffd;
d_mem[1] <= 16'h0004;
d_mem[2] <= 16'h0005;
d_mem[3] <= 16'hc369;
d_mem[4] <= 16'h69c3;
d_mem[5] <= 16'h0041;
d_mem[6] <= 16'hffff;
d_mem[7] <= 16'h0001;
d_mem[8] <= 16'h0000;
d_mem[9] <= 16'h0000;
d_mem[10] <= 16'h0000;*/

//最大公因数 最小公倍数data

d_mem[0] <= 16'h0000;
d_mem[1] <= 16'h0020;  //32
d_mem[2] <= 16'h0018;   //24      8 96

//64badde
/*
d_mem[0] <= 16'hfffe;
d_mem[1] <= 16'hfffe;
d_mem[2] <= 16'hfffe;
d_mem[3] <= 16'h0000;
d_mem[4] <= 16'hffff;
d_mem[5] <= 16'hffff;
d_mem[6] <= 16'hffff;
d_mem[7] <= 16'h0000;
*/
//冒泡排序
/*
d_mem[0] <= 16'h000a;
d_mem[1] <= 16'h0004;
d_mem[2] <= 16'h0005;
d_mem[3] <= 16'h2369;
d_mem[4] <= 16'h69c3;
d_mem[5] <= 16'h0060;
d_mem[6] <= 16'h0fff;
d_mem[7] <= 16'h5555;
d_mem[8] <= 16'h6152;
d_mem[9] <= 16'h1057;
d_mem[10] <= 16'h2895;
d_mem[11] <= 16'h0000;
*/
//sort
/*
d_mem[0] = 16'h000a;
d_mem[1] = 16'h0009;
d_mem[2] = 16'h0006;
d_mem[3] = 16'h0005;
d_mem[4] = 16'h0001;
d_mem[5] = 16'h0004;
d_mem[6] = 16'h0003;
d_mem[7] = 16'h0011;
d_mem[8] = 16'h0000;
d_mem[9] = 16'h0000;
d_mem[10] = 16'h0000;
d_mem[11] = 16'h0000;/
*/
end
endmodule


仿真文件test.v

module test;

// Inputs
reg clk;
reg enable;
reg reset;
reg start;

// Instantiate the Unit Under Test (UUT)
cpu uut (
.clk(clk),
.enable(enable),
.reset(reset),
.start(start)
);
always #5 clk = ~clk;
initial begin
// Initialize Inputs
clk = 0;
enable = 0;
reset = 0;
start = 0;

$monitor("%h:%b:%h:%h:%h:%h:%h:%h:%b:%h:%h:%h:%h:%h:%h:%h:%h:%b:%b:%b",
uut.pcpu.pc, uut.pcpu.id_ir, uut.pcpu.reg_A, uut.pcpu.reg_B, uut.pcpu.reg_C,
uut.pcpu.d_addr, uut.pcpu.d_dataout, uut.pcpu.ALUo, uut.pcpu.d_we, uut.pcpu.reg_C1, uut.pcpu.gr[1], uut.pcpu.gr[2], uut.pcpu.gr[3],
uut.pcpu.gr[4], uut.pcpu.gr[5], uut.pcpu.gr[6],
uut.pcpu.gr[7], uut.pcpu.cin, uut.pcpu.nf, uut.pcpu.zf);

// Wait 100 ns for global reset to finish
#100;
$display("pc:      id_ir:    regA:regB:regC:da:dout:ALUo:dwe:reC1: gr1:gr2:gr3: gr4: gr5: gr6: gr7: cf:nf:zf");
// Add stimulus here
#10 reset <= 0;
#10 reset <= 1;
#10 enable <= 1;
#10 start <=1;
#10 start <= 0;
#100;

end

endmodule


结果验证(Data Memory)

init_test





最大公约数和最小公倍数

数字0x20和数字0x18的最大公约数是 0x0008,最小公倍数是0x0060。



64位加法



冒泡排序

0x000a表示要对10个数字进行排序,下面为十个排好序的数字。



排序

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息