v04-IIR based on IP core

This commit is contained in:
thfu 2024-11-09 17:13:18 +08:00
parent e757bd72c6
commit 8fa46ded3a
9 changed files with 938 additions and 788 deletions

417
rtl/DW_iir_dc.v Executable file
View File

@ -0,0 +1,417 @@
////////////////////////////////////////////////////////////////////////////////
//
// This confidential and proprietary software may be used only
// as authorized by a licensing agreement from Synopsys Inc.
// In the event of publication, the following notice is applicable:
//
// (C) COPYRIGHT 1995 - 2018 SYNOPSYS INC.
// ALL RIGHTS RESERVED
//
// The entire notice above must be reproduced on all authorized
// copies.
//
// AUTHOR: KB May 20, 1995
//
// VERSION: Verilog Simulation Model for DW_iir_dc
//
// DesignWare_version: 10b10551
// DesignWare_release: O-2018.06-DWBB_201806.1
//
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
//
// ABSTRACT: Verilog simulation model for IIR filter with dynamic coefficients
//
// MODIFIED:
// Doug Lee 06/02/2008
// Fix for STAR#9000245949
// data_out and saturation results were wrong
// compared to synthetic and VHDL simulation
// models in a specific negative number
// boundary case. Re-wrote rounding/saturation
// function to resemble VHDL simulation model
// approach.
//
// Zhijun (Jerry) Huang 02/12/2004
// Changed interface names
// Added parameter legality check
// Added asynchronous reset signal rst_n
// Added optional output register controlled by parameter out_reg
// Added X-processing
// Fixed verilog analysis warning about zero multiconcat multiplier
// Fixed verilog analysis error about negative array index
// Fixed logic errors with saturation and negative/positive handling
// Fixed logic errors with feedback_data when feedback_width > data_out_width
//
//-----------------------------------------------------------------------------------
module DW_iir_dc(clk,rst_n,init_n,enable,
A1_coef,A2_coef,B0_coef,B1_coef,B2_coef,
data_in,data_out,saturation);
parameter integer data_in_width = 8;
parameter integer data_out_width = 16;
parameter integer frac_data_out_width = 4;
parameter integer feedback_width = 12;
parameter integer max_coef_width = 8;
parameter integer frac_coef_width = 4;
parameter integer saturation_mode = 0;
parameter integer out_reg = 1;
input clk,rst_n,init_n,enable;
input [max_coef_width-1:0] A1_coef,A2_coef,B0_coef,B1_coef,B2_coef;
input [data_in_width-1:0] data_in;
output [data_out_width-1:0] data_out;
output saturation;
parameter integer psum_width = (feedback_width-frac_data_out_width > data_in_width)?
feedback_width+max_coef_width+3
: data_in_width+frac_data_out_width+max_coef_width+3;
// synopsys translate_off
function [feedback_width+data_out_width:0] rnd_sat;
input [psum_width-1:0] psum0;
reg signed [psum_width:0] psum0_shiftedby1;
reg signed [data_out_width-1:0] data_out_noreg;
reg signed [feedback_width-1:0] feedback_data;
reg signed [frac_coef_width:0] round_limit;
reg signed [frac_coef_width-1:0] psum0_frac_part;
reg signed [data_out_width-1:0] max_pos_output;
reg signed [data_out_width-1:0] max_neg_output;
reg signed [feedback_width-1:0] max_pos_feedback;
reg signed [feedback_width-1:0] max_neg_feedback;
reg signed [data_out_width-1:0] output_inc_data;
reg signed [feedback_width-1:0] feedback_inc_data;
reg output_to_big;
reg feedback_to_big;
reg saturation_internal;
integer i, j, k, l;
begin
for (i=0; i<data_out_width; i=i+1) begin
if (i == data_out_width-1)
max_pos_output[i] = 0;
else
max_pos_output[i] = 1;
end
for (j=0; j<data_out_width; j=j+1) begin
if (j == data_out_width-1)
max_neg_output[j] = 1;
else if (j == 0)
if (saturation_mode == 0)
max_neg_output[j] = 0;
else
max_neg_output[j] = 1;
else
max_neg_output[j] = 0;
end
for (k=0; k<feedback_width; k=k+1) begin
if (k == feedback_width-1)
max_pos_feedback[k] = 0;
else
max_pos_feedback[k] = 1;
end
for (l=0; l<feedback_width; l=l+1) begin
if (l == feedback_width-1)
max_neg_feedback[l] = 1;
else if (l == 0)
if (saturation_mode == 0)
max_neg_feedback[l] = 0;
else
max_neg_feedback[l] = 1;
else
max_neg_feedback[l] = 0;
end
// round_limit = -2^(frac_coef_width-1)
for (i=0; i<=frac_coef_width; i=i+1) begin
if (i == frac_coef_width)
round_limit[i] = 1;
else if (i == frac_coef_width-1)
round_limit[i] = 1;
else
round_limit[i] = 0;
end
if (frac_coef_width > 0) begin
psum0_shiftedby1 = psum0 << 1;
// Break out the frac_coef portion of psum0
for (i=0; i<frac_coef_width; i=i+1) begin
psum0_frac_part[i] = psum0[i];
end
if ($signed(psum0_shiftedby1[psum_width:frac_coef_width]) >= $signed({max_pos_output, 1'b1})) begin
data_out_noreg = max_pos_output;
output_to_big = 1;
end else begin
if ($signed(psum0_shiftedby1[psum_width:frac_coef_width+1]) < $signed(max_neg_output)) begin
data_out_noreg = max_neg_output;
output_to_big = 1;
end else begin
if (psum0_shiftedby1[frac_coef_width] &&
(!psum0_shiftedby1[psum_width] || (($signed(psum0_frac_part)) > $signed(round_limit)))) begin
output_inc_data = psum0[data_out_width+frac_coef_width-1:frac_coef_width] + 1;
data_out_noreg = output_inc_data;
output_to_big = 0;
end else begin
data_out_noreg = psum0[data_out_width+frac_coef_width-1:frac_coef_width];
output_to_big = 0;
end
end
end
if ($signed(psum0_shiftedby1[psum_width:frac_coef_width]) >= $signed({max_pos_feedback, 1'b1})) begin
feedback_data = max_pos_feedback;
feedback_to_big = 1;
end else begin
if ($signed(psum0_shiftedby1[psum_width:frac_coef_width+1]) < $signed(max_neg_feedback)) begin
feedback_data = max_neg_feedback;
feedback_to_big = 1;
end else begin
if (psum0_shiftedby1[frac_coef_width] &&
(!psum0_shiftedby1[psum_width] || (($signed(psum0_frac_part)) > $signed(round_limit)))) begin
feedback_inc_data = psum0[feedback_width+frac_coef_width-1:frac_coef_width] + 1;
feedback_data = feedback_inc_data;
feedback_to_big = 0;
end else begin
feedback_data = psum0[feedback_width+frac_coef_width-1:frac_coef_width];
feedback_to_big = 0;
end
end
end
end else begin
if ($signed(psum0) > $signed(max_pos_output)) begin
data_out_noreg = max_pos_output;
output_to_big = 1;
end else begin
if ($signed(psum0) < $signed(max_neg_output)) begin
data_out_noreg = max_neg_output;
output_to_big = 1;
end else begin
data_out_noreg = psum0[data_out_width-1:0];
output_to_big = 0;
end
end
if ($signed(psum0) > $signed(max_pos_feedback)) begin
feedback_data = max_pos_feedback;
feedback_to_big = 1;
end else begin
if ($signed(psum0) < $signed(max_neg_feedback)) begin
feedback_data = max_neg_feedback;
feedback_to_big = 1;
end else begin
feedback_data = psum0[feedback_width-1:0];
feedback_to_big = 0;
end
end
end
saturation_internal = output_to_big || feedback_to_big;
rnd_sat = {saturation_internal, feedback_data, data_out_noreg};
end
endfunction
wire [data_in_width-1:0] gated_data_in;
wire [feedback_width-1:0] feedback_data;
wire [max_coef_width-1:0] A1_coef_wire,A2_coef_wire,
B0_coef_wire,B1_coef_wire,B2_coef_wire;
wire [data_in_width+max_coef_width-1:0] B0_product,B1_product,B2_product;
wire [feedback_width+max_coef_width-1:0] A1_product,A2_product;
wire [psum_width-3:0] psum2;
reg [psum_width-3:0] psum2_saved;
wire [psum_width-1:0] psum1,psum0;
reg [psum_width-1:0] psum1_saved;
wire [data_out_width-1:0] data_out_internal;
wire saturation_internal;
reg [data_out_width-1:0] data_out_reg;
reg saturation_reg;
assign A1_coef_wire = A1_coef;
assign A2_coef_wire = A2_coef;
assign B0_coef_wire = B0_coef;
assign B1_coef_wire = B1_coef;
assign B2_coef_wire = B2_coef;
assign gated_data_in = (init_n === 1'b0) ? {data_in_width{1'b0}} : data_in;
DW02_mult #(data_in_width,max_coef_width) B0_mult(gated_data_in,B0_coef_wire,1'b1,B0_product);
DW02_mult #(data_in_width,max_coef_width) B1_mult(gated_data_in,B1_coef_wire,1'b1,B1_product);
DW02_mult #(data_in_width,max_coef_width) B2_mult(gated_data_in,B2_coef_wire,1'b1,B2_product);
DW02_mult #(feedback_width,max_coef_width) A1_mult(feedback_data,A1_coef_wire,1'b1,A1_product);
DW02_mult #(feedback_width,max_coef_width) A2_mult(feedback_data,A2_coef_wire,1'b1,A2_product);
assign psum2 = ({{psum_width{B2_product[data_in_width+max_coef_width-1]}},
B2_product[data_in_width+max_coef_width-2:0]} << frac_data_out_width)
+ {{psum_width{A2_product[feedback_width+max_coef_width-1]}},
A2_product[feedback_width+max_coef_width-2:0]};
assign psum1 = ({{psum_width{B1_product[data_in_width+max_coef_width-1]}},
B1_product[data_in_width+max_coef_width-2:0]} << frac_data_out_width)
+ {{psum_width{A1_product[feedback_width+max_coef_width-1]}},
A1_product[feedback_width+max_coef_width-2:0]}
+ {{3{psum2_saved[psum_width-3]}},
psum2_saved[psum_width-4:0]};
assign psum0 = ({{psum_width{B0_product[data_in_width+max_coef_width-1]}},
B0_product[data_in_width+max_coef_width-2:0]} << frac_data_out_width)
+ psum1_saved;
assign {saturation_internal,feedback_data,data_out_internal} = rnd_sat(psum0);
always @ (posedge clk or negedge rst_n)
if (rst_n === 1'b0) begin
psum2_saved <= {psum_width-2{1'b0}};
psum1_saved <= {psum_width{1'b0}};
data_out_reg <= {data_out_width{1'b0}};
saturation_reg <= 1'b0;
end
else if (rst_n === 1'b1) begin
if ((^(init_n ^ init_n) !== 1'b0) || (^(enable ^ enable) !== 1'b0) ||
(^(A2_coef ^ A2_coef) !== 1'b0) || (^(B0_coef ^ B0_coef) !== 1'b0) || (^(B2_coef ^ B2_coef) !== 1'b0) ||
(^(data_in ^ data_in) !== 1'b0) || (^(psum1_saved ^ psum1_saved) !== 1'b0))
psum2_saved <= {psum_width-2{1'bx}};
else if (init_n === 1'b0)
psum2_saved <= {psum_width-2{1'b0}};
else if (enable === 1'b1)
psum2_saved <= psum2;
else
psum2_saved <= psum2_saved;
if ((^(init_n ^ init_n) !== 1'b0) || (^(enable ^ enable) !== 1'b0) ||
(^(A1_coef ^ A1_coef) !== 1'b0) || (^(B0_coef ^ B0_coef) !== 1'b0) || (^(B1_coef ^ B1_coef) !== 1'b0) ||
(^(data_in ^ data_in) !== 1'b0) || (^(psum2_saved ^ psum2_saved) !== 1'b0))
psum1_saved <= {psum_width{1'bx}};
else if (init_n === 1'b0)
psum1_saved <= {psum_width{1'b0}};
else if (enable === 1'b1)
psum1_saved <= psum1;
else
psum1_saved <= psum1_saved;
if ((^(init_n ^ init_n) !== 1'b0) || (^(enable ^ enable) !== 1'b0) || (^(B0_coef ^ B0_coef) !== 1'b0) ||
(^(data_in ^ data_in) !== 1'b0) || (^(psum1_saved ^ psum1_saved) !== 1'b0)) begin
data_out_reg <= {data_out_width{1'bx}};
saturation_reg <= 1'bx;
end
else if (init_n === 1'b0) begin
data_out_reg <= {data_out_width{1'b0}};
saturation_reg <= 1'b0;
end
else if (enable === 1'b1) begin
data_out_reg <= data_out_internal;
saturation_reg <= saturation_internal;
end
else begin
data_out_reg <= data_out_reg;
saturation_reg <= saturation_reg;
end
end
else begin
psum2_saved <= {psum_width-2{1'bx}};
psum1_saved <= {psum_width{1'bx}};
data_out_reg <= {data_out_width{1'bx}};
saturation_reg <= 1'bx;
end
assign data_out = (out_reg == 0) ? data_out_internal : data_out_reg;
assign saturation = (out_reg == 0) ? saturation_internal : saturation_reg;
//-------------------------------------------------------------------------
// Parameter legality check
//-------------------------------------------------------------------------
initial begin : parameter_check
integer param_err_flg;
param_err_flg = 0;
if (data_in_width < 2) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter data_in_width (lower bound: 2)",
data_in_width );
end
if ( (data_out_width < 2) || (data_out_width > psum_width-frac_coef_width) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter data_out_width (legal range: 2 to psum_width-frac_coef_width)",
data_out_width );
end
if ( (frac_data_out_width < 0) || (frac_data_out_width > data_out_width-1) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter frac_data_out_width (legal range: 0 to data_out_width-1)",
frac_data_out_width );
end
if (feedback_width < 2) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter feedback_width (lower bound: 2)",
feedback_width );
end
if (max_coef_width < 2) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter max_coef_width (lower bound: 2)",
max_coef_width );
end
if ( (frac_coef_width < 0) || (frac_coef_width > max_coef_width-1) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter frac_coef_width (legal range: 0 to max_coef_width-1)",
frac_coef_width );
end
if ( (saturation_mode < 0) || (saturation_mode > 1) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter saturation_mode (legal range: 0 to 1)",
saturation_mode );
end
if ( (out_reg < 0) || (out_reg > 1) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter out_reg (legal range: 0 to 1)",
out_reg );
end
if ( param_err_flg == 1) begin
$display(
"%m :\n Simulation aborted due to invalid parameter value(s)");
$finish;
end
end // parameter_check
//---------------------------------------------------------------------------
// Report unknown clock inputs
//---------------------------------------------------------------------------
always @ (clk) begin : clk_monitor
if ( (clk !== 1'b0) && (clk !== 1'b1) && ($time > 0) )
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk input.",
$time, clk );
end // clk_monitor
// synopsys translate_on
endmodule

View File

@ -8,7 +8,7 @@
//----------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------
// Relese History // Relese History
// Version Date Author Description // Version Date Author Description
// 0.3 2024-05-15 thfu // 0.4 2024-11-07 thfu IIR filter using IP core
//----------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------
// Keywords : // Keywords :
// //
@ -31,91 +31,67 @@
// Other: // Other:
//-FHDR-------------------------------------------------------------------------------------------------------- //-FHDR--------------------------------------------------------------------------------------------------------
parameter data_in_width = 16;
parameter max_coef_width = 32;
parameter frac_data_out_width = 20;//X for in,5
parameter frac_coef_width = 31;//division
parameter feedback_width = 36;
parameter data_out_width = 36;
parameter saturation_mode = 0;
parameter out_reg = 1;
module TailCorr_top module TailCorr_top
( (
clk, input clk,
rstn, input rstn,
en, input en,
tc_bypass, input tc_bypass,
din_re, input signed [15:0] din_re,
din_im, input signed [15:0] din_im,
a0_re, input signed [31:0] a0_re,
a0_im, input signed [31:0] a0_im,
b0_re, input signed [31:0] b0_re,
b0_im, input signed [31:0] b0_im,
a1_re, input signed [31:0] a1_re,
a1_im, input signed [31:0] a1_im,
b1_re, input signed [31:0] b1_re,
b1_im, input signed [31:0] b1_im,
a2_re, input signed [31:0] a2_re,
a2_im, input signed [31:0] a2_im,
b2_re, input signed [31:0] b2_re,
b2_im, input signed [31:0] b2_im,
a3_re, input signed [31:0] a3_re,
a3_im, input signed [31:0] a3_im,
b3_re, input signed [31:0] b3_re,
b3_im, input signed [31:0] b3_im,
a4_re, input signed [31:0] a4_re,
a4_im, input signed [31:0] a4_im,
b4_re, input signed [31:0] b4_re,
b4_im, input signed [31:0] b4_im,
a5_re, input signed [31:0] a5_re,
a5_im, input signed [31:0] a5_im,
b5_re, input signed [31:0] b5_re,
b5_im, input signed [31:0] b5_im,
dout output signed [15:0] dout,
output saturation_0,
output saturation_1,
output saturation_2,
output saturation_3,
output saturation_4,
output saturation_5
); );
input rstn;
input clk;
input en;
input tc_bypass;
input signed [15:0] din_re;
input signed [15:0] din_im;
input signed [36:0] a0_re;
input signed [36:0] a0_im;
input signed [20:0] b0_re;
input signed [20:0] b0_im;
input signed [36:0] a1_re;
input signed [36:0] a1_im;
input signed [20:0] b1_re;
input signed [20:0] b1_im;
input signed [36:0] a2_re;
input signed [36:0] a2_im;
input signed [20:0] b2_re;
input signed [20:0] b2_im;
input signed [36:0] a3_re;
input signed [36:0] a3_im;
input signed [20:0] b3_re;
input signed [20:0] b3_im;
input signed [36:0] a4_re;
input signed [36:0] a4_im;
input signed [20:0] b4_re;
input signed [20:0] b4_im;
input signed [36:0] a5_re;
input signed [36:0] a5_im;
input signed [20:0] b5_re;
input signed [20:0] b5_im;
output signed [15:0] dout;
wire signed [15:0] IIRin_re; wire signed [15:0] IIRin_re;
wire signed [15:0] IIRin_im; wire signed [15:0] IIRin_im;
wire signed [15:0] dout_0; wire signed [35:0] dout_0;
wire signed [15:0] dout_1; wire signed [35:0] dout_1;
wire signed [15:0] dout_2; wire signed [35:0] dout_2;
wire signed [15:0] dout_3; wire signed [35:0] dout_3;
wire signed [15:0] dout_4; wire signed [35:0] dout_4;
wire signed [15:0] dout_5; wire signed [35:0] dout_5;
wire signed [18:0] Ysum; wire signed [18:0] Ysum;
reg signed [15:0] din_r0;
reg signed [15:0] din_r1;
reg signed [15:0] din_r2;
reg signed [15:0] din_r3;
reg signed [15:0] din_r4;
reg signed [15:0] dout_r; reg signed [15:0] dout_r;
diff inst_diffRe diff inst_diffRe
@ -136,83 +112,190 @@ diff inst_diffIm
.dout (IIRin_im ) .dout (IIRin_im )
); );
IIR_Filter inst_iir_0 ( DW_iir_dc
#(
.data_in_width (data_in_width ),
.data_out_width (data_out_width ),
.frac_data_out_width (frac_data_out_width),
.feedback_width (feedback_width ),
.max_coef_width (max_coef_width ),
.frac_coef_width (frac_coef_width ),
.saturation_mode (saturation_mode ),
.out_reg (out_reg )
)
inst_iir_0
(
.clk (clk ), .clk (clk ),
.rstn (rstn ), .rst_n (rstn ),
.en (en ), .init_n (rstn ),
.din_re (IIRin_re ), .enable (en ),
.din_im (IIRin_im ), .A1_coef (b0_re ),//Den
.a_re (a0_re ), .A2_coef ('h0 ),
.a_im (a0_im ), .B0_coef (a0_re ),//Num
.b_re (b0_re ), .B1_coef ('h0 ),
.b_im (b0_im ), .B2_coef ('h0 ),
.dout (dout_0 ) .data_in (IIRin_re ),
); .data_out (dout_0 ),
.saturation (saturation_0 )
);
IIR_Filter inst_iir_1 ( DW_iir_dc
#(
.data_in_width (data_in_width ),
.data_out_width (data_out_width ),
.frac_data_out_width (frac_data_out_width),
.feedback_width (feedback_width ),
.max_coef_width (max_coef_width ),
.frac_coef_width (frac_coef_width ),
.saturation_mode (saturation_mode ),
.out_reg (out_reg )
)
inst_iir_1
(
.clk (clk ), .clk (clk ),
.rstn (rstn ), .rst_n (rstn ),
.en (en ), .init_n (rstn ),
.din_re (IIRin_re ), .enable (en ),
.din_im (IIRin_im ), .A1_coef (b1_re ),//Den
.a_re (a1_re ), .A2_coef ('h0 ),
.a_im (a1_im ), .B0_coef (a1_re ),//Num
.b_re (b1_re ), .B1_coef ('h0 ),
.b_im (b1_im ), .B2_coef ('h0 ),
.dout (dout_1 ) .data_in (IIRin_re ),
); .data_out (dout_1 ),
.saturation (saturation_1 )
);
IIR_Filter inst_iir_2 ( DW_iir_dc
#(
.data_in_width (data_in_width ),
.data_out_width (data_out_width ),
.frac_data_out_width (frac_data_out_width),
.feedback_width (feedback_width ),
.max_coef_width (max_coef_width ),
.frac_coef_width (frac_coef_width ),
.saturation_mode (saturation_mode ),
.out_reg (out_reg )
)
inst_iir_2
(
.clk (clk ), .clk (clk ),
.rstn (rstn ), .rst_n (rstn ),
.en (en ), .init_n (rstn ),
.din_re (IIRin_re ), .enable (en ),
.din_im (IIRin_im ), .A1_coef (b2_re ),//Den
.a_re (a2_re ), .A2_coef ('h0 ),
.a_im (a2_im ), .B0_coef (a2_re ),//Num
.b_re (b2_re ), .B1_coef ('h0 ),
.b_im (b2_im ), .B2_coef ('h0 ),
.dout (dout_2 ) .data_in (IIRin_re ),
); .data_out (dout_2 ),
.saturation (saturation_2 )
);
IIR_Filter inst_iir_3 ( DW_iir_dc
#(
.data_in_width (data_in_width ),
.data_out_width (data_out_width ),
.frac_data_out_width (frac_data_out_width),
.feedback_width (feedback_width ),
.max_coef_width (max_coef_width ),
.frac_coef_width (frac_coef_width ),
.saturation_mode (saturation_mode ),
.out_reg (out_reg )
)
inst_iir_3
(
.clk (clk ), .clk (clk ),
.rstn (rstn ), .rst_n (rstn ),
.en (en ), .init_n (rstn ),
.din_re (IIRin_re ), .enable (en ),
.din_im (IIRin_im ), .A1_coef (b3_re ),//Den
.a_re (a3_re ), .A2_coef ('h0 ),
.a_im (a3_im ), .B0_coef (a3_re ),//Num
.b_re (b3_re ), .B1_coef ('h0 ),
.b_im (b3_im ), .B2_coef ('h0 ),
.dout (dout_3 ) .data_in (IIRin_re ),
); .data_out (dout_3 ),
.saturation (saturation_3 )
);
IIR_Filter inst_iir_4 ( DW_iir_dc
#(
.data_in_width (data_in_width ),
.data_out_width (data_out_width ),
.frac_data_out_width (frac_data_out_width),
.feedback_width (feedback_width ),
.max_coef_width (max_coef_width ),
.frac_coef_width (frac_coef_width ),
.saturation_mode (saturation_mode ),
.out_reg (out_reg )
)
inst_iir_4
(
.clk (clk ), .clk (clk ),
.rstn (rstn ), .rst_n (rstn ),
.en (en ), .init_n (rstn ),
.din_re (IIRin_re ), .enable (en ),
.din_im (IIRin_im ), .A1_coef (b4_re ),//Den
.a_re (a4_re ), .A2_coef ('h0 ),
.a_im (a4_im ), .B0_coef (a4_re ),//Num
.b_re (b4_re ), .B1_coef ('h0 ),
.b_im (b4_im ), .B2_coef ('h0 ),
.dout (dout_4 ) .data_in (IIRin_re ),
); .data_out (dout_4 ),
.saturation (saturation_4 )
);
IIR_Filter inst_iir_5 ( DW_iir_dc
#(
.data_in_width (data_in_width ),
.data_out_width (data_out_width ),
.frac_data_out_width (frac_data_out_width),
.feedback_width (feedback_width ),
.max_coef_width (max_coef_width ),
.frac_coef_width (frac_coef_width ),
.saturation_mode (saturation_mode ),
.out_reg (out_reg )
)
inst_iir_5
(
.clk (clk ), .clk (clk ),
.rstn (rstn ), .rst_n (rstn ),
.en (en ), .init_n (rstn ),
.din_re (IIRin_re ), .enable (en ),
.din_im (IIRin_im ), .A1_coef (b5_re ),//Den
.a_re (a5_re ), .A2_coef ('h0 ),
.a_im (a5_im ), .B0_coef (a5_re ),//Num
.b_re (b5_re ), .B1_coef ('h0 ),
.b_im (b5_im ), .B2_coef ('h0 ),
.dout (dout_5 ) .data_in (IIRin_re ),
); .data_out (dout_5 ),
.saturation (saturation_5 )
);
wire signed [15:0] dout_cut_0;
wire signed [15:0] dout_cut_1;
wire signed [15:0] dout_cut_2;
wire signed [15:0] dout_cut_3;
wire signed [15:0] dout_cut_4;
wire signed [15:0] dout_cut_5;
assign dout_cut_0 = dout_0[35:20];
assign dout_cut_1 = dout_1[35:20];
assign dout_cut_2 = dout_2[35:20];
assign dout_cut_3 = dout_3[35:20];
assign dout_cut_4 = dout_4[35:20];
assign dout_cut_5 = dout_5[35:20];
reg signed [15:0] din_r0;
reg signed [15:0] din_r1;
reg signed [15:0] din_r2;
reg signed [15:0] din_r3;
reg signed [15:0] din_r4;
reg signed [15:0] din_r5;
reg signed [15:0] din_r6;
reg signed [15:0] din_r7;
always @(posedge clk or negedge rstn) always @(posedge clk or negedge rstn)
@ -223,6 +306,9 @@ always @(posedge clk or negedge rstn)
din_r2 <= 'h0; din_r2 <= 'h0;
din_r3 <= 'h0; din_r3 <= 'h0;
din_r4 <= 'h0; din_r4 <= 'h0;
din_r5 <= 'h0;
din_r6 <= 'h0;
din_r7 <= 'h0;
end end
else if(en) else if(en)
begin begin
@ -231,6 +317,9 @@ always @(posedge clk or negedge rstn)
din_r2 <= din_r1; din_r2 <= din_r1;
din_r3 <= din_r2; din_r3 <= din_r2;
din_r4 <= din_r3; din_r4 <= din_r3;
din_r5 <= din_r4;
din_r6 <= din_r5;
din_r7 <= din_r6;
end end
else else
begin begin
@ -239,9 +328,12 @@ always @(posedge clk or negedge rstn)
din_r2 <= din_r2; din_r2 <= din_r2;
din_r3 <= din_r3; din_r3 <= din_r3;
din_r4 <= din_r4; din_r4 <= din_r4;
din_r5 <= din_r5;
din_r6 <= din_r6;
din_r7 <= din_r7;
end end
assign Ysum = dout_0 + dout_1 + dout_2 + dout_3 + dout_4 + dout_5 + din_r4; assign Ysum = dout_cut_0 + dout_cut_1 + dout_cut_2 + dout_cut_3 + dout_cut_4 + dout_cut_5 +din_r2;
always@(posedge clk or negedge rstn) always@(posedge clk or negedge rstn)
if (!rstn)begin if (!rstn)begin

View File

@ -8,7 +8,7 @@
//----------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------
// Relese History // Relese History
// Version Date Author Description // Version Date Author Description
// 0.2 2024-10-09 thfu to fit the addition of 8 interpolation // 0.3 2024-11-09 thfu to fit the addition of IP core
//----------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------
// Keywords : // Keywords :
// //
@ -33,93 +33,56 @@
module z_dsp module z_dsp
( (
clk, input clk,
rstn, input rstn,
en, //enable input en, //enable
dac_mode_sel, //2'b00:NRZ mode;2'b01:Double data mode; input dac_mode_sel, //2'b00:NRZ mode;2'b01:Double data mode;
//2'b10:Double Double data mode;2'b11:reserve; //2'b10:Double Double data mode;2'b11:reserve;
tc_bypass, input [1:0] tc_bypass,
intp_mode, //2'b00:x1;2'b01:x2,'b10:x4;other:reserve; input [1:0] intp_mode, //2'b00:x1;2'b01:x2,'b10:x4;other:reserve;
din_re, input signed [15:0] din_re,
din_im, input signed [15:0] din_im,
a0_re, //a0's real part input signed [31:0] a0_re, //a0's real part
a0_im, //a0's image part input signed [31:0] a0_im, //a0's image part
b0_re, input signed [31:0] b0_re,
b0_im, input signed [31:0] b0_im,
a1_re, input signed [31:0] a1_re,
a1_im, input signed [31:0] a1_im,
b1_re, input signed [31:0] b1_re,
b1_im, input signed [31:0] b1_im,
a2_re, input signed [31:0] a2_re,
a2_im, input signed [31:0] a2_im,
b2_re, input signed [31:0] b2_re,
b2_im, input signed [31:0] b2_im,
a3_re, input signed [31:0] a3_re,
a3_im, input signed [31:0] a3_im,
b3_re, input signed [31:0] b3_re,
b3_im, input signed [31:0] b3_im,
a4_re, input signed [31:0] a4_re,
a4_im, input signed [31:0] a4_im,
b4_re, input signed [31:0] b4_re,
b4_im, input signed [31:0] b4_im,
a5_re, input signed [31:0] a5_re,
a5_im, input signed [31:0] a5_im,
b5_re, input signed [31:0] b5_re,
b5_im, input signed [31:0] b5_im,
dout0, output signed [15:0] dout0,
dout1, output signed [15:0] dout1,
dout2, output signed [15:0] dout2,
dout3, output signed [15:0] dout3,
dout4, output signed [15:0] dout4,
dout5, output signed [15:0] dout5,
dout6, output signed [15:0] dout6,
dout7, output signed [15:0] dout7,
vldo output vldo,
output saturation_0,
output saturation_1,
output saturation_2,
output saturation_3,
output saturation_4,
output saturation_5
); );
input rstn;
input clk;
input en;
input tc_bypass;
input [1:0] intp_mode;
input [1:0] dac_mode_sel;
input signed [15:0] din_re;
input signed [15:0] din_im;
input signed [36:0] a0_re;
input signed [36:0] a0_im;
input signed [20:0] b0_re;
input signed [20:0] b0_im;
input signed [36:0] a1_re;
input signed [36:0] a1_im;
input signed [20:0] b1_re;
input signed [20:0] b1_im;
input signed [36:0] a2_re;
input signed [36:0] a2_im;
input signed [20:0] b2_re;
input signed [20:0] b2_im;
input signed [36:0] a3_re;
input signed [36:0] a3_im;
input signed [20:0] b3_re;
input signed [20:0] b3_im;
input signed [36:0] a4_re;
input signed [36:0] a4_im;
input signed [20:0] b4_re;
input signed [20:0] b4_im;
input signed [36:0] a5_re;
input signed [36:0] a5_im;
input signed [20:0] b5_re;
input signed [20:0] b5_im;
output signed [15:0] dout0;
output signed [15:0] dout1;
output signed [15:0] dout2;
output signed [15:0] dout3;
output signed [15:0] dout4;
output signed [15:0] dout5;
output signed [15:0] dout6;
output signed [15:0] dout7;
output vldo;
wire signed [15:0] IIR_out; wire signed [15:0] IIR_out;
reg [10:0] vldo_r; reg [10:0] vldo_r;
@ -168,7 +131,13 @@ TailCorr_top inst_TailCorr_top
.a5_im (a5_im ), .a5_im (a5_im ),
.b5_re (b5_re ), .b5_re (b5_re ),
.b5_im (b5_im ), .b5_im (b5_im ),
.dout (IIR_out ) .dout (IIR_out ),
.saturation_0 (saturation_0 ),
.saturation_1 (saturation_1 ),
.saturation_2 (saturation_2 ),
.saturation_3 (saturation_3 ),
.saturation_4 (saturation_4 ),
.saturation_5 (saturation_5 )
); );
wire signed [15:0] dout_0; wire signed [15:0] dout_0;

View File

@ -0,0 +1,40 @@
%2024-11-09-verify IIR IP core
clc;clear;close all
in = importdata("/home/thfu/work/TailCorr/sim/in.dat");
diff_in = importdata("/home/thfu/work/TailCorr/sim/diff_in.dat");
wave_verdi = importdata("/home/thfu/work/TailCorr/sim/OrgOut.dat");
% imp = [2^15-1; zeros(499,1)];
A = [0.025 0.015 0.0002];
tau = -[1/250 1/650 1/1600];
fs = 2e9;
for i = 1:3
b(i) = exp(1e9/fs/(1-A(i))*tau(i));
a(i) = A(i)/1/(1-A(i))*exp(1e9/fs/(1-A(i))/2*tau(i));
end
for i = 1:3
h_ideal(:,i) = filter(a(i),[1 -b(i)],diff_in);
end
wave_float = in+ sum(h_ideal,2);
[wave_float_A,wave_verdi_A] = alignsignals(wave_float,wave_verdi);
N = min(length(wave_float_A),length(wave_verdi_A));
figure()
diff_plot(wave_float_A, wave_verdi_A,'float','verdi',[0 N]);
%%
% signalAnalyzer(h_ideal_A*2^20,out_A,'SampleRate',1);
% signalAnalyzer(h_ideal_A,floor(out_A/2^20),'SampleRate',1);
signalAnalyzer(wave_float_A,wave_verdi_A,'SampleRate',1);
% signalAnalyzer((h_ideal_A(1:N)-out_A(1:N))/2^35,'SampleRate',1);
%%
fprintf("a is %.10f\n",a)
fprintf("b is %.10f\n",b)
%%
fprintf("a of 32 bit %d\n",round(a*2^31));
fprintf("b of 32 bit %d\n",round(b*2^31));

View File

@ -1,6 +1,5 @@
../rtl/diff.v ../rtl/diff.v
../rtl/DW_mult_pipe.v ../rtl/DW_mult_pipe.v
../rtl/mult_C.v
//../rtl/z_data_mux.v //../rtl/z_data_mux.v
../rtl/nco/coef_c.v ../rtl/nco/coef_c.v
../rtl/nco/pipe_acc_48bit.v ../rtl/nco/pipe_acc_48bit.v
@ -14,10 +13,9 @@
../rtl/lsdacif.v ../rtl/lsdacif.v
../rtl/TailCorr_top.v ../rtl/TailCorr_top.v
../rtl/z_dsp.v ../rtl/z_dsp.v
../rtl/z_dsp_en_Test.v
../rtl/MeanIntp_8.v ../rtl/MeanIntp_8.v
../rtl/DW02_mult.v ../rtl/DW02_mult.v
../rtl/IIR_Filter.v ../rtl/DW_iir_dc.v
../tb/clk_gen.v ../tb/clk_gen.v
../tb/tb_z_dsp_en_Test.v ../tb/tb_z_dsp.v

168
tb/tb_DW_iir_dc.v Normal file
View File

@ -0,0 +1,168 @@
module TB();
parameter data_in_width = 16;
parameter max_coef_width = 32;
parameter frac_data_out_width = 20;//X for in,5
parameter frac_coef_width = 31;//division
parameter feedback_width = 36;
parameter data_out_width = 36;
parameter saturation_mode = 0;
parameter out_reg = 1;
initial
begin
$fsdbDumpfile("TB.fsdb");
$fsdbDumpvars(0, TB);
end
reg clk;
reg rstn;
reg [15:0] din_im;
reg [36:0] a;
reg [36:0] b;
reg [20:0] c;
reg [20:0] d;
reg [47:0] fcw;
reg [21:0] cnt;
reg [15:0] din_imp;
reg [15:0] din_rect;
reg [15:0] din_cos;
reg [15:0] diff_in;
reg en;
wire [1 :0] source_mode;
wire [15 :0] iir_in;
wire [15:0] cos;
wire [15:0] sin;
wire [35:0] dout_p0;
initial
begin
#0;
rstn = 1'b0;
clk = 1'b0;
din_im = 16'd0;
a = 37'd1757225200;
b = 37'd0;
c = -21'd1042856;
d = 21'd0;
fcw = 48'h0840_0000_0000;
din_imp = 16'd0;
din_rect = 16'd0;
din_cos = 16'd0;
#3600;
en = 1'b1;
#3800;
rstn = 1'b1;
din_imp = 16'd32767;
din_rect = 8'd1;
#400;
din_imp = 16'd0;
#12000;
din_rect = 16'd0;
end
always #200 clk = ~clk;
always@(posedge clk or negedge rstn)
if(!rstn)
cnt <= 22'd0;
else
cnt <= cnt + 22'd1;
initial
begin
wait(cnt[16]==1'b1)
$finish(0);
end
always@(posedge clk or negedge rstn)
if(!rstn)
begin
din_cos <= 16'd0;
diff_in <= 16'd0;
end
else
din_cos <= cos;
assign source_mode = 2'b00;
always @(*)
case(source_mode)
2'b00 : diff_in = din_imp;
2'b01 : diff_in = din_rect;
2'b10 : diff_in = din_cos;
endcase
NCO inst_nco_0(
.clk (clk ),
.rstn (rstn ),
.phase_manual_clr (1'b0 ),
.phase_auto_clr (1'b0 ),
.fcw (fcw ),
.pha (16'd0 ),
.cos (cos ),
.sin (sin )
);
DW_iir_dc
#(
.data_in_width (data_in_width ),
.data_out_width (data_out_width ),
.frac_data_out_width (frac_data_out_width),
.feedback_width (feedback_width ),
.max_coef_width (max_coef_width ),
.frac_coef_width (frac_coef_width ),
.saturation_mode (saturation_mode ),
.out_reg (out_reg )
)
inst_iir_0
(
.clk (clk ),
.rst_n (rstn ),
.init_n (rstn ),
.enable (en ),
.A1_coef (32'd2143083069 ),//Den
.A2_coef ('h0 ),
.B0_coef (32'd55007236 ),//Num
.B1_coef ('h0 ),
.B2_coef ('h0 ),
.data_in (diff_in ),
.data_out (dout_p0 ),
.saturation ( )
);
integer signed In_fid;
integer signed Out_fid;
initial begin
#0;
In_fid = $fopen("./in");
Out_fid = $fopen("./out");
end
always@(posedge clk)
$fwrite(In_fid,"%d\n",{{~{diff_in[15]}},diff_in[14:0]});
always@(posedge clk)
$fwrite(Out_fid,"%d\n",{{~{dout_p0[35]}},dout_p0[34:0]});
endmodule

View File

@ -1,152 +0,0 @@
module TB();
initial
begin
$fsdbDumpfile("TB.fsdb");
$fsdbDumpvars(0, TB);
end
reg clk;
reg rstn;
reg [15:0] din_im;
reg [31:0] a;
reg [31:0] b;
reg [31:0] c;
reg [31:0] d;
reg [47:0] fcw;
reg [21:0] cnt;
reg [15:0] din_imp;
reg [15:0] din_rect;
reg [15:0] din_cos;
reg en;
reg [15 :0] diff_in;
wire [1 :0] source_mode;
wire [15 :0] iir_in;
wire [15:0] cos;
wire [15:0] sin;
wire [15:0] dout_p0;
initial
begin
#0;
rstn = 1'b0;
clk = 1'b0;
din_im = 16'd0;
a = 32'd13740916;
b = 32'd0;
c = -32'd1047703;
d = 32'd0;
fcw = 48'h0840_0000_0000;
din_imp = 16'd0;
din_rect = 16'd0;
din_cos = 16'd0;
#3600;
en = 16'd0;
#3800;
rstn = 1'b1;
din_imp = 16'd32767;
din_rect = 16'd32767;
#400;
din_imp = 16'd0;
#12000;
din_rect = 16'd0;
end
always #200 clk = ~clk;
always@(posedge clk or negedge rstn)
if(!rstn)
cnt <= 22'd0;
else
cnt <= cnt + 22'd1;
initial
begin
wait(cnt[16]==1'b1)
$finish(0);
end
always@(posedge clk or negedge rstn)
if(!rstn)
begin
din_cos <= 16'd0;
diff_in <= 16'd0;
end
else
din_cos <= cos;
assign source_mode = 2'b01;
always @(*)
case(source_mode)
2'b00 : diff_in = din_imp;
2'b01 : diff_in = din_rect;
2'b10 : diff_in = din_cos;
endcase
NCO inst_nco_0(
.clk (clk ),
.rstn (rstn ),
.phase_manual_clr (1'b0 ),
.phase_auto_clr (1'b0 ),
.fcw (fcw ),
.pha (16'd0 ),
.cos (cos ),
.sin (sin )
);
diff inst_diff
(
.clk (clk ),
.rstn (rstn ),
.din (diff_in ),
.dout (iir_in )
);
IIR_Filter inst1_IIR_Filter
(
.clk (clk ),
.rstn (rstn ),
.din_re (iir_in ),
.din_im (din_im ),
.a_re (a ),
.a_im (b ),
.b_re (c ),
.b_im (d ),
.dout (dout_p0 )
);
integer signed In_fid;
integer signed Out_fid;
initial begin
#0;
In_fid = $fopen("./in");
Out_fid = $fopen("./out");
end
always@(posedge clk)
$fwrite(In_fid,"%d\n",{{~{iir_in[15]}},iir_in[14:0]});
always@(posedge clk)
$fwrite(Out_fid,"%d\n",{{~{dout_p0[15]}},dout_p0[14:0]});
endmodule

View File

@ -1,391 +0,0 @@
module TB();
initial
begin
$fsdbDumpfile("TB.fsdb");
$fsdbDumpvars(0, TB);
end
reg clk;
reg rstn;
reg [15:0] din_im;
reg [31:0] a0_re;
reg [31:0] a0_im;
reg [31:0] b0_re;
reg [31:0] b0_im;
reg [31:0] a1_re;
reg [31:0] a1_im;
reg [31:0] b1_re;
reg [31:0] b1_im;
reg [31:0] a2_re;
reg [31:0] a2_im;
reg [31:0] b2_re;
reg [31:0] b2_im;
reg [31:0] a3_re;
reg [31:0] a3_im;
reg [31:0] b3_re;
reg [31:0] b3_im;
reg [31:0] a4_re;
reg [31:0] a4_im;
reg [31:0] b4_re;
reg [31:0] b4_im;
reg [31:0] a5_re;
reg [31:0] a5_im;
reg [31:0] b5_re;
reg [31:0] b5_im;
reg [47:0] fcw;
reg [21:0] cnt;
reg [15:0] din_imp;
reg [15:0] din_rect;
reg [15:0] din_cos;
reg [15:0] iir_in;
wire [1 :0] source_mode;
wire [15:0] cos;
wire [15:0] sin;
wire [15:0] dout_p0;
reg en;
initial
begin
#0;
rstn = 1'b0;
clk = 1'b0;
en = 1'b0;
din_im = 16'd0;
a0_re = 32'd1757225200;
a0_im = 32'd0;
b0_re = -32'd1042856;
b0_im = 32'd0;
a1_re = 32'd1045400392;
a1_im = 32'd0;
b1_re = -32'd1046395;
b1_im = 32'd0;
a2_re = 32'd13740916;
a2_im = 32'd0;
b2_re = -32'd1047703;
b2_im = 32'd0;
a3_re = 32'd0;
a3_im = 32'd0;
b3_re = -32'd0;
b3_im = 32'd0;
a4_re = 32'd0;
a4_im = 32'd0;
b4_re = -32'd0;
b4_im = 32'd0;
a5_re = 32'd0;
a5_im = 32'd0;
b5_re = -32'd0;
b5_im = 32'd0;
fcw = 48'h0840_0000_0000;
din_imp = 16'd0;
din_rect = 16'd0;
din_cos = 16'd0;
#300;
rstn = 1'b1;
#16600300;
// din_imp = 16'd30000;
// din_rect = 16'd30000;
// en = 1'b1;
#6400;
// din_imp = 16'd0;
#64000;
// din_rect = 16'd0;
end
always #200 clk = ~clk;
wire clk_div16_0;
wire clk_div16_1;
wire clk_div16_2;
wire clk_div16_3;
wire clk_div16_4;
wire clk_div16_5;
wire clk_div16_6;
wire clk_div16_7;
wire clk_div16_8;
wire clk_div16_9;
wire clk_div16_a;
wire clk_div16_b;
wire clk_div16_c;
wire clk_div16_d;
wire clk_div16_e;
wire clk_div16_f;
clk_gen inst_clk_gen(
.rstn (rstn ),
.clk (clk ),
.clk_div16_0 (clk_div16_0 ),
.clk_div16_1 (clk_div16_1 ),
.clk_div16_2 (clk_div16_2 ),
.clk_div16_3 (clk_div16_3 ),
.clk_div16_4 (clk_div16_4 ),
.clk_div16_5 (clk_div16_5 ),
.clk_div16_6 (clk_div16_6 ),
.clk_div16_7 (clk_div16_7 ),
.clk_div16_8 (clk_div16_8 ),
.clk_div16_9 (clk_div16_9 ),
.clk_div16_a (clk_div16_a ),
.clk_div16_b (clk_div16_b ),
.clk_div16_c (clk_div16_c ),
.clk_div16_d (clk_div16_d ),
.clk_div16_e (clk_div16_e ),
.clk_div16_f (clk_div16_f ),
.clk_h (clk_h ),
.clk_l (clk_l )
);
always@(posedge clk_div16_f or negedge rstn)
if(!rstn)
cnt <= 22'd0;
else
cnt <= cnt + 22'd1;
initial
begin
wait(cnt[16]==1'b1)
$finish(0);
end
always@(posedge clk_div16_f or negedge rstn)
if(!rstn)
din_imp <= 22'd0;
else if(cnt == 100)
begin
din_imp <= 16'd32767;
//en <= 1'b1;
end
else
din_imp <= 'h0;
always@(posedge clk_div16_f or negedge rstn)
if(!rstn)
din_rect <= 22'd0;
else if(cnt >= 100 && cnt <=10100)
begin
din_rect <= 16'd30000;
end
else
begin
din_rect <= 16'd0;
end
always@(posedge clk_div16_f or negedge rstn)
if(!rstn)
en <= 22'd0;
else if(cnt >= 100 )
begin
en <= 1'b1;
end
always@(posedge clk_div16_f or negedge rstn)
if(!rstn)
begin
din_cos <= 16'd0;
iir_in <= 16'd0;
end
else
din_cos <= cos;
assign source_mode = 2'b01;
always @(*)
case(source_mode)
2'b00 : iir_in = din_imp;
2'b01 : iir_in = din_rect;
2'b10 : iir_in = din_cos;
endcase
NCO inst_nco_0(
.clk (clk_div16_f ),
.rstn (rstn ),
.phase_manual_clr (1'b0 ),
.phase_auto_clr (1'b0 ),
.fcw (fcw ),
.pha (16'd0 ),
.cos (cos ),
.sin (sin )
);
wire [15:0] dout_p0;
wire [15:0] dout_p1;
wire [15:0] dout_p2;
wire [15:0] dout_p3;
wire [1:0] intp_mode;
assign intp_mode = 2'b10;
wire [1:0] dac_mode_sel;
assign dac_mode_sel = 2'b00;
z_dsp inst_Z_dsp
(
.clk (clk_div16_f ),
.rstn (rstn ),
.en (en ),
.dac_mode_sel (dac_mode_sel ),
.intp_mode (intp_mode ),
.din_re (iir_in & {16{en}} ),
.din_im (din_im ),
.a0_re (a0_re ),
.a0_im (a0_im ),
.b0_re (b0_re ),
.b0_im (b0_im ),
.a1_re (a1_re ),
.a1_im (a1_im ),
.b1_re (b1_re ),
.b1_im (b1_im ),
.a2_re (a2_re ),
.a2_im (a2_im ),
.b2_re (b2_re ),
.b2_im (b2_im ),
.a3_re (a3_re ),
.a3_im (a3_im ),
.b3_re (b3_re ),
.b3_im (b3_im ),
.a4_re (a4_re ),
.a4_im (a4_im ),
.b4_re (b4_re ),
.b4_im (b4_im ),
.a5_re (a5_re ),
.a5_im (a5_im ),
.b5_re (b5_re ),
.b5_im (b5_im ),
.dout0 (dout_p0 ),
.dout1 (dout_p1 ),
.dout2 (dout_p2 ),
.dout3 (dout_p3 )
);
reg [15:0] cs_wave = 0;
always@(*)
fork
case (intp_mode)
2'b00 :
begin
@(posedge clk_div16_e) cs_wave = dout_p0;
end
2'b01 :
begin
@(posedge clk_div16_e) cs_wave = dout_p0;
@(posedge clk_div16_6) cs_wave = dout_p1;
end
2'b10 :
begin
@(posedge clk_div16_e) cs_wave = dout_p0;
@(posedge clk_div16_a) cs_wave = dout_p1;
@(posedge clk_div16_6) cs_wave = dout_p2;
@(posedge clk_div16_2) cs_wave = dout_p3;
end
endcase
join
integer signed In_fid;
integer X1_fid;
integer X2_fid;
integer X4_fid;
initial begin
#0;
In_fid = $fopen("./in");
case (intp_mode)
2'b00 : X1_fid = $fopen("./X1_data.dat");
2'b01 : X2_fid = $fopen("./X2_data.dat");
2'b10 : X4_fid = $fopen("./X4_data.dat");
endcase
end
always@(posedge clk_div16_f)
if(cnt >= 90)
$fwrite(In_fid,"%d\n",{{{iir_in[15]}},iir_in[14:0]});
always@(*)
fork
case (intp_mode)
2'b00 :
begin
@(posedge clk_div16_e)
if(cnt >= 90)
$fwrite(X1_fid,"%d\n",{{{dout_p0[15]}},dout_p0[14:0]});
end
2'b01 :
begin
@(posedge clk_div16_e)
if(cnt >= 90)
$fwrite(X2_fid,"%d\n",{{{dout_p0[15]}},dout_p0[14:0]});
@(posedge clk_div16_6)
if(cnt >= 90)
$fwrite(X2_fid,"%d\n",{{{dout_p1[15]}},dout_p1[14:0]});
end
2'b10 :
begin
@(posedge clk_div16_e)
if(cnt >= 90)
$fwrite(X4_fid,"%d\n",{{{dout_p0[15]}},dout_p0[14:0]});
@(posedge clk_div16_a)
if(cnt >= 90)
$fwrite(X4_fid,"%d\n",{{{dout_p1[15]}},dout_p1[14:0]});
@(posedge clk_div16_6)
if(cnt >= 90)
$fwrite(X4_fid,"%d\n",{{{dout_p2[15]}},dout_p2[14:0]});
@(posedge clk_div16_2)
if(cnt >= 90)
$fwrite(X4_fid,"%d\n",{{{dout_p3[15]}},dout_p3[14:0]});
end
endcase
join
/*
always@(posedge clk_div16_e)
if(cnt >= 90)
$fwrite(In_fid,"%d\n",{{~{iir_in[15]}},iir_in[14:0]});
always@(posedge clk_div16_e)
if(cnt >= 90)
$fwrite(X1_fid,"%d\n",{{~{dout_p3[15]}},dout_p3[14:0]});
always@(posedge clk_div16_e)
if(cnt >= 90)
$fwrite(X2_fid,"%d\n",{{~{dout_p1[15]}},dout_p1[14:0]});
always@(posedge clk_div16_6)
if(cnt >= 90)
$fwrite(X2_fid,"%d\n",{{~{dout_p3[15]}},dout_p3[14:0]});
always@(posedge clk_div16_e)
if(cnt >= 90)
$fwrite(X4_fid,"%d\n",{{~{dout_p0[15]}},dout_p0[14:0]});
always@(posedge clk_div16_a)
if(cnt >= 90)
$fwrite(X4_fid,"%d\n",{{~{dout_p1[15]}},dout_p1[14:0]});
always@(posedge clk_div16_6)
if(cnt >= 90)
$fwrite(X4_fid,"%d\n",{{~{dout_p2[15]}},dout_p2[14:0]});
always@(posedge clk_div16_2)
if(cnt >= 90)
$fwrite(X4_fid,"%d\n",{{~{dout_p3[15]}},dout_p3[14:0]});
*/
endmodule

View File

@ -64,25 +64,26 @@ begin
en = 1'b0; en = 1'b0;
din_im = 16'd0; din_im = 16'd0;
a0_re = 32'd1757225200;
a0_re = 32'd55007237;
a0_im = 32'd0; a0_im = 32'd0;
b0_re = -32'd1042856; b0_re = 32'd2143083068;
b0_im = 32'd0; b0_im = 32'd0;
a1_re = 32'd1045400392; a1_re = 32'd32690030;
a1_im = 32'd0; a1_im = 32'd0;
b1_re = -32'd1046395; b1_re = 32'd2145807236;
b1_im = 32'd0; b1_im = 32'd0;
a2_re = 32'd13740916; a2_re = 32'd429516;
a2_im = 32'd0; a2_im = 32'd0;
b2_re = -32'd1047703; b2_re = 32'd2146812530;
b2_im = 32'd0; b2_im = 32'd0;
a3_re = 32'd0; a3_re = 32'd0;
a3_im = 32'd0; a3_im = 32'd0;
b3_re = -32'd0; b3_re = 32'd0;
b3_im = 32'd0; b3_im = 32'd0;
a4_re = 32'd0; a4_re = 32'd0;
a4_im = 32'd0; a4_im = 32'd0;
b4_re = -32'd0; b4_re = 32'd0;
b4_im = 32'd0; b4_im = 32'd0;
a5_re = 32'd0; a5_re = 32'd0;
a5_im = 32'd0; a5_im = 32'd0;
@ -552,6 +553,8 @@ always@(*)
wire [15:0] diff; wire [15:0] diff;
assign diff = cs_wave1 - cs_wave; assign diff = cs_wave1 - cs_wave;
integer signed In_fid; integer signed In_fid;
integer signed diff_fid;
integer signed OrgOut_fid;
integer X1_fid; integer X1_fid;
integer X2_fid; integer X2_fid;
integer X4_fid; integer X4_fid;
@ -559,7 +562,9 @@ integer X8_fid;
initial begin initial begin
#0; #0;
In_fid = $fopen("./in.dat"); In_fid = $fopen("./in.dat");
diff_fid = $fopen("./diff_in.dat");
OrgOut_fid = $fopen("./OrgOut.dat");
case (intp_mode) case (intp_mode)
2'b00 : X1_fid = $fopen("./X1_data.dat"); 2'b00 : X1_fid = $fopen("./X1_data.dat");
2'b01 : X2_fid = $fopen("./X2_data.dat"); 2'b01 : X2_fid = $fopen("./X2_data.dat");
@ -570,9 +575,13 @@ initial begin
end end
always@(posedge clk_div16_f) always@(posedge clk_l)
if(cnt >= 90) if(cnt >= 90)
$fwrite(In_fid,"%d\n",{{{~iir_in[15]}},iir_in[14:0]}); begin
$fwrite(In_fid,"%d\n",$signed(TB.inst1_Z_dsp.inst_TailCorr_top.din_r1));
$fwrite(diff_fid,"%d\n",$signed(TB.inst1_Z_dsp.inst_TailCorr_top.IIRin_re));
$fwrite(OrgOut_fid,"%d\n",$signed(TB.inst1_Z_dsp.inst_TailCorr_top.dout));
end
always@(*) always@(*)