sinc3 滤波器仿真中无输出数据
No output data in sinc3 filter simulation
我在 verilog 中有以下用于 sinc3 数字滤波器的代码:-
`timescale 1ns / 1ps
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 [15:0] word_count;
reg word_clk;
reg enable;
/*Perform the Sinc action*/
always @ (mdata1)
if(mdata1==0)
ip_data1 <= 37'd0;
/* change 0 to a -1 for twos complement */
else
ip_data1 <= 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
/* 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 <= (diff3[15:0] == 16'h8000) ? 16'hFFFF : {diff3[14:0], 1'b0};
end
16'd64:begin
DATA <= (diff3[18:2] == 17'h10000) ? 16'hFFFF : diff3[17:2];
end
16'd128:begin
DATA <= (diff3[21:5] == 17'h10000) ? 16'hFFFF : diff3[20:5];
end
16'd256:begin
DATA <= (diff3[24:8] == 17'h10000) ? 16'hFFFF : diff3[23:8];
end
16'd512:begin
DATA <= (diff3[27:11] == 17'h10000) ? 16'hFFFF : diff3[26:11];
end
16'd1024:begin
DATA <= (diff3[30:14] == 17'h10000) ? 16'hFFFF : diff3[29:14];
end
16'd2048:begin
DATA <= (diff3[33:17] == 17'h10000) ? 16'hFFFF : diff3[32:17];
end
16'd4096:begin
DATA <= (diff3[36:20] == 17'h10000) ? 16'hFFFF : diff3[35:20];
end
default:begin
DATA <= (diff3[24:8] == 17'h10000) ? 16'hFFFF : diff3[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
我已经为此编写了一个测试台,输入如下:mclk1 = 10MHz,mdata1 = 5MHz 和 dec_rate = 64
`timescale 1ns / 1ps
`define SIM_CYCLE 8192
module sinc3_tb;
//Inputs
reg mclk1;
reg reset;
reg mdata1;
reg [15:0] dec_rate;
//outputs
wire [15:0] DATA;
wire data_en;
//debug
wire [36:0] diff3 = dec256sinc24b_inst.diff3;
// Instantiate the Unit Under Test (UUT)
dec256sinc24b dec256sinc24b_inst(
.mclk1(mclk1),
.reset(reset),
.dec_rate(dec_rate),
/*************************************/
.mdata1(mdata1),
.DATA(DATA),
.data_en(data_en)
);
/*************************************/
// mclk1 = 10MHz
always#(50)
begin
mclk1 <= ~mclk1;
end
// mdata1 = 5MHz
always@(posedge mclk1)
begin
mdata1 <= ~mdata1;
end
initial begin
// Initialize Inputs
mclk1 = 1'b0;
reset = 1'b0;
mdata1 = 1'b0;
dec_rate = 16'd64;
// Add stimulus here
#5 reset = 1'b1;
#(`SIM_CYCLE) $finish;
end
endmodule
当我 运行 模拟时,我没有得到 DATA
和 diff3
的任何输出,如下面的模拟所示。有什么建议可以解决这个问题吗?
另外为什么 dec_rate = 40?因为,我把它设置为 64?
问题在于您如何从测试台驱动重置。您的设计使用高电平有效复位,但您的测试平台在大多数模拟中将复位设置为 1,从而使设计始终处于复位状态。
您需要在测试台中反转 reset
信号的极性。在时间 0 置位复位,然后在时间 5 释放复位:
initial begin
// Initialize Inputs
mclk1 = 1'b0;
reset = 1'b1;
mdata1 = 1'b0;
dec_rate = 16'd64;
// Add stimulus here
#5 reset = 1'b0;
#(`SIM_CYCLE) $finish;
end
另外,运行你的模拟时间要多一些,看看DATA
从0变化。例如:
`define SIM_CYCLE 8192*10
如果你想运行 1ms:
`define SIM_CYCLE 1_000_000
您的波形显示设置为十六进制格式。 40
是 0x40
,与十进制的 64 相同。
DATA 卡在 0,因为它被 word_clk 重新计时,word_clk 卡在 0。
信号 word_clk 停留在 0,因为重置为高并且它保持 word_clk 为 0。
你还没有运行它有足够的时间看什么数据出来。
尝试运行 8192*8 个周期而不是 8192 个周期。
整个设计永远处于重置状态。
顺便说一下,在您的 RTL 中使用 always 块生成时钟是一种不好的做法。它可能在模拟中工作,而不是在 synthesis/build 流程中工作。
最佳做法是使用 PLL 或 MMCM 或其他供应商设备来生成时钟。
像这样以毫秒为单位表示时间:
localparam NUM_MS = 2;
// other code
#(NUM_MS*1ms);
我在 verilog 中有以下用于 sinc3 数字滤波器的代码:-
`timescale 1ns / 1ps
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 [15:0] word_count;
reg word_clk;
reg enable;
/*Perform the Sinc action*/
always @ (mdata1)
if(mdata1==0)
ip_data1 <= 37'd0;
/* change 0 to a -1 for twos complement */
else
ip_data1 <= 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
/* 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 <= (diff3[15:0] == 16'h8000) ? 16'hFFFF : {diff3[14:0], 1'b0};
end
16'd64:begin
DATA <= (diff3[18:2] == 17'h10000) ? 16'hFFFF : diff3[17:2];
end
16'd128:begin
DATA <= (diff3[21:5] == 17'h10000) ? 16'hFFFF : diff3[20:5];
end
16'd256:begin
DATA <= (diff3[24:8] == 17'h10000) ? 16'hFFFF : diff3[23:8];
end
16'd512:begin
DATA <= (diff3[27:11] == 17'h10000) ? 16'hFFFF : diff3[26:11];
end
16'd1024:begin
DATA <= (diff3[30:14] == 17'h10000) ? 16'hFFFF : diff3[29:14];
end
16'd2048:begin
DATA <= (diff3[33:17] == 17'h10000) ? 16'hFFFF : diff3[32:17];
end
16'd4096:begin
DATA <= (diff3[36:20] == 17'h10000) ? 16'hFFFF : diff3[35:20];
end
default:begin
DATA <= (diff3[24:8] == 17'h10000) ? 16'hFFFF : diff3[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
我已经为此编写了一个测试台,输入如下:mclk1 = 10MHz,mdata1 = 5MHz 和 dec_rate = 64
`timescale 1ns / 1ps
`define SIM_CYCLE 8192
module sinc3_tb;
//Inputs
reg mclk1;
reg reset;
reg mdata1;
reg [15:0] dec_rate;
//outputs
wire [15:0] DATA;
wire data_en;
//debug
wire [36:0] diff3 = dec256sinc24b_inst.diff3;
// Instantiate the Unit Under Test (UUT)
dec256sinc24b dec256sinc24b_inst(
.mclk1(mclk1),
.reset(reset),
.dec_rate(dec_rate),
/*************************************/
.mdata1(mdata1),
.DATA(DATA),
.data_en(data_en)
);
/*************************************/
// mclk1 = 10MHz
always#(50)
begin
mclk1 <= ~mclk1;
end
// mdata1 = 5MHz
always@(posedge mclk1)
begin
mdata1 <= ~mdata1;
end
initial begin
// Initialize Inputs
mclk1 = 1'b0;
reset = 1'b0;
mdata1 = 1'b0;
dec_rate = 16'd64;
// Add stimulus here
#5 reset = 1'b1;
#(`SIM_CYCLE) $finish;
end
endmodule
当我 运行 模拟时,我没有得到 DATA
和 diff3
的任何输出,如下面的模拟所示。有什么建议可以解决这个问题吗?
另外为什么 dec_rate = 40?因为,我把它设置为 64?
问题在于您如何从测试台驱动重置。您的设计使用高电平有效复位,但您的测试平台在大多数模拟中将复位设置为 1,从而使设计始终处于复位状态。
您需要在测试台中反转 reset
信号的极性。在时间 0 置位复位,然后在时间 5 释放复位:
initial begin
// Initialize Inputs
mclk1 = 1'b0;
reset = 1'b1;
mdata1 = 1'b0;
dec_rate = 16'd64;
// Add stimulus here
#5 reset = 1'b0;
#(`SIM_CYCLE) $finish;
end
另外,运行你的模拟时间要多一些,看看DATA
从0变化。例如:
`define SIM_CYCLE 8192*10
如果你想运行 1ms:
`define SIM_CYCLE 1_000_000
您的波形显示设置为十六进制格式。 40
是 0x40
,与十进制的 64 相同。
DATA 卡在 0,因为它被 word_clk 重新计时,word_clk 卡在 0。
信号 word_clk 停留在 0,因为重置为高并且它保持 word_clk 为 0。
你还没有运行它有足够的时间看什么数据出来。
尝试运行 8192*8 个周期而不是 8192 个周期。
整个设计永远处于重置状态。
顺便说一下,在您的 RTL 中使用 always 块生成时钟是一种不好的做法。它可能在模拟中工作,而不是在 synthesis/build 流程中工作。
最佳做法是使用 PLL 或 MMCM 或其他供应商设备来生成时钟。
像这样以毫秒为单位表示时间:
localparam NUM_MS = 2;
// other code
#(NUM_MS*1ms);