//+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 #( .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 #( .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 #( .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 #( .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 #( .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 #( .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; always @(posedge clk or negedge rstn) if (!rstn) begin din_r0 <= 'h0; din_r1 <= 'h0; din_r2 <= 'h0; din_r3 <= 'h0; din_r4 <= '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; end else begin din_r0 <= din_r0; din_r1 <= din_r1; din_r2 <= din_r2; din_r3 <= din_r3; din_r4 <= din_r4; 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