1

I have been working on this code from more than week now and there is a problem which I have not been able to solve. Basically I am making 2 data patterns, one is T_DATA and the other is RX_Data. I am comparing both patterns and get a result after comparing in the form of total_error.

Here is the code

`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

Above is the code of module ber, in the next module, I made state machine that basically controls the transfer and receiving signals. The above module BER has been instantiated with StateMachine_BER module. Please see the code below

`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

Here is the test bench for above modules.

`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

I am using VIVADO 2014.3 software. After running bhavioral simulation, it starts from 0 ns, I keep it running for 50 ns. During this, the data transmission takes place, T_Data and RX_Data are 16 bit datas. So the transmisison takes place from 0 till 15. I am expecting every data bit to have a value, but that I dont see. I only see the final values of T_Data and RX_Data after the 16 bit data trasnmission is complete. Throughout the trasnmission, both the datas are undefined in red having value X. But after 16 bits, when the process is complete, I can see the final data values. Strange thing is during data trasnmission, even though they are undefined but I can see the value at total_error changing, which means that there is some value in those undefined datas. I really dont understand how to fix this issue. Need help.

Please help me with this, I am new to verilog, I have not been able to figure it out on my own yet.

1 Answer 1

2

The reason you are seeing the red X's during simulation is that you never initialize the value of T_Data or RX_Data at the start of simulation. As these are declared reg [15:0], they will begin with the value of 16'bXXXX (ie, all bits 1'bx for dont care). Many data types in Verilog being in that state to illustrate the unknown state of the system at the beginning of time. You'll need to have all your inputs set to some default value (probably 0) at the start of your simulation, so you can add them to the start of your stimulus initial block:

//-----------------------//       
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;
  ...

That should help clear up your error. However, as you are new to Verilog, there are a few other mistakes you want want to fix:

Your combinational logic are triggered at the clock, when they should be triggered any time any of the "input" signals change, so any always block in your code using blocking assignment = should be always @(*) instead of always @(posedge clk) such as the blocks determining T_Ready and next_subtotal. The subtotal and sel blocks use always @(posedge clk) correctly.

For your combinational logic determining T_ready, the value of T_ready is not determined for all values of sel. For example, what should T_ready be is sel is 7'd3? You need to be sure any values determined by combinational logic are defined for all values of the inputs.

As not all your flip-flops are reset asynchronously, you need to be sure to run the clock while reset is begin asserted. Your initial block for initial reset and clocking does not do this.

Sign up to request clarification or add additional context in comments.

2 Comments

I really appreciate your help. The last lines, you mentioned as not all my flip flops are reset asynchronously, can you give me reference as per to which block you see such bahaviour? which initial block for initial reset? Once again, thankyou very much
@Sultan The block labelled dff in the BER module has a synchronous reset as resetn is not on the sensitivity list. You need to add negedge resetn like you have in your state machine module if you want it to be an asynchronous reset. The initial block I am referring to is the first one in your testbench that does the clocking (starts with clk = 1'b0;); if you want to reset synchronously, you need to run the clock while asserting resetn (typically by having the reset and clock in different initial blocks).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.