OpenCores
URL https://opencores.org/ocsvn/cic_core_2/cic_core_2/trunk

Subversion Repositories cic_core_2

[/] [cic_core_2/] [trunk/] [rtl/] [verilog/] [cic_d.sv] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 Juzujka
module cic_d
2
/*********************************************************************************************/
3
#(
4
        parameter INP_DW = 18,                  ///< input data width
5
        parameter OUT_DW = 18,                  ///< output data width
6
        parameter CIC_R = 100,                  ///< decimation ratio
7
        parameter CIC_N = 7,                    ///< number of stages
8
        parameter CIC_M = 1,                    ///< delay in comb
9
        parameter SMALL_FOOTPRINT = 1   ///< reduced registers usage, f_clk / (f_samp/CIC_R)  > CIC_N required
10
)
11
/*********************************************************************************************/
12
(
13 9 Juzujka
        input                                                           clk,                    ///< input clock
14
        input                                                           reset_n,                ///< input reset
15
        input                                                           clear,                  ///< input clear integrator, set accumulator to 0
16
        input   wire    signed [INP_DW-1:0]     inp_samp_data,  ///< input data
17
        input                                                           inp_samp_str,   ///< input data ready strobe
18
        output  wire    signed [OUT_DW-1:0]     out_samp_data,  ///< output data
19
        output                                                          out_samp_str    ///< output data ready strobe
20 7 Juzujka
);
21
/*********************************************************************************************/
22
`include "cic_functions.vh"
23
/*********************************************************************************************/
24
localparam      B_max = clog2_l((CIC_R * CIC_M) ** CIC_N) + INP_DW - 1;
25
/*********************************************************************************************/
26
genvar  i;
27
generate
28
        for (i = 0; i < CIC_N; i = i + 1) begin : int_stage
29 9 Juzujka
                localparam B_jm1        = B_calc(i    , CIC_N, CIC_R, CIC_M, INP_DW, OUT_DW);   ///< the number of bits to prune in previous stage
30
                localparam B_j          = B_calc(i + 1, CIC_N, CIC_R, CIC_M, INP_DW, OUT_DW);   ///< the number of bits to prune in current stage
31
                localparam idw_cur = B_max - B_jm1 + 1;         ///< data width on the input
32
                localparam odw_cur = B_max - B_j   + 1;         ///< data width on the output
33
                wire signed [idw_cur - 1 : 0] int_in;           ///< input data bus
34
                if ( i == 0 )   assign int_in = inp_samp_data;                          ///< if it is the first stage, then takes data from input of CIC filter
35
                        else            assign int_in = int_stage[i - 1].int_out;       ///< otherwise, takes data from the previous stage of the filter
36 7 Juzujka
                wire signed [odw_cur - 1 : 0] int_out;
37
                integrator #(
38
                                idw_cur,
39 9 Juzujka
                                odw_cur
40 7 Juzujka
                                )
41
                        int_inst(
42
                                .clk                    (clk),
43
                                .reset_n                (reset_n),
44
                                .clear                  (clear) ,
45
                                .inp_samp_data  (int_in),
46
                                .inp_samp_str   (inp_samp_str),
47 9 Juzujka
                                .out_samp_data  (int_out)
48 7 Juzujka
                                );
49
                initial begin
50
                        //$display("i:%d integ idw=%2d odw=%2d  B(%2d, %3d, %2d, %2d, %2d, %2d)=%2d, Bj-1=%2d, F_sq=%8d", i, idw_cur, odw_cur, i + 1, CIC_R, CIC_M, CIC_N, INP_DW, OUT_DW, B_j, B_jm1, F_sq_j);
51
                        $display("i:%d integ idw=%d ", i, idw_cur);
52
                end
53
        end
54
endgenerate
55
/*********************************************************************************************/
56 9 Juzujka
/// downsampler takes data from m-th stage
57
localparam B_m = B_calc(CIC_N, CIC_N, CIC_R, CIC_M, INP_DW, OUT_DW);    ///< bits to prune on the m-th stage
58
localparam ds_dw = B_max - B_m + 1;                                                                             ///< data width of the downsampler
59 7 Juzujka
wire    signed [ds_dw - 1 : 0]  ds_out_samp_data;
60
wire                                                    ds_out_samp_str;
61
/*********************************************************************************************/
62
initial begin
63
        //$display("i downsamp dw %d , int_stage[%2d].dw_out = %2d", ds_dw, CIC_N - 1, int_stage[CIC_N - 1].odw_cur);
64
        $display("i downsamp dw %d", ds_dw);
65
end
66
downsampler #(
67
                .DATA_WIDTH_INP (ds_dw),
68
                .CIC_R                  (CIC_R)
69
        )
70
        downsampler_inst
71
        (
72
                .clk                    (clk),
73
                .reset_n                (reset_n),
74
                .clear                  (clear),
75
                .inp_samp_data  (int_stage[CIC_N - 1].int_out),
76
                .inp_samp_str   (inp_samp_str),
77
                .out_samp_data  (ds_out_samp_data),
78
                .out_samp_str   (ds_out_samp_str)
79
        );
80
/*********************************************************************************************/
81
genvar  j;
82
wire comb_chain_out_str;
83
reg     [CIC_N : 0]     comb_inp_str_d;
84
generate
85
        wire summ_rdy_str;
86 9 Juzujka
        if (SMALL_FOOTPRINT != 0) begin ///< generate comb for small footprint
87
                always @(negedge reset_n or posedge clk)        ///< shift register for strobe from datasampler, used to latch data from comb at N'th clock after downsamplers strobe
88 7 Juzujka
                        if              (~reset_n)      comb_inp_str_d <= '0;
89
                        else if (clear)         comb_inp_str_d <= '0;
90
                        else                            comb_inp_str_d <= {comb_inp_str_d[CIC_N - 1 : 0], ds_out_samp_str};
91
        end
92
 
93
        if (SMALL_FOOTPRINT == 0)       assign summ_rdy_str = '0;
94
        else                                            assign summ_rdy_str = comb_inp_str_d[CIC_N];
95
 
96
 
97
        for (j = 0; j < CIC_N; j = j + 1) begin : comb_stage
98
                localparam B_m_j_m1             =    B_calc(CIC_N + j    ,      CIC_N, CIC_R, CIC_M, INP_DW, OUT_DW);
99
                localparam B_m_j                =    B_calc(CIC_N + j + 1,      CIC_N, CIC_R, CIC_M, INP_DW, OUT_DW);
100
                localparam idw_cur = B_max - B_m_j_m1 + 1;
101
                localparam odw_cur = B_max - B_m_j + 1;
102
                wire signed [idw_cur - 1 : 0] comb_in;
103
                wire signed [idw_cur - 1 : 0] comb_inst_out;
104
                wire signed [odw_cur - 1 : 0] comb_out;
105
                wire comb_dv;
106
                if (j == 0)     assign comb_in = ds_out_samp_data;
107
                        else    assign comb_in = comb_stage[j - 1].comb_out;
108
                assign comb_out = comb_inst_out[idw_cur - 1 -: odw_cur];
109
                comb #(
110
                                .SAMP_WIDTH             (idw_cur),
111
                                .CIC_M                  (CIC_M),
112
                                .SMALL_FOOTPRINT(SMALL_FOOTPRINT)
113
                        )
114
                        comb_inst(
115
                                .clk                    (clk),
116
                                .reset_n                (reset_n),
117
                                .clear                  (clear),
118
                                .samp_inp_str   (ds_out_samp_str),
119
                                .samp_inp_data  (comb_in),
120
                                .summ_rdy_str   (summ_rdy_str),
121
                                .samp_out_str   (comb_dv),
122
                                .samp_out_data  (comb_inst_out)
123
                                );
124
                if (SMALL_FOOTPRINT == 0)       assign comb_chain_out_str = comb_stage[CIC_N - 1].comb_dv;
125
                else                                            assign comb_chain_out_str = comb_inp_str_d[CIC_N - 1];
126
                initial begin
127 9 Juzujka
                        //$display("i:%d  comb idw=%2d odw=%2d  B(%2d, %3d, %2d, %2d, %2d, %2d)=%2d", j, idw_cur, odw_cur, CIC_N + j + 1, CIC_R, CIC_M, CIC_N, INP_DW, OUT_DW, B_m_j);
128 7 Juzujka
                        //if (j != 0) $display("odw_prev=%2d, comb_stage[j - 1].odw_cur=%2d", odw_prev, comb_stage[j - 1].odw_cur);
129
                        $display("i:%d  comb idw=%d", j, idw_cur);
130
                end
131
        end
132
endgenerate
133
/*********************************************************************************************/
134
localparam dw_out = B_max - B_calc(2 * CIC_N, CIC_N, CIC_R, CIC_M, INP_DW, OUT_DW) + 1;
135
reg             signed [OUT_DW-1:0]     comb_out_samp_data_reg;
136
reg                                                     comb_out_samp_str_reg;
137
 
138
always @(negedge reset_n or posedge clk)
139
begin
140
        if              (~reset_n)                                      comb_out_samp_data_reg <= '0;
141
        else if (comb_chain_out_str)            comb_out_samp_data_reg <= comb_stage[CIC_N - 1].comb_out[dw_out - 1 -: OUT_DW];
142
end
143
 
144
always @(negedge reset_n or posedge clk)
145
        if              (~reset_n)                                      comb_out_samp_str_reg <= '0;
146
        else if (clear)                                         comb_out_samp_str_reg <= '0;
147
        else                                                            comb_out_samp_str_reg <= comb_chain_out_str;
148
 
149
assign out_samp_data    = comb_out_samp_data_reg;
150
assign out_samp_str             = comb_out_samp_str_reg;
151
/*********************************************************************************************/
152
task print_parameters_nice;
153
        integer tot_registers;
154
        integer j;
155
        integer B_2Np1;
156
        integer dw_j;
157
        integer B_j;
158
        reg [127:0] h_f0_pre;
159
        integer log2_h_f0_pre;
160
        integer h_f0_pre_limit_prec;
161
        integer h_f0_pre_divider;
162
        integer h_f0_divider_exp;
163
        integer h_f0_x_mul;
164
        integer x_multiplier;
165
        reg [127:0] F_sq_curr;
166
        x_multiplier = 100000;
167
        B_2Np1 = B_max - dw_out + 1;
168
        h_f0_pre = (CIC_R*CIC_M)**CIC_N;
169
        h_f0_divider_exp = (B_2Np1 + 1);
170
        h_f0_pre_limit_prec = 30;
171
        log2_h_f0_pre = clog2_l(h_f0_pre);
172
        if (log2_h_f0_pre > h_f0_pre_limit_prec) begin
173
                //$display(" log2_h_f0_pre = %2d, lim %2d", log2_h_f0_pre, h_f0_pre_limit_prec);
174
                h_f0_pre_divider = log2_h_f0_pre - h_f0_pre_limit_prec;
175
                //$display(" h_f0_pre_divider = %2d", h_f0_pre_divider);
176
                h_f0_pre = h_f0_pre >> h_f0_pre_divider;
177
                h_f0_divider_exp = h_f0_divider_exp - h_f0_pre_divider;
178
                //$display(" log2_h_f0_pre limited = %2d, divider_exp limited %2d", log2_h_f0_pre, h_f0_divider_exp);
179
                h_f0_x_mul = x_multiplier * h_f0_pre / 2**(h_f0_divider_exp);
180
        end
181
        else begin
182
                h_f0_x_mul = x_multiplier * h_f0_pre / 2**(B_2Np1 + 1);
183
        end
184
        $display("CIC inp_dw   %d", INP_DW);
185
        $display("CIC out_dw   %d", OUT_DW);
186
        $display("CIC B_max    %d", B_max);
187
        $display("CIC B_out    %d", dw_out);
188
        $display("CIC B_2Np1   %d", B_2Np1);
189
        $display("CIC h(f=0)   %1d.%1d", h_f0_x_mul / x_multiplier, h_f0_x_mul % x_multiplier);
190
        $display(" clog2_l((r*m)**n)  %d", clog2_l((CIC_R*CIC_M)**CIC_N));
191
        tot_registers = 0;
192
        for (j = 1; j < 2 * CIC_N + 2; j = j + 1) begin : check_Bj
193
                F_sq_curr = F_sq_calc(j, CIC_N, CIC_R, CIC_M);
194
                B_j = B_calc(j, CIC_N, CIC_R, CIC_M, INP_DW, OUT_DW);
195
                dw_j = B_max - B_j + 1;
196
                tot_registers = tot_registers + dw_j;
197
        end
198
        $display("CIC total registers %2d", tot_registers);
199
endtask
200
 
201
 
202
generate
203
        initial begin : initial_print_parameters
204
        if (1) begin
205
                print_parameters_nice;
206
        end
207
 
208
        end
209
        if (0) begin
210
                for (j = 0; j < CIC_N; j = j + 1) begin : print_int_stage
211
                        initial begin
212
                                $display("CIC integrator j:%2d B %2d B_ jm1 %2d odw_prev %2d in_dw %3d out_dw %3d data_width_pass %3d", j + 1, int_stage[j].B_j, int_stage[j].B_jm1, int_stage[j].odw_prev, int_stage[j].idw_cur, int_stage[j].odw_cur, 0);
213
                        end
214
                end
215
                initial begin
216
                                $display("CIC downsampler     B %2d                                  ds_dw %3d", B_m, ds_dw);
217
                end
218
                for (j = 0; j < CIC_N; j = j + 1) begin : print_comb_stage
219
                        initial begin
220
                                $display("CIC comb       j:%2d B %2d B_mjm1 %2d             in_dw %3d out_dw %3d", j, comb_stage[j].B_m_j, comb_stage[j].B_m_j_m1, comb_stage[j].idw_cur, comb_stage[j].odw_cur);
221
                        end
222
                end
223
                initial begin
224
                        $display("CIC out odw %3d", OUT_DW);
225
                end
226
        end
227
endgenerate
228
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.