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.