简体   繁体   中英

No Output Data Values in Simulation (Gate Level Modelling) - Verilog

I have written the part of the following code using gate level modelling as follows:-

`timescale 1ns / 1ps

module flip_flop (d,clk,q,q_bar);
input [36:0] d;
input clk;
output [36:0] q;
output [36:0] q_bar;
wire [36:0] dbar,x,y;
not n3 [36:0] (dbar,d);
nand n4 [36:0] (x,clk,d);
nand n5 [36:0] (y,clk,dbar);
nand n1 [36:0] (q,q_bar,y);
nand n2 [36:0] (q_bar,q,x);
endmodule

module adder(A,B,S);
input [36:0] A;
input [36:0] B;
output [36:0] S;
assign S = A + B;
endmodule

module subtractor(A,B,S);
input [36:0] A;
input [36:0] B;
output [36:0] S;
assign S = A - B;
endmodule

module dec256sinc24b
(input mclk1, /* used to clk filter */
input reset, /* used to reset filter */
input mdata1, /* input data to be filtered */

output reg [15:0] DATA, /* filtered output*/
output reg data_en,
input [15:0] dec_rate
);

/* Data is read on negative clk edge */
//reg [36:0] ip_data1;
//reg [36:0] acc1;
//reg [36:0] acc2;
//reg [36:0] acc3;
//reg [36:0] acc3_d2;
//reg [36:0] diff1;
//reg [36:0] diff2;
//reg [36:0] diff3;
//reg [36:0] diff1_d;
//reg [36:0] diff2_d;

reg [36:0] MOUT;
wire [36:0] delta;
wire [36:0] CNN1;
wire [36:0] CN1;
wire [36:0] CNN2;
wire [36:0] CN2;
wire [36:0] DN0;
wire [36:0] DN1;
wire [36:0] CN3;
wire [36:0] DN3;
wire [36:0] CN4;
wire [36:0] DN5;
wire [36:0] CN5;

reg [15:0] word_count;

reg word_clk;
reg enable;

/*Perform the Sinc action*/
always @ (mdata1)
if(mdata1==0)
    MOUT <= 37'd0;
    /* change 0 to a -1 for twos complement */
else
    MOUT <= 37'd1;

/*Accumulator (Integrator)
Perform the accumulation (IIR) at the speed of the modulator.
Z = one sample delay MCLKOUT = modulators conversion bit rate */

//always @ (negedge mclk1, posedge reset)
//begin
//    if (reset)
//    begin
//    /* initialize acc registers on reset*/
//        acc1 <= 37'd0;
//        acc2 <= 37'd0;
//        acc3 <= 37'd0;
//    end
//    else
//    begin
//    /*perform accumulation process */
//        acc1 <= acc1 + ip_data1;
//        acc2 <= acc2 + acc1;
//        acc3 <= acc3 + acc2;
//    end
//end

/*decimation stage (MCLKOUT/WORD_CLK) */
always @ (negedge mclk1, posedge reset)
begin
    if (reset)
        word_count <= 16'd0;
    else
    begin
        if ( word_count == dec_rate - 1 )
            word_count <= 16'd0;
        else
            word_count <= word_count + 16'b1;
    end
end

always @ ( negedge mclk1, posedge reset )
begin
if ( reset )
    word_clk <= 1'b0;
else
begin
    if ( word_count == dec_rate/2 - 1 )
        word_clk <= 1'b1;
    else if ( word_count == dec_rate - 1 )
        word_clk <= 1'b0;
    end
end

/*Differentiator (including decimation stage)
Perform the differentiation stage (FIR) at a lower speed.
Z = one sample delay WORD_CLK = output word rate */

//always @ (negedge word_clk, posedge reset)
//begin
//    if(reset)
//    begin
//        acc3_d2 <= 37'd0;
//        diff1_d <= 37'd0;
//        diff2_d <= 37'd0;
//        diff1 <= 37'd0;
//        diff2 <= 37'd0;
//        diff3 <= 37'd0;
//    end
//    else
//    begin
//        diff1 <= acc3 - acc3_d2;
//        diff2 <= diff1 - diff1_d;
//        diff3 <= diff2 - diff2_d;
//        acc3_d2 <= acc3;
//        diff1_d <= diff1;
//        diff2_d <= diff2;
//    end
//end

flip_flop M1(.d(MOUT),.clk(mclk1),.q(delta));
adder M2(.A(CN1),.B(delta),.S(CNN1));
flip_flop M75(.d(CNN1),.clk(mclk1),.q(CN1));
adder M76(.A(CN2),.B(CN1),.S(CNN2));
flip_flop M77(.d(CNN2),.clk(mclk1),.q(CN2));
flip_flop M78(.d(CN2),.clk(word_clk),.q(DN0));
flip_flop M79(.d(DN0),.clk(word_clk),.q(DN1));
subtractor M80(.A(DN0),.B(DN1),.S(CN3));
flip_flop M81(.d(CN3),.clk(word_clk),.q(DN3));
subtractor M82(.A(CN3),.B(DN3),.S(CN4));
flip_flop M83(.d(CN4),.clk(word_clk),.q(DN5));
subtractor M84(.A(CN4),.B(DN5),.S(CN5));

/* Clock the Sinc output into an output register
WORD_CLK = output word rate */

always @ (negedge word_clk )
begin
    case ( dec_rate )
        16'd32:begin
            DATA <= (CN5[15:0] == 16'h8000) ? 16'hFFFF : {CN5[14:0], 1'b0};
        end
        16'd64:begin
            DATA <= (CN5[18:2] == 17'h10000) ? 16'hFFFF : CN5[17:2];
        end
        16'd128:begin
            DATA <= (CN5[21:5] == 17'h10000) ? 16'hFFFF : CN5[20:5];
        end
        16'd256:begin
            DATA <= (CN5[24:8] == 17'h10000) ? 16'hFFFF : CN5[23:8];
        end
        16'd512:begin
            DATA <= (CN5[27:11] == 17'h10000) ? 16'hFFFF : CN5[26:11];
        end
        16'd1024:begin
            DATA <= (CN5[30:14] == 17'h10000) ? 16'hFFFF : CN5[29:14];
        end
        16'd2048:begin
            DATA <= (CN5[33:17] == 17'h10000) ? 16'hFFFF : CN5[32:17];
        end
        16'd4096:begin
        DATA <= (CN5[36:20] == 17'h10000) ? 16'hFFFF : CN5[35:20];
        end
        default:begin
            DATA <= (CN5[24:8] == 17'h10000) ? 16'hFFFF : CN5[23:8];
        end
    endcase
end

/* Synchronize Data Output*/
always@ (negedge mclk1, posedge reset )
begin
    if ( reset )
    begin
        data_en <= 1'b0;
        enable <= 1'b1;
    end
    else
    begin
        if ( (word_count == dec_rate/2 - 1) && enable )
        begin
            data_en <= 1'b1;
            enable <= 1'b0;
        end
        else if ( (word_count == dec_rate - 1)  && ~enable )
        begin
            data_en <= 1'b0;
            enable <= 1'b1;
        end
        else
            data_en <= 1'b0;
    end
end

endmodule

Testbench

`timescale 1ns / 1ps

`define SIM_CYCLE 1_000_000*20

module sinc3_tb;

//Inputs
reg mclk1;
reg   reset;
reg       mdata1;
reg [15:0] dec_rate_0; //256
reg [15:0] dec_rate_1; //512
reg [15:0] dec_rate_2; //1024

//outputs
wire [15:0] DATA_0;
wire [15:0] DATA_1;
wire [15:0] DATA_2;
wire data_en_0;
wire data_en_1;
wire data_en_2;
    //debug
wire [36:0] CN5_0 = dec256sinc24b_inst_0.CN5;
wire [36:0] CN5_1 = dec256sinc24b_inst_1.CN5;
wire [36:0] CN5_2 = dec256sinc24b_inst_2.CN5;

// Instantiate the Unit Under Test (UUT)
dec256sinc24b dec256sinc24b_inst_0(
.mclk1(mclk1),
.reset(reset),
.dec_rate(dec_rate_0),
/*************************************/
.mdata1(mdata1),
.DATA(DATA_0),
.data_en(data_en_0)
);
dec256sinc24b dec256sinc24b_inst_1(
.mclk1(mclk1),
.reset(reset),
.dec_rate(dec_rate_1),
/*************************************/
.mdata1(mdata1),
.DATA(DATA_1),
.data_en(data_en_1)
);
dec256sinc24b dec256sinc24b_inst_2(
.mclk1(mclk1),
.reset(reset),
.dec_rate(dec_rate_2),
/*************************************/
.mdata1(mdata1),
.DATA(DATA_2),
.data_en(data_en_2)
);
/*************************************/
// mclk1 = 10MHz
always#(50)
begin
mclk1 <= ~mclk1;
end
/*************************************/

    // Case 6 and // Case 7
   
    reg mem[1:50000];
    integer i;
   
    initial begin
        for(i=1;i<=50000;i=i+1) begin
 @(posedge mclk1);
 mdata1 = mem[i];
 $display("a=%0b",mdata1);
        end
    end
   
    // Wrting the DATA values at the rising edge of data_en to a .csv file
   
    integer out_r0;
    integer out_r1;
    integer out_r2;
   
    initial begin
        out_r0 = $fopen("P:/data_0.csv");
        forever begin
        @(posedge data_en_0);
            $fdisplay(out_r0, "%0d",DATA_0);
        end
        $fclose(out_r0);
    end
   
    initial begin
        out_r1 = $fopen("P:/data_1.csv");
        forever begin
        @(posedge data_en_1);
            $fdisplay(out_r1, "%0d",DATA_1);
        end
        $fclose(out_r1);
    end
   
    initial begin
        out_r2 = $fopen("P:/data_2.csv");
        forever begin
        @(posedge data_en_2);
            $fdisplay(out_r2, "%0d",DATA_2);
        end
        $fclose(out_r2);
    end
   
    /*************************************/
   
initial begin
// Initialize Inputs
mclk1 = 1'b0;
reset = 1'b1;
mdata1 = 1'b0;
dec_rate_0 = 16'd256;
dec_rate_1 = 16'd512;
dec_rate_2 = 16'd1024;
// Case 6 and // Case 7
// Read .csv file into the mdata1 register
$readmemb("P:/mdata1_min2.csv",mem);

// Add stimulus here
#5 reset = 1'b0;
//#5 mdata1 = 1'b1;

#(`SIM_CYCLE) $finish;
end
endmodule

When I run the simulation there is no output data values (DATA[15:0]) and no output values for (CN5[36:0]). Before changing the code to gate level modelling (now commented out) the output data values were available in the simulation. Would appreciate any suggestions to resolve the issues. Thanks!

I think there are 2-4 related questions/answers wrapped up in your debug. I think its inappropriate to give detailed answers to all of them in one SO answer. Will try to point you in the right direction.

I put your code and testbench in EDA playground. The sim reaches the iteration limit of 5000 at t=0 thus stops at t=0. Don't know for certain what is causing this; a good guess is that this design is building a flip-flop out of gates and has a 0-delay infinite loop caused by feedback around combinational logic in the model. To get around this model finite propagation delay in the gate. Otherwise the output causes a change in the input which causes a change in the output..... forever.

If you need to model a ff out of gates, create another design-testbench combination and get the ff model working first as its own design. Model finite propagation delay for some of the gates. I would not model a ff out of gates in Verilog; Verilog natively models ffs at an RTL level very well.

One to quickly validate this is to replace the gate model of the flip flop with an RTL model and see if that part of the problem (stuck at t=0 because of infinite loop) goes away.

"How do I model propagation delay in a Verilog gate level model" is another question.

If you don't already know, it would help to understand Verilog simulation event scheduling semantics. This is a whole other area and the subject of another question. "How does a Verilog simulation work with respect to modeling time"

As a general approach to debugging, if a design has several pieces and nothing comes out, break it down into a much smaller number of pieces until something you understand is working then add back the rest. Version control (git,subversion etc) is helpful with this. Create commits which take the design apart, analyzing at each step. The commits can be reversed to get back to a particular place in the development in a manageable way. This would be another question "How do I debug a Verilog design that has several pieces when nothing comes out"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM