TailCorr/rtl/z_dsp/CoefGen.v

312 lines
10 KiB
Verilog

//+FHDR--------------------------------------------------------------------------------------------------------
// Company:
//-----------------------------------------------------------------------------------------------------------------
// File Name : IIR_Filter.v
// Department :
// Author : thfu
// Author's Tel :
//-----------------------------------------------------------------------------------------------------------------
// Relese History
// Version Date Author Description
// 0.4 2024-05-28 thfu
//2024-05-28 10:22:49
//-----------------------------------------------------------------------------------------------------------------
// Keywords :
//
//-----------------------------------------------------------------------------------------------------------------
// Parameter
//
//-----------------------------------------------------------------------------------------------------------------
// Purpose :
//
//-----------------------------------------------------------------------------------------------------------------
// Target Device:
// Tool versions:
//-----------------------------------------------------------------------------------------------------------------
// Reuse Issues
// Reset Strategy:
// Clock Domains:
// Critical Timing:
// Asynchronous I/F:
// Synthesizable (y/n):
// Other:
//-FHDR--------------------------------------------------------------------------------------------------------
module CoefGen #(
parameter data_in_width = 32
,parameter coef_width = 32
,parameter frac_data_out_width = 20//X for in,5
,parameter frac_coef_width = 31//division
)
(
input rstn
,input clk
,input [5:0] vldi
,input signed [coef_width-1 :0] a_re [5:0]
,input signed [coef_width-1 :0] a_im [5:0]
,input signed [coef_width-1 :0] b_re [5:0]
,input signed [coef_width-1 :0] b_im [5:0]
,output reg signed [coef_width-1 :0] ao_re [5:0]
,output reg signed [coef_width-1 :0] ao_im [5:0]
,output reg signed [coef_width-1 :0] ab_re [5:0]
,output reg signed [coef_width-1 :0] ab_im [5:0]
,output reg signed [coef_width-1 :0] abb_re [5:0]
,output reg signed [coef_width-1 :0] abb_im [5:0]
,output reg signed [coef_width-1 :0] ab_pow3_re [5:0]
,output reg signed [coef_width-1 :0] ab_pow3_im [5:0]
,output reg signed [coef_width-1 :0] ab_pow4_re [5:0]
,output reg signed [coef_width-1 :0] ab_pow4_im [5:0]
,output reg signed [coef_width-1 :0] ab_pow5_re [5:0]
,output reg signed [coef_width-1 :0] ab_pow5_im [5:0]
,output reg signed [coef_width-1 :0] ab_pow6_re [5:0]
,output reg signed [coef_width-1 :0] ab_pow6_im [5:0]
,output reg signed [coef_width-1 :0] ab_pow7_re [5:0]
,output reg signed [coef_width-1 :0] ab_pow7_im [5:0]
,output reg signed [coef_width-1 :0] b_pow8_re [5:0]
,output reg signed [coef_width-1 :0] b_pow8_im [5:0]
);
reg [5:0] vldi_r1;
always @(posedge clk or negedge rstn)begin
if(rstn==1'b0)begin
vldi_r1 <= 'h0;
end
else if(vldi)begin
vldi_r1 <= vldi;
end
end
reg vldi_or_r1;
wire vldi_or = | vldi;
always @(posedge clk or negedge rstn)begin
if(rstn==1'b0)begin
vldi_or_r1 <= 'h0;
end
else begin
vldi_or_r1 <= vldi_or;
end
end
reg signed [data_in_width-1:0] a_re_r1;
reg signed [data_in_width-1:0] a_im_r1;
reg signed [data_in_width-1:0] b_re_r1;
reg signed [data_in_width-1:0] b_im_r1;
genvar i;
generate
for (i = 0; i < 6; i = i + 1) begin
always @(posedge clk or negedge rstn)begin
if(rstn==1'b0)begin
a_re_r1 <= 'h0;
a_im_r1 <= 'h0;
b_re_r1 <= 'h0;
b_im_r1 <= 'h0;
end
else if(vldi[i]) begin
a_re_r1 <= a_re[i];
a_im_r1 <= a_im[i];
b_re_r1 <= b_re[i];
b_im_r1 <= b_im[i];
end
else begin
a_re_r1 <= a_re_r1;
a_im_r1 <= a_im_r1;
b_re_r1 <= b_re_r1;
b_im_r1 <= b_im_r1;
end
end
end
endgenerate
reg en;
reg en_r1;
reg en_r2;
reg [3:0] cnt0;
wire add_cnt0;
wire end_cnt0;
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
cnt0 <= 0;
end
else if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
end
end
assign add_cnt0 = en;
assign end_cnt0 = add_cnt0 && cnt0== 8-1;
wire en_l;
wire en_h;
always @(posedge clk or negedge rstn)begin
if(rstn==1'b0)begin
en <= 0;
end
else if(en_h)begin
en <= 1;
end
else if(en_l)begin
en <= 0;
end
end
assign en_h = vldi_or == 1 && vldi_or_r1 == 0 && cnt0 == 0;
assign en_l = end_cnt0;
always @(posedge clk or negedge rstn)begin
if(rstn==1'b0)begin
en_r1 <= 'h0;
en_r2 <= 'h0;
end
else begin
en_r1 <= en;
en_r2 <= en_r1;
end
end
reg signed [data_in_width-1:0] bin_re;
reg signed [data_in_width-1:0] bin_im;
wire signed [data_in_width-1:0] bout_re;
wire signed [data_in_width-1:0] bout_im;
always @(*)begin
if(en_r1) begin
bin_re <= bout_re;
bin_im <= bout_im;
end
else begin
bin_re <= 32'd2147483647;
bin_im <= 0;
end
end
mult_C
#(
.A_width(data_in_width)
,.B_width(data_in_width)
,.C_width(coef_width)
,.D_width(coef_width)
,.frac_coef_width(frac_coef_width)
)
inst_c1 (
.clk (clk ),
.rstn (rstn ),
.en (en ),
.a (bin_re ),
.b (bin_im ),
.c (b_re_r1 ),
.d (b_im_r1 ),
.Re (bout_re ),
.Im (bout_im )
);
reg [3:1] cnt1;
wire add_cnt1;
wire end_cnt1;
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
cnt1 <= 0;
end
else if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== 7-1;
wire signed [data_in_width-1:0] abo_re;
wire signed [data_in_width-1:0] abo_im;
mult_C
#(
.A_width(data_in_width)
,.B_width(data_in_width)
,.C_width(coef_width)
,.D_width(coef_width)
,.frac_coef_width(frac_coef_width)
)
inst_c2 (
.clk (clk ),
.rstn (rstn ),
.en (en ),
.a (bin_re ),
.b (bin_im ),
.c (a_re_r1 ),
.d (a_im_r1 ),
.Re (abo_re ),
.Im (abo_im )
);
generate
for (i = 0; i < 6; i = i + 1) begin
always @(posedge clk or negedge rstn)begin
if(rstn==1'b0)begin
ao_re[i] <= 0;
ao_im[i] <= 0;
ab_re[i] <= 0;
ab_im[i] <= 0;
abb_re[i] <= 0;
abb_im[i] <= 0;
ab_pow3_re[i] <= 0;
ab_pow3_im[i] <= 0;
ab_pow4_re[i] <= 0;
ab_pow4_im[i] <= 0;
ab_pow5_re[i] <= 0;
ab_pow5_im[i] <= 0;
ab_pow6_re[i] <= 0;
ab_pow6_im[i] <= 0;
ab_pow7_re[i] <= 0;
ab_pow7_im[i] <= 0;
b_pow8_re[i] <= 0;
b_pow8_im[i] <= 0;
end
else if(vldi_r1[i] && en_r1) begin
if(add_cnt0 && cnt0 == 1 && en_r1)begin
ao_re[i] <= abo_re;
ao_im[i] <= abo_im;
end
else if(add_cnt0 && cnt0 == 2 && en_r1)begin
ab_re[i] <= abo_re;
ab_im[i] <= abo_im;
end
else if(add_cnt0 && cnt0 == 3 && en_r1)begin
abb_re[i] <= abo_re;
abb_im[i] <= abo_im;
end
else if(add_cnt0 && cnt0 == 4 && en_r1)begin
ab_pow3_re[i] <= abo_re;
ab_pow3_im[i] <= abo_im;
end
else if(add_cnt0 && cnt0 == 5 && en_r1)begin
ab_pow4_re[i] <= abo_re;
ab_pow4_im[i] <= abo_im;
end
else if(add_cnt0 && cnt0 == 6 && en_r1)begin
ab_pow5_re[i] <= abo_re;
ab_pow5_im[i] <= abo_im;
end
else if(add_cnt0 && cnt0 == 7 && en_r1)begin
ab_pow6_re[i] <= abo_re;
ab_pow6_im[i] <= abo_im;
end
else if(cnt0 == 0 && en_r1)begin
ab_pow7_re[i] <= abo_re;
ab_pow7_im[i] <= abo_im;
b_pow8_re[i] <= bin_re;
b_pow8_im[i] <= bin_im;
end
end
// else begin
// end
end
end
endgenerate
endmodule