我从一周以来一直在研究这个代码,并且存在一个我无法解决的问题。基本上我正在制作2种数据模式,一种是T_DATA,另一种是RX_Data。我正在比较两种模式,并在以total_error的形式进行比较后得到结果。
这是代码
`timescale 1ns / 1ps
module BER
(
clk,
rstn,
T_Data,
RX_Data,
enable,
total_error
);
input clk;
input rstn;
input [15:0] T_Data;
input [15:0] RX_Data;
input enable;
output [15:0] total_error;
reg [4:0] i;
reg [15:0] subtotal, next_subtotal;
assign total_error = subtotal;
always @ (posedge clk) begin: comb
next_subtotal = 0;
for (i = 0; i < 16; i = i +1)
begin
if (T_Data[i] != RX_Data[i])
begin
next_subtotal = next_subtotal + 1;
end
end
end
always @ (posedge clk) begin: dff
if (rstn == 1'b0) begin
subtotal <= 16'b0000000000000000;
end else
begin
subtotal <= next_subtotal;
end
end
endmodule
以上是模块ber的代码,在下一个模块中,我制作了基本上控制传输和接收信号的状态机。上述模块BER已使用StateMachine_BER模块进行实例化。请参阅以下代码
`timescale 1ns / 1ps
module StateMachine_BER
(
clk,
resetn, //negetive edge reset
T_Data [15:0],
T_Valid,
T_Ready,
RX_Data [15:0],
RX_Active,
RX_Valid,
total_error
);
//-----------------------//
input clk;
input resetn;
//-----------------------//
//declaring input and output for transferring signals
input [15:0] T_Data;
input T_Valid;
output T_Ready;
//declaring inputs and outputs for receiving signals
input [15:0] RX_Data;
input RX_Active;
input RX_Valid;
//-----------------------//
output [15:0] total_error;
//-----------------------//
//declaring registers to use them for procedural assignments
//-----------------------//
reg [6:0] sel;
reg execute_in;
reg T_Ready;
//-----------------------//
//instantiating ber module here
BER uut
(
.clk(clk),
.rstn(resetn),
.T_Data(T_Data),
.RX_Data(RX_Data),
.enable(execute_in),
.total_error(total_error)
);
//-----------------------//
//making state machine here
always @ (posedge clk or negedge resetn)
begin
if (resetn == 1'b0) //idle state
begin
sel <= 7'b0000000; //state 0
end
else if (T_Valid == 7'b0000001)
begin
sel <= 7'b0000001; //state 1
end
else if (sel == 7'b0000001)
begin
sel <= 7'b0000010; //state 2
end
else if (RX_Active == 7'b0000001)
begin
sel <= 7'b0000011; //state 3
end
else if (T_Valid == 7'b0000001 && RX_Valid == 7'b0000001)
begin
sel <= 7'b0000100; //state 4
end
else if (sel == 7'b0000100)
begin
sel <= 7'b0000101; //state 5
end
else if (T_Valid == 7'b0000000 && RX_Valid == 7'b0000000)
begin
sel <= 7'b0000100; //goes back to state 4
end
end
//making outputs for state machine
always @ (posedge clk)
begin
case(sel)
7'b0000000 :
execute_in = 1'b0; //state 0
7'b0000001 :
T_Ready = 1'b1; //state 1
7'b0000010 :
T_Ready = 1'b0; //state 2
7'b0000011 :
execute_in = 1'b1; //state 3
7'b0000100 :
T_Ready = 1'b1; //state 4
7'b0000101 :
T_Ready = 1'b0; //state 5
endcase
end
endmodule
以上是上述模块的测试平台。
`timescale 1ns / 1ps
module TB_BER();
//inputs
reg clk;
reg resetn;
reg execute_in;
//-----------------------//
//inputs for trasnferring signals
reg [15:0] T_Data;
reg T_Valid;
//-----------------------//
//inputs for receiving signals
reg [15:0] RX_Data;
reg RX_Active;
reg RX_Valid;
//-----------------------//
//outputs
wire [15:0] total_error;
wire T_Ready;
//-----------------------//
//instantiate the unit under test (UUT)
StateMachine_BER uut_BER
(
.clk(clk),
.resetn(resetn), //negetive edge reset
.T_Data(T_Data),
.T_Valid(T_Valid),
.T_Ready(T_Ready),
.RX_Data(RX_Data),
.RX_Active(RX_Active),
.RX_Valid(RX_Valid),
.total_error(total_error)
);
//-----------------------//
initial begin
clk = 1'b0;
resetn = 1'b0;
#50
resetn = 1'b1;
forever #10 clk = ~clk;
end
//-----------------------//
initial begin
#100
execute_in = 0;
#100
execute_in = 1;
//-----------------------//
#100
T_Valid = 1'b0;
RX_Active = 1'b0;
#100
RX_Valid = 1'b0;
//-----------------------//
// for T_Data: 0 and RX_Data: 0
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[0] = 1'b1; //data 0 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[0] = 1'b1; //data 0 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 1 and RX_Data: 1
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[1] = 1'b1; //data 1 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[1] = 1'b1; //data 1 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 2 and RX_Data: 2
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[2] = 1'b1; //data 2 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[2] = 1'b1; //data 2 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 3 and RX_Data: 3
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[3] = 1'b1; //data 3 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[3] = 1'b1; //data 3 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 4 and RX_Data: 4
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[4] = 1'b1; //data 4 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[4] = 1'b1; //data 4 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 5 and RX_Data: 5
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[5] = 1'b1; //data 5 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[5] = 1'b1; //data 5 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 6 and RX_Data: 6
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[6] = 1'b1; //data 6 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[6] = 1'b1; //data 6 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 7 and RX_Data: 7
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[7] = 1'b1; //data 7 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[7] = 1'b1; //data 7 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 8 and RX_Data: 8
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[8] = 1'b0; //data 8 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[8] = 1'b1; //data 8 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 9 and RX_Data: 9
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[9] = 1'b1; //data 9 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[9] = 1'b0; //data 9 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 10 and RX_Data: 10
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[10] = 1'b0; //data 10 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[10] = 1'b1; //data 10 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 11 and RX_Data: 11
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[11] = 1'b1; //data 11 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[11] = 1'b0; //data 11 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 12 and RX_Data: 12
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[12] = 1'b1; //data 12 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[12] = 1'b0; //data 12 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 13 and RX_Data: 13
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[13] = 1'b0; //data 13 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[13] = 1'b1; //data 13 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 14 and RX_Data: 14
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[14] = 1'b0; //data 14 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[14] = 1'b1; //data 14 //make it 0 for getting an error
#50
T_Valid = 1'b0;
//-----------------------//
// for T_Data: 15 and RX_Data: 15
#100
RX_Active = 1'b1;
T_Valid = 1'b1;
T_Data[15] = 1'b1; //data 15 //make it 0 for getting an error
RX_Valid = 1'b1;
RX_Data[15] = 1'b0; //data 15 //make it 0 for getting an error
#50
T_Valid = 1'b0;
end
endmodule
我使用的是VIVADO 2014.3软件。 运行bhavioral仿真后,它从0 ns开始,我保持运行50 ns。在此期间,发生数据传输,T_Data和RX_Data是16位数据。因此传输发生在0到15之间。我期待每个数据位都有一个值,但我没看到。在16位数据传输完成后,我只看到T_Data和RX_Data的最终值。在整个传输期间,两个数据都未定义为红色,值为X.但是在16位之后,当过程完成时,我可以看到最终的数据值。 奇怪的是在数据传输期间,即使它们未定义但我可以看到total_error中的值发生变化,这意味着这些未定义数据中存在一些值。我真的不明白如何解决这个问题。需要帮助。
请帮助我,我是verilog的新手,我还没有能够自己解决这个问题。
答案 0 :(得分:2)
您在模拟过程中看到红色X的原因是您从未在模拟开始时初始化T_Data
或RX_Data
的值。当这些声明为reg [15:0]
时,它们将以16'bXXXX
的值开头(即,所有位1'bx
都不关心)。 Verilog中的许多数据类型都处于该状态,以便在开始时说明系统的未知状态。您需要在模拟开始时将所有输入设置为某个默认值(可能为0),以便将它们添加到刺激初始块的开头:
//-----------------------//
initial begin
// Set all inputs to 0
T_data = 16'b0;
RX_data = 16'b0;
T_Valid = 1'b0;
RX_Valid = 1'b0;
RX_Active = 1'b0;
#100
execute_in = 0;
...
这应该有助于消除您的错误。但是,由于您是Verilog的新手,您还有一些其他想要解决的错误:
你的组合逻辑是在时钟触发的,当它们应该在任何时候触发任何&#34;输入&#34;信号发生变化,因此使用阻止分配=
的代码中的任何内容始终应为always @(*)
而不是always @(posedge clk)
,例如确定T_Ready
和next_subtotal
的阻止。 subtotal
和sel
块正确使用always @(posedge clk)
。
对于确定T_ready
的组合逻辑,未确定T_ready
的所有值的sel
值。例如,T_ready
应该是sel
是7&#39; d3?您需要确保为所有输入值定义了由组合逻辑确定的任何值。
由于并非所有的触发器都是异步复位的,因此您需要确保在复位开始声明时运行时钟。初始重置和计时的初始块不会这样做。