EDA 游乐场链接:https://edaplayground.com/x/PQVx
有人可以帮我调试这个 verilog 设计吗?我检查了我的逻辑并检查了所有内容。然而,EDA playground 的模拟总是给我 count = 1 的每种情况。此外,只计算了 Testvector.txt 的前两行,EDA playground 给我一个错误:
警告:testbench.sv:24: $readmemb: 标准不一致,如下 1364-2005.
警告:testbench.sv:24: $readmemb(Testvector.txt): 中的单词太多 请求范围 [0:3] 的文件。
下面附上设计代码和测试台文件:
//top module
module GDP(count, start, restart, clk, n, done);
//top module combines all other modules, including DP and CU
// Note: nEqZero is the input N=0, that is false condition is //evaluated, just for the convenience
input start, clk, restart;
input [7:0] n;
output [7:0] count;
output done;
wire WE, RAE, RBE, OE, nEqZero, LSB, IE;
wire [1:0] WA, RAA, RBA, SH;
wire [2:0] ALU;
//instantiate control unit
CU control (IE, WE, WA, RAE, RAA, RBE, RBA, ALU, SH, OE, ~start, clk, ~restart, nEqZero, LSB);
//instantiate datapath
DP datapath (nEqZero, LSB, count, n, clk, IE, WE, WA, RAE, RAA, RBE, RBA, ALU, SH, OE);
assign done = OE;
endmodule
module CU(IE, WE, WA, RAE, RAA, RBE, RBA, ALU, SH, OE, start, clk, restart, nEqZero, LSB);
input start, clk, restart;
output IE, WE, RAE, RBE, OE;
output [1:0] WA, RAA, RBA, SH;
output [2:0] ALU;
input wire nEqZero;
input wire LSB;
reg [2:0] state;
reg [2:0] nextstate;
parameter S0 = 3'b000;
parameter S1 = 3'b001;
parameter S2 = 3'b010;
parameter S3 = 3'b011;
parameter S4 = 3'b100;
initial
state = S0;
// State register
always @ (posedge clk)
begin
state <= nextstate;
end
// NS logic
always @ (*)
case(state)
S0:if(start) nextstate = S1;//at s0, if start is true, go to s1
else nextstate = S0;//otherwise stay at s0
S1:if(~nEqZero && LSB) nextstate = S2;//if N ~= 0 and LSB = 1, count++
S1:if(~nEqZero && ~LSB) nextstate = S3;//if N ~= 0 and LSB=0, n>>
S1:if(nEqZero) nextstate = S4;//if N = 0, go to output
S2:nextstate = S3;//after count++,n>>
S3:if(nEqZero) nextstate = S4;//after N>>, if n=0, output
S3:if(~nEqZero && LSB) nextstate = S2;//otherwise, back to S2 and check for LSB
S3:if(~nEqZero && ~LSB) nextstate = S3;
S4:if(restart) nextstate = S0;//at s4, if restart is true, back to s0
else nextstate = S4;//otherwise no change
default: nextstate = S0;//initial state is s0
endcase
// output logic
assign IE = state==S1;
assign WE = (state == S0) || (state == S1)||(state == S2)||(state==S3);
assign WA[1] = 0;
assign WA[0] = (state == S1)||(state == S3);
assign RAE = (state == S0) || (state ==S2) || (state == S3)||(state == S4);
assign RAA[1] = 0;
assign RAA[0] = state == S3;
assign RBE = state == S0;
assign RBA[1] = 0;
assign RBA[0] = 0;
assign ALU[2] = state== S0|| state==S2;
assign ALU[1] = state == S2;
assign ALU[0] = state == S0;
assign SH[1] = state == S3;
assign SH[0] = 0;
assign OE = state == S4;
endmodule
module DP(nEQZero, LSB, count, nIn, clk, IE, WE, WA, RAE, RAA, RBE, RBA, ALU, SH, OE);
input clk, IE, WE, RAE, RBE, OE;
input [1:0] WA, RAA, RBA, SH;
input [2:0] ALU;
input [7:0] nIn;
output nEQZero;
output LSB;
output wire [7:0] count;
reg [7:0] rfIn;
wire [7:0] RFa, RFb, aluOut, shOut, n;
initial
rfIn = 0;
always @ (*)
rfIn = n;
mux8 muxs (n, shOut, nIn, IE);
Regfile RF (clk, RAA, RFa, RBA, RFb, WE, WA, rfIn, RAE, RBE);
alu theALU (aluOut, RFa, RFb, ALU);
shifter SHIFT (shOut, aluOut, SH);
buff buffer1 (count, shOut, OE);
assign nEQZero = n == 0; //note: checks the false condition
assign LSB = n[0] == 1; //note: checks the false condition
endmodule
// ALU
module alu (out,a,b,sel);
input [7:0] a,b;
input [2:0] sel;
output [7:0] out;
reg [7:0] out;
always @ (*)
begin
case(sel)
3'b000: out=a;
3'b001: out=a&b;
3'b010: out=a|b;
3'b011: out=!a;
3'b100: out=a+b;
3'b101: out=a-b;
3'b110: out=a+1;
3'b111: out=a-1;
endcase
end
endmodule
// final buffer
module buff(output reg [7:0] result, input[7:0] a, input buf1);
always @(*)
if(buf1 == 1)
result = a;
else
result = 8'bzzzz_zzzz;
endmodule
// 2-to-1 mux (sel = 0 -> choose a)
module mux8(result, a, b, sel);
output reg[7:0] result;
input[7:0] a;
input[7:0] b;
input sel;
always @(*)
if(sel == 0)
result = a;
else
result = b;
endmodule
// Regfile for GDP
module Regfile(
input clk,
input [1:0] RAA, // Port A Read address
output [7:0] ReadA, // Port A
input [1:0] RBA, // Port B Read address
output [7:0] ReadB, // Port B
input WE, // Write enable
input [1:0] WA, // Write port register address
input [7:0] INPUT_D, // Write data port
input RAE, // Port A decoder enable
input RBE // Port B decoder enable
);
// width depth
reg [7:0] REG_F [0:3];
// Write only when WE is asserted
always @(posedge clk)
if (WE == 1) REG_F[WA] <= INPUT_D;
//reading to Port A and B, combinational
assign ReadA = (RAE)? REG_F [RAA]:0;
assign ReadB = (RBE)? REG_F [RBA]:0;
endmodule
// Shifter
module shifter (out,a,sh);
input [7:0] a;
input [1:0] sh;
output reg [7:0] out;
always @ (*)
begin
case(sh)
3'b00: out=a;
3'b01: out=a << 1;
3'b10: out=a >> 1;
3'b11: out={a[6],a[5],a[4],a[3],a[2],a[1],a[0], a[7]} ;
endcase
end
endmodule
测试台文件:
module testb1;
parameter vectlength = 4;
wire displayRes;
wire [7:0] count;
reg [7:0] nIn;
reg [3:0] count_exp;
reg [11:0] vect[3:0];
reg start, restart, clk;
integer i;
initial
begin
i = 0;
$readmemb("Testvector.txt", vect);
start = 1;
restart = 1;
clk = 0;
// Clock generator
forever
#2 clk = ~clk;
end
//start the algorithm
always @ (posedge clk)
begin
#1;{nIn,count_exp}=vect[i];//parse the testvector to input A and expected result count_exp
end
always @ (negedge clk)
begin
for(i = 0; i < vectlength; i = i + 1)
begin
start = 0;
#40 restart = 1;
// Waiting for the work to finish, DispRes (Done)=1
while(displayRes !=1 && nIn[0]==1)
#5 begin end
$write("Input: %2d, Result:%3d,Expected: %3d:",nIn,count,count_exp);
if(count == count_exp)
$display("Correct!");
else
$display("Incorrect!");
restart = 0;
start = 1;
end
$stop;
end
//Initialize GDP
GDP main ( count,
start,
restart,
clk,
nIn,
displayRes);
endmodule
11010101_0101
11000001_0011
00000000_0000
10101010_0100
11111111_1000
解决自述消息。
这些消息是警告,而不是错误。
如果您了解它们,并且喜欢代码本身的行为,那么您就很好。
第一个警告是说代码违反了定义与 readmemb 关联的内存变量的默认样式。
这与方向有关。
你这样定义变量:
reg [vectwidth-1:0] vect[vectlength-1:0];
这样定义它,警告消失了:
reg [vectwidth-1:0] vect[0:vectlength-1];
第二个警告与向量的数量有关。
您在文本文件中有 5 行数据,以及一个包含 4 个位置的数组以将它们放入您的内存变量中。
parameter vectlength = 4;
将此更改为 5,警告消失。