Attention

This documentation is a work in progress. Expect to see errors and unfinished things.

cic_wave_recorder Source File

  1`timescale 1ns / 1ns
  2
  3/* CIC Wave Recorder
  4   Generic waveform recording system comprised of:
  5   - Multichannel CIC filter with runtime selectable base sample rate and waveform
  6     sampling rate (cc_samp_per)
  7   - Double-buffered circular buffer that can be read through a local bus interface
  8
  9         +------------------------+
 10         |  +-------+    +------+ |
 11 in[0]+----->       |    |      <---+ rd_addr/stb
 12         |  |  CIC  |    | CIRC | |
 13 in[1]+----->       +----> BUF  | |
 14         |  |MULTICH|    |SERIAL+---> d_out
 15 in[N]+----->       |    |      | |
 16         |  +---^---+    +---^--+ |
 17         |      |            |    |
 18         +------------------------+
 19                |            |
 20     cic_sample +            + cc_sample
 21*/
 22
 23module cic_wave_recorder #(
 24   parameter n_chan=12,
 25
 26   // DI parameters
 27   parameter di_dwi=16,       // data width
 28   parameter di_rwi=32,       // result width
 29                              // Difference between above two widths should be N*log2 of the maximum number
 30                              // of samples per CIC sample, where N=2 is the order of the CIC filter.
 31   parameter di_noise_bits=4, // Number of noise bits to discard at the output of Double Integrator.
 32                              // This depends on the SNR of the inputs and the CIC sample rate
 33   // CCFILT parameters
 34   parameter cc_outw=20,      // CCFilt output width; Must be 20 if using half-band filter
 35   parameter cc_halfband=1,
 36   parameter cc_use_delay=0,  // Match pipeline length of filt_halfband=1
 37   parameter cc_shift_base=0, // Bits to discard from previous acc step
 38   parameter cc_shift_wi=4,
 39
 40
 41   // Circular Buffer parameters
 42   parameter buf_dw=16,       // If buf_dw < cc_outw, lsb are dropped
 43                              // If buf_dw > cc_outw, msbs are zero-filled
 44   parameter buf_aw=13,
 45   parameter lsb_mask=1,      // LSB of channel mask is CH0
 46   parameter buf_stat_w=16,
 47   parameter buf_auto_flip=1  // auto_flip=1: Double buffers will be flipped when
 48                              //              last read address is reached
 49                              // auto_flip=0: Buffers must be explicitly flipped by
 50                              //              using stb_out as a pulse and not a strobe
 51) (
 52   input                      iclk,
 53   input                      reset,
 54   input                      stb_in,          // Strobe signal for input samples
 55   input [n_chan*di_dwi-1:0]  d_in,            // Flattened array of unprocessed data streams. CH0 in LSBs
 56   input                      cic_sample,      // CIC base sampling signal
 57
 58   // Post-integrator conveyor belt tap
 59   output                      di_stb_out,
 60   output [di_rwi-1:0]         di_sr_out,
 61
 62   // CC Filter controls
 63   input                      cc_sample,       // CCFilt sampling signal
 64   input [cc_shift_wi-1:0]    cc_shift,        // controls scaling of filter result
 65
 66   // Channel selector controls
 67   input [n_chan-1:0]         chan_mask,       // Bitmask of channels to record
 68
 69   // Selected waveform data in iclk domain
 70   output                     wave_gate_out,
 71   output                     wave_dval_out,
 72   output                     [buf_dw-1:0] wave_data_out,
 73
 74   // Circular Buffer control and status
 75   input                      oclk,
 76   input                      buf_write,       // Level-signal to enable writing into buffer
 77   output                     buf_sync,        // single-cycle when buffer starts/ends
 78   output                     buf_transferred, // single-cycle when a buffer has been
 79                                               // handed over for reading;
 80                                               // one cycle delayed from buf_sync
 81   input                      buf_stop,        // single-cycle - interrupts cbuf writing
 82   output [buf_stat_w-1:0]    buf_count,
 83   output [buf_aw-1:0]        buf_stat2,       // includes fault bit
 84   output [buf_stat_w-1:0]    buf_stat,        // includes fault bit, and (if set) the last valid location
 85   output [buf_aw+4:0]        debug_stat,      // {stb_in, boundary, btest, wbank, rbank, wr_addr}
 86
 87   // Circular Buffer data readout
 88   input                      buf_stb,
 89   output                     buf_enable,
 90   input  [buf_aw-1:0]        buf_read_addr,   // nominally 8192 locations
 91   output [buf_dw-1:0]        buf_d_out
 92);
 93
 94   // ------
 95   // CIC Filter
 96   // ------
 97   wire cic_stb_out;
 98   wire [cc_outw-1:0] cic_sr_out;
 99
100   cic_multichannel #(
101      .n_chan        (n_chan),
102      .di_dwi        (di_dwi),
103      .di_rwi        (di_rwi),
104      .di_noise_bits (di_noise_bits),
105      .cc_outw       (cc_outw),
106      .cc_halfband   (cc_halfband),
107      .cc_use_delay  (cc_use_delay),
108      .cc_shift_base (cc_shift_base),
109      .cc_shift_wi   (cc_shift_wi))
110   i_cic_multichannel
111   (
112      .clk           (iclk),
113      .reset         (reset),
114      .stb_in        (stb_in),
115      .d_in          (d_in),
116      .cic_sample    (cic_sample),
117
118      .cc_sample     (cc_sample),
119      .cc_shift      (cc_shift),
120
121      .di_stb_out    (di_stb_out),
122      .di_sr_out     (di_sr_out),
123
124      .cc_stb_out    (cic_stb_out),
125      .cc_sr_out     (cic_sr_out)
126   );
127
128   // ------
129   // Double-buffered circular buffer
130   // ------
131
132   wire [buf_dw-1:0] wave_data_i;
133
134   // Resize output of CIC filter so it can be stored in circle_buf
135   generate
136      if (cc_outw > buf_dw) begin: g_wave_data_resize
137         assign wave_data_i = cic_sr_out[cc_outw-1:(cc_outw-buf_dw)]; // Drop lsbs
138      end else if (cc_outw < buf_dw) begin: g_wave_data_pad
139         assign wave_data_i = {{(buf_dw-cc_outw){1'b0}}, cic_sr_out}; // Zero extend
140      end else begin: g_wave_data_direct
141         assign wave_data_i = cic_sr_out;
142      end
143   endgenerate
144
145   // Avoid partial strobes/bursts when using buf_write
146   // Assume strobes are well formed (asserted in fchan_subset)
147   // Count beats in case there's no separation between bursts
148   reg [4:0] chan_stb_cnt=0;
149   reg wr_gated_r=0;
150
151   wire wr_gated = (chan_stb_cnt==0 && !buf_write);
152
153   always @(posedge iclk) begin
154      if (cic_stb_out) begin
155         chan_stb_cnt <= chan_stb_cnt + 1;
156
157         if (wr_gated) wr_gated_r <= 1;
158      end
159
160      if (chan_stb_cnt == n_chan-1) begin
161         chan_stb_cnt <= 0;
162         wr_gated_r <= 0;
163      end
164   end
165
166   circle_buf_serial #(
167      .n_chan        (n_chan),
168      .lsb_mask      (lsb_mask),
169      .buf_aw        (buf_aw),
170      .buf_dw        (buf_dw),
171      .buf_stat_w    (buf_stat_w),
172      .buf_auto_flip (buf_auto_flip))
173   i_circle_buf_serial (
174      .iclk            (iclk),
175      .reset           (reset),
176      .sr_in           (wave_data_i),
177      .sr_stb          (cic_stb_out & (~wr_gated & ~wr_gated_r)),
178      .chan_mask       (chan_mask),
179      .wave_data       (wave_data_out),
180      .wave_dval       (wave_dval_out),
181      .wave_gate       (wave_gate_out),
182      .oclk            (oclk),
183      .buf_sync        (buf_sync),
184      .buf_transferred (buf_transferred),
185      .buf_stop        (buf_stop),
186      .buf_count       (buf_count),
187      .buf_stat2       (buf_stat2),
188      .buf_stat        (buf_stat),
189      .debug_stat      (debug_stat),
190      .stb_out         (buf_stb),
191      .enable          (buf_enable),
192      .read_addr       (buf_read_addr),
193      .d_out           (buf_d_out)
194   );
195
196endmodule