Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

$urandom for error insertion in Systemverilog

Status
Not open for further replies.

rrucha

Member level 3
Joined
Jul 17, 2019
Messages
66
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
675
Hi,

I am making use of $urandom to insert an error in random bits of data. To begin with, I am inserting a 1 bit error, where the position bit is randomly chosen and flipped. I am new to SystemVerilog and I noticed that it only executes once. I give data to the module through my testbench, and I want it to iteratively add errors to the same data at different bit positions. I made use of repeat(50), but it does the final work only on the last data.

Code:
module error_inject (data_in, parity_in, data_out, parity_out);

    parameter DATA_WIDTH = 13; 
    parameter ERROR_WIDTH = $clog2(DATA_WIDTH);

    input [7:0] data_in;
    input [4:0] parity_in;
    output reg [7:0] data_out;
    output reg [4:0] parity_out;

    reg [ERROR_WIDTH-1:0] BIT_to_flip;
    reg [DATA_WIDTH-1:0] int_data;

    always @(*)
    repeat(50)
    begin 
    int_data = {data_in, parity_in};

    idx_to_flip = $urandom_range(0, DATA_WIDTH-1);
    $display("Flipping data bit %d", BIT_to_flip);

    int_data[BIT_to_flip] = !int_data[BIT_to_flip];
    $display("bad data = %b",int_data);

    data_out = int_data[12:5];

    parity_out = int_data[4:0];

    end 
endmodule
 

Only the last one because Verilog/Systemverilog loops are unrolled at compile time. They represent multiple instances of whatever is in the loop and not sequential operations.

You also have a typo as there isn't any signal called idx_to_flip.

I also would not use an always @(*) for doing this, I'd put this in a task or create a test FSM to run the test sequence if I needed it to be synthesizable.

I wouldn't write software style assignments like you have in this code your relying on Systemverilog's event scheduling working exactly the way software programs run code. I would generate the errors by doing something straightforward and simple like this:

Code Verilog - [expand]
1
2
BIT_to_flip = 1'b1 << $urandom_range(0, DATA_WIDTH-1);   // set an error bit in a random location
data_out = int_data ^ BIT_to_flip;   // invert the selected bit

 

Hi Ads-ee,

Thank you for your reply. I made a few changes in the code. I initially had a different module for error injection. Now I made it a part of the top test bench and directly connected to other modules that send and receive data from this module. I also just made it a part of an initial block now. The error gets placed in the data now for as many number of times as is specified in the repeat statement. But it wont receive any inputs anymore. So all the other signals are high impedance.
 

Can't help you if I don't see the code.
 

Hi,

This is the code with a seperate module. Here, every module is able to interact with each other and send data. The for loop in the error module produces different data with different error bits but the final print statment only executes for the last data. I want it to execute for every iteration.

Code:
module test_bench ();

    parameter DATA_WIDTH = 13; 
    parameter IDX_WIDTH = $clog2(DATA_WIDTH);

    wire [4:0] parity_out_enc;

    wire [7:0] corr_data_out;
    wire [4:0] syndrome;
    wire uncorr, corr;
    wire flag;
    wire [4:0]      vxh;
    wire [4:0] parity_out;
    wire [7:0] data_dec;
    wire [4:0] parity_dec;
    wire [IDX_WIDTH-1:0] idx_to_flip;

    reg [7:0] data_enc;
    
    initial 
    begin 

        $display ("time\t parity_out_enc data_enc  idx_flip data_dec   parity_dec corr_data_out syndrome uncorr  corr vxh    flag  parity_out");  
        $monitor ("%g\t %b          %b  %d       %b   %b      %b      %b    %b        %b   %b  %b     %b", $time, parity_out_enc, data_enc, idx_to_flip, data_dec, parity_dec, corr_data_out, syndrome, uncorr, corr, vxh,                     flag, parity_out);

        data_enc = 8'b10101010;

    end 

    secded_8_enc encoder (parity_out_enc, data_enc);
    error_inject error_module (data_enc, parity_out_enc, data_dec, parity_dec, idx_to_flip);
    secded_8_dec decoder (corr_data_out, syndrome, uncorr, corr, vxh, flag, parity_out, data_dec, parity_dec);

endmodule 

module error_inject (data_in, parity_in, data_out, parity_out, idx_to_flip);

    parameter DATA_WIDTH = 13; 
    parameter IDX_WIDTH = $clog2(DATA_WIDTH);

    input [7:0] data_in;
    input [4:0] parity_in;
    output reg [7:0] data_out;
    output reg [4:0] parity_out;
    int i;

    output reg [IDX_WIDTH-1:0] idx_to_flip;
    reg [DATA_WIDTH-1:0] int_data;

    always@(*)
    begin 
    for (i=0;i<10;i=i+1)
    //repeat(10)
    begin 
    int_data = {data_in, parity_in};

    idx_to_flip = $urandom_range(DATA_WIDTH-1);
    $display("Flipping data bit %d", idx_to_flip);

    int_data[idx_to_flip] = !int_data[idx_to_flip];
    $display("bad data = %b",int_data);

     data_out = int_data[12:5];

     parity_out = int_data[4:0];
    end 
    end 
endmodule
 

I'm not sure what you are expecting, but the for loop is going to cycle through all 10 iterations in 0 ns.

The entire structure of this testbench doesn't make a lot of sense to me and is more complicated than the one I wrote years ago for checking a hsaio (72,64) code.

I would structure it with a clocked always block generating data and generating an error mask. The data generator would feed the encoder and the output of the encoder is XOR'd with the error mask and fed to the decoder. The output of the decoder is then checked against the generated data. I randomize the input data and the error mask along with keeping track of the number of errors and the position of the errors.

Burying the error generation as a separate module with an always block and a for loop is not a good approach and it doesn't work due to the lack of any time control statements in the loop.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top