508 lines
14 KiB
Verilog
508 lines
14 KiB
Verilog
//+FHDR--------------------------------------------------------------------------------------------------------
|
|
// Company:
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// File Name : TailCorr_top.v
|
|
// Department :
|
|
// Author : thfu
|
|
// Author's Tel :
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Relese History
|
|
// Version Date Author Description
|
|
// 0.4 2024-11-07 thfu IIR filter using IP core
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Keywords :
|
|
//
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Parameter
|
|
//
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Purpose :
|
|
//
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Target Device:
|
|
// Tool versions:
|
|
//-----------------------------------------------------------------------------------------------------------------
|
|
// Reuse Issues
|
|
// Reset Strategy:
|
|
// Clock Domains:
|
|
// Critical Timing:
|
|
// Asynchronous I/F:
|
|
// Synthesizable (y/n):
|
|
// Other:
|
|
//-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
|
|
|
|
(
|
|
input clk,
|
|
input rstn,
|
|
input en,
|
|
input tc_bypass,
|
|
input signed [data_in_width-1:0] din_re,
|
|
input signed [data_in_width-1:0] din_im,
|
|
input signed [frac_coef_width:0] a0_re,
|
|
input signed [frac_coef_width:0] a0_im,
|
|
input signed [frac_coef_width:0] b0_re,
|
|
input signed [frac_coef_width:0] b0_im,
|
|
input signed [frac_coef_width:0] a1_re,
|
|
input signed [frac_coef_width:0] a1_im,
|
|
input signed [frac_coef_width:0] b1_re,
|
|
input signed [frac_coef_width:0] b1_im,
|
|
input signed [frac_coef_width:0] a2_re,
|
|
input signed [frac_coef_width:0] a2_im,
|
|
input signed [frac_coef_width:0] b2_re,
|
|
input signed [frac_coef_width:0] b2_im,
|
|
input signed [frac_coef_width:0] a3_re,
|
|
input signed [frac_coef_width:0] a3_im,
|
|
input signed [frac_coef_width:0] b3_re,
|
|
input signed [frac_coef_width:0] b3_im,
|
|
input signed [frac_coef_width:0] a4_re,
|
|
input signed [frac_coef_width:0] a4_im,
|
|
input signed [frac_coef_width:0] b4_re,
|
|
input signed [frac_coef_width:0] b4_im,
|
|
input signed [frac_coef_width:0] a5_re,
|
|
input signed [frac_coef_width:0] a5_im,
|
|
input signed [frac_coef_width:0] b5_re,
|
|
input signed [frac_coef_width:0] b5_im,
|
|
output signed [15:0] dout,
|
|
output saturation_0,
|
|
output saturation_1,
|
|
output saturation_2,
|
|
output saturation_3,
|
|
output saturation_4,
|
|
output saturation_5
|
|
);
|
|
|
|
wire signed [data_in_width-1:0] IIRin_re;
|
|
wire signed [data_in_width-1:0] IIRin_im;
|
|
wire signed [data_out_width-1:0] dout_0;
|
|
wire signed [data_out_width-1:0] dout_1;
|
|
wire signed [data_out_width-1:0] dout_2;
|
|
wire signed [data_out_width-1:0] dout_3;
|
|
wire signed [data_out_width-1:0] dout_4;
|
|
wire signed [data_out_width-1:0] dout_5;
|
|
wire signed [18:0] Ysum;
|
|
|
|
|
|
reg signed [15:0] dout_r;
|
|
|
|
diff inst_diffRe
|
|
(
|
|
.clk (clk ),
|
|
.rstn (rstn ),
|
|
.en (en ),
|
|
.din (din_re ),
|
|
.dout (IIRin_re )
|
|
);
|
|
|
|
diff inst_diffIm
|
|
(
|
|
.clk (clk ),
|
|
.rstn (rstn ),
|
|
.en (en ),
|
|
.din (din_im ),
|
|
.dout (IIRin_im )
|
|
);
|
|
|
|
DW_iir_dc_m
|
|
#(
|
|
.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 (b0_re ),//Den
|
|
.A2_coef ('h0 ),
|
|
.B0_coef (a0_re ),//Num
|
|
.B1_coef ('h0 ),
|
|
.B2_coef ('h0 ),
|
|
.data_in (IIRin_re ),
|
|
.data_out (dout_0 ),
|
|
.saturation (saturation_0 )
|
|
);
|
|
|
|
DW_iir_dc_m
|
|
#(
|
|
.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 ),
|
|
.rst_n (rstn ),
|
|
.init_n (rstn ),
|
|
.enable (en ),
|
|
.A1_coef (b1_re ),//Den
|
|
.A2_coef ('h0 ),
|
|
.B0_coef (a1_re ),//Num
|
|
.B1_coef ('h0 ),
|
|
.B2_coef ('h0 ),
|
|
.data_in (IIRin_re ),
|
|
.data_out (dout_1 ),
|
|
.saturation (saturation_1 )
|
|
);
|
|
|
|
DW_iir_dc_m
|
|
#(
|
|
.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 ),
|
|
.rst_n (rstn ),
|
|
.init_n (rstn ),
|
|
.enable (en ),
|
|
.A1_coef (b2_re ),//Den
|
|
.A2_coef ('h0 ),
|
|
.B0_coef (a2_re ),//Num
|
|
.B1_coef ('h0 ),
|
|
.B2_coef ('h0 ),
|
|
.data_in (IIRin_re ),
|
|
.data_out (dout_2 ),
|
|
.saturation (saturation_2 )
|
|
);
|
|
|
|
DW_iir_dc_m
|
|
#(
|
|
.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 ),
|
|
.rst_n (rstn ),
|
|
.init_n (rstn ),
|
|
.enable (en ),
|
|
.A1_coef (b3_re ),//Den
|
|
.A2_coef ('h0 ),
|
|
.B0_coef (a3_re ),//Num
|
|
.B1_coef ('h0 ),
|
|
.B2_coef ('h0 ),
|
|
.data_in (IIRin_re ),
|
|
.data_out (dout_3 ),
|
|
.saturation (saturation_3 )
|
|
);
|
|
|
|
DW_iir_dc_m
|
|
#(
|
|
.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 ),
|
|
.rst_n (rstn ),
|
|
.init_n (rstn ),
|
|
.enable (en ),
|
|
.A1_coef (b4_re ),//Den
|
|
.A2_coef ('h0 ),
|
|
.B0_coef (a4_re ),//Num
|
|
.B1_coef ('h0 ),
|
|
.B2_coef ('h0 ),
|
|
.data_in (IIRin_re ),
|
|
.data_out (dout_4 ),
|
|
.saturation (saturation_4 )
|
|
);
|
|
|
|
DW_iir_dc_m
|
|
#(
|
|
.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 ),
|
|
.rst_n (rstn ),
|
|
.init_n (rstn ),
|
|
.enable (en ),
|
|
.A1_coef (b5_re ),//Den
|
|
.A2_coef ('h0 ),
|
|
.B0_coef (a5_re ),//Num
|
|
.B1_coef ('h0 ),
|
|
.B2_coef ('h0 ),
|
|
.data_in (IIRin_re ),
|
|
.data_out (dout_5 ),
|
|
.saturation (saturation_5 )
|
|
);
|
|
|
|
reg signed [data_out_width-1:0] dout_round_0;
|
|
reg signed [data_out_width-1:0] dout_round_1;
|
|
reg signed [data_out_width-1:0] dout_round_2;
|
|
reg signed [data_out_width-1:0] dout_round_3;
|
|
reg signed [data_out_width-1:0] dout_round_4;
|
|
reg signed [data_out_width-1:0] dout_round_5;
|
|
|
|
always@(posedge clk or negedge rstn)
|
|
if(!rstn)
|
|
begin
|
|
dout_round_0 <= 'h0;
|
|
end
|
|
else if(en) begin
|
|
if(dout_0[35] == 1'b0)
|
|
begin
|
|
dout_round_0 <= dout_0 + {{1'b1},{(frac_data_out_width-1){1'b0}}};
|
|
end
|
|
else if (dout_0[35] == 1'b1)
|
|
begin
|
|
dout_round_0 <= dout_0 + {{1'b1},{(frac_data_out_width-1){1'b0}}} - 1'b1;
|
|
end
|
|
end
|
|
else begin
|
|
dout_round_0 <= dout_round_0;
|
|
end
|
|
|
|
always@(posedge clk or negedge rstn)
|
|
if(!rstn)
|
|
begin
|
|
dout_round_1 <= 'h0;
|
|
end
|
|
else if(en) begin
|
|
if(dout_1[35] == 1'b0)
|
|
begin
|
|
dout_round_1 <= dout_1 + {{1'b1},{(frac_data_out_width-1){1'b0}}};
|
|
end
|
|
else if (dout_1[35] == 1'b1)
|
|
begin
|
|
dout_round_1 <= dout_1 + {{1'b1},{(frac_data_out_width-1){1'b0}}} - 1'b1;
|
|
end
|
|
end
|
|
else begin
|
|
dout_round_1 <= dout_round_1;
|
|
end
|
|
|
|
always@(posedge clk or negedge rstn)
|
|
if(!rstn)
|
|
begin
|
|
dout_round_2 <= 'h0;
|
|
end
|
|
else if(en) begin
|
|
if(dout_2[35] == 1'b0)
|
|
begin
|
|
dout_round_2 <= dout_2 + {{1'b1},{(frac_data_out_width-1){1'b0}}};
|
|
end
|
|
else if (dout_2[35] == 1'b1)
|
|
begin
|
|
dout_round_2 <= dout_2 + {{1'b1},{(frac_data_out_width-1){1'b0}}} - 1'b1;
|
|
end
|
|
end
|
|
else begin
|
|
dout_round_2 <= dout_round_2;
|
|
end
|
|
|
|
always@(posedge clk or negedge rstn)
|
|
if(!rstn)
|
|
begin
|
|
dout_round_3 <= 'h0;
|
|
end
|
|
else if(en) begin
|
|
if(dout_3[35] == 1'b0)
|
|
begin
|
|
dout_round_3 <= dout_3 + {{1'b1},{(frac_data_out_width-1){1'b0}}};
|
|
end
|
|
else if (dout_3[35] == 1'b1)
|
|
begin
|
|
dout_round_3 <= dout_3 + {{1'b1},{(frac_data_out_width-1){1'b0}}} - 1'b1;
|
|
end
|
|
end
|
|
else begin
|
|
dout_round_3 <= dout_round_3;
|
|
end
|
|
|
|
always@(posedge clk or negedge rstn)
|
|
if(!rstn)
|
|
begin
|
|
dout_round_4 <= 'h0;
|
|
end
|
|
else if(en) begin
|
|
if(dout_4[35] == 1'b0)
|
|
begin
|
|
dout_round_4 <= dout_4 + {{1'b1},{(frac_data_out_width-1){1'b0}}};
|
|
end
|
|
else if (dout_4[35] == 1'b1)
|
|
begin
|
|
dout_round_4 <= dout_4 + {{1'b1},{(frac_data_out_width-1){1'b0}}} - 1'b1;
|
|
end
|
|
end
|
|
else begin
|
|
dout_round_4 <= dout_round_4;
|
|
end
|
|
|
|
always@(posedge clk or negedge rstn)
|
|
if(!rstn)
|
|
begin
|
|
dout_round_5 <= 'h0;
|
|
end
|
|
else if(en) begin
|
|
if(dout_5[35] == 1'b0)
|
|
begin
|
|
dout_round_5 <= dout_5 + {{1'b1},{(frac_data_out_width-1){1'b0}}};
|
|
end
|
|
else if (dout_5[35] == 1'b1)
|
|
begin
|
|
dout_round_5 <= dout_5 + {{1'b1},{(frac_data_out_width-1){1'b0}}} - 1'b1;
|
|
end
|
|
end
|
|
else begin
|
|
dout_round_5 <= dout_round_5;
|
|
end
|
|
|
|
|
|
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_round_0[35:20];
|
|
assign dout_cut_1 = dout_round_1[35:20];
|
|
assign dout_cut_2 = dout_round_2[35:20];
|
|
assign dout_cut_3 = dout_round_3[35:20];
|
|
assign dout_cut_4 = dout_round_4[35:20];
|
|
assign dout_cut_5 = dout_round_5[35:20];
|
|
|
|
reg signed [15:0] dout_cut0_r0;
|
|
reg signed [15:0] dout_cut1_r0;
|
|
reg signed [15:0] dout_cut2_r0;
|
|
reg signed [15:0] dout_cut3_r0;
|
|
reg signed [15:0] dout_cut4_r0;
|
|
reg signed [15:0] dout_cut5_r0;
|
|
|
|
always @(posedge clk or negedge rstn)
|
|
if(!rstn) begin
|
|
dout_cut0_r0 <= 'h0;
|
|
dout_cut1_r0 <= 'h0;
|
|
dout_cut2_r0 <= 'h0;
|
|
dout_cut3_r0 <= 'h0;
|
|
dout_cut4_r0 <= 'h0;
|
|
dout_cut5_r0 <= 'h0;
|
|
end
|
|
else if(en) begin
|
|
dout_cut0_r0 <= dout_cut_0;
|
|
dout_cut1_r0 <= dout_cut_1;
|
|
dout_cut2_r0 <= dout_cut_2;
|
|
dout_cut3_r0 <= dout_cut_3;
|
|
dout_cut4_r0 <= dout_cut_4;
|
|
dout_cut5_r0 <= dout_cut_5;
|
|
end
|
|
else begin
|
|
dout_cut0_r0 <= dout_cut0_r0;
|
|
dout_cut1_r0 <= dout_cut1_r0;
|
|
dout_cut2_r0 <= dout_cut2_r0;
|
|
dout_cut3_r0 <= dout_cut3_r0;
|
|
dout_cut4_r0 <= dout_cut4_r0;
|
|
dout_cut5_r0 <= dout_cut5_r0;
|
|
end
|
|
|
|
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;
|
|
|
|
always @(posedge clk or negedge rstn)
|
|
if (!rstn)
|
|
begin
|
|
din_r0 <= 'h0;
|
|
din_r1 <= 'h0;
|
|
din_r2 <= 'h0;
|
|
din_r3 <= 'h0;
|
|
din_r4 <= 'h0;
|
|
din_r5 <= 'h0;
|
|
end
|
|
else if(en)
|
|
begin
|
|
din_r0 <= din_re;
|
|
din_r1 <= din_r0;
|
|
din_r2 <= din_r1;
|
|
din_r3 <= din_r2;
|
|
din_r4 <= din_r3;
|
|
din_r5 <= din_r4;
|
|
end
|
|
else
|
|
begin
|
|
din_r0 <= din_r0;
|
|
din_r1 <= din_r1;
|
|
din_r2 <= din_r2;
|
|
din_r3 <= din_r3;
|
|
din_r4 <= din_r4;
|
|
din_r5 <= din_r5;
|
|
end
|
|
|
|
assign Ysum = din_r4 + dout_cut0_r0 + dout_cut1_r0 + dout_cut2_r0 + dout_cut3_r0 + dout_cut4_r0 + dout_cut5_r0;
|
|
|
|
always@(posedge clk or negedge rstn)
|
|
if (!rstn)begin
|
|
dout_r <= 'h0;
|
|
end
|
|
else if(tc_bypass)begin
|
|
dout_r <= din_re;
|
|
end
|
|
else begin
|
|
if (en) begin
|
|
if(Ysum[16:15]==2'b01)
|
|
dout_r <= 16'd32767;
|
|
else if(Ysum[16:15]==2'b10)
|
|
dout_r <= -16'd32768;
|
|
else
|
|
dout_r <= Ysum[15:0];
|
|
end
|
|
else begin
|
|
dout_r <= dout_r;
|
|
end
|
|
end
|
|
assign dout = dout_r;
|
|
endmodule
|
|
|