Attention
This documentation is a work in progress. Expect to see errors and unfinished things.
circle_buf_serial Source File
1`timescale 1ns / 1ns
2
3/** CIRCLE_BUF_SERIAL **
4 Double-buffered circular buffer wrapper with channel selector.
5 This module takes a conveyor belt carrying multiple channels as an input
6 and writes the channels selected by chan_mask into the Circular Buffer.
7 Circular buffer can be read out at a different clock rate through the local bus.
8
9 +------------------------+
10 | +-----+ +--------+ |
11 sr_in+----> | | <-----+ rd_addr/val
12 | |fchan+----> Circle | |
13 mask +----> sel | | Buf | |
14 | | | | +-----> d_out
15 | +-----+ +--------+ |
16 +------------------------+
17*/
18
19module circle_buf_serial #(
20 // Channel selector parameters
21 parameter n_chan=12,
22 parameter lsb_mask=0, // lsb_mask=0: chan_mask is LEFT-to-RIGHT; MSB=CH0
23 // lsb_mask=1: chan_mask is RIGHT-to-LEFT; LSB=CH0
24
25 // Circular Buffer parameters
26 parameter buf_dw=16,
27 parameter buf_aw=13,
28 parameter buf_stat_w=16,
29 parameter buf_auto_flip=1 // auto_flip=1: Double buffers will be flipped when
30 // last read address is reached
31 // auto_flip=0: Buffers must be explicitly flipped by
32 // using stb_out as a pulse and not a strobe
33) (
34 // Incoming stream
35 input iclk,
36 input reset,
37 input [buf_dw-1:0] sr_in, // Conveyor belt carrying n_chan channels
38 input sr_stb,
39
40 // Channel selector controls
41 input [n_chan-1:0] chan_mask, // Bitmask of channels to record. See lsb_mask parameter
42 // Selected waveform data in iclk domain
43 output wave_gate,
44 output wave_dval,
45 output [buf_dw-1:0] wave_data,
46
47 // Circular Buffer control and statistics
48 // all of these signals are also in the iclk domain
49 output buf_sync, // single-cycle when buffer starts/ends
50 output buf_transferred, // single-cycle when a buffer has been
51 // handed over for reading;
52 // one cycle delayed from buf_sync
53 input buf_stop, // single-cycle - interrupts cbuf writing
54 output [buf_stat_w-1:0] buf_count,
55 output [buf_aw-1:0] buf_stat2, // includes fault bit
56 output [buf_stat_w-1:0] buf_stat, // includes fault bit, and (if set) the last valid location
57 output [buf_aw+4:0] debug_stat, // {stb_in, boundary, btest, wbank, rbank, wr_addr}
58
59 // Circular Buffer data readout
60 input oclk,
61 input stb_out,
62 output enable,
63 input [buf_aw-1:0] read_addr, // nominally 8192 locations
64 output [buf_dw-1:0] d_out
65);
66
67 // ------
68 // Interleaved channel selector
69 // ------
70 wire fchan_time_error; // For debug only - will pulse if gate-per-trigger ratio is broken
71 wire wave_trig;
72 assign wave_dval = ~wave_trig;
73
74 fchan_subset #(
75 .KEEP_OLD (lsb_mask),
76 .a_dw (buf_dw),
77 .o_dw (buf_dw),
78 .len (n_chan))
79 i_fchan_subset (
80 .clk (iclk),
81 .reset (reset),
82 .keep (chan_mask),
83 .a_data (sr_in),
84 .a_gate (sr_stb),
85 .a_trig (~sr_stb),
86 .o_data (wave_data),
87 .o_gate (wave_gate),
88 .o_trig (wave_trig),
89 .time_err (fchan_time_error)
90 );
91
92`ifdef SIMULATE
93 always @(negedge iclk) if (fchan_time_error) begin
94 $display("ERROR: Gate-per-Trigger ratio violated in fchan_selector.");
95 $finish;
96 end
97 // Output file (if any) for dumping the results
98 integer out_file;
99 reg [255:0] out_file_name;
100 wire signed [buf_dw/2-1:0] wave_i = wave_data[buf_dw-1:buf_dw/2];
101 wire signed [buf_dw/2-1:0] wave_q = wave_data[buf_dw/2-1:0];
102 reg needs_cr=0;
103 initial begin
104 out_file = 0;
105 if ($value$plusargs("conveyor_file=%s", out_file_name))
106 out_file = $fopen(out_file_name,"w");
107 end
108 always @(negedge iclk) if (out_file != 0) begin
109 if (wave_trig && needs_cr) begin
110 $fwrite(out_file, "\n");
111 needs_cr <= 0;
112 end
113 if (wave_gate) begin
114 $fwrite(out_file, " %d %d", wave_i, wave_q);
115 needs_cr <= 1;
116 end
117 end
118`endif
119
120 // ------
121 // Double-buffered circular buffer
122 // ------
123
124 circle_buf #(
125 .aw (buf_aw),
126 .dw (buf_dw),
127 .auto_flip (buf_auto_flip))
128 i_circle_buf (
129 .iclk (iclk),
130 .d_in (wave_data),
131 .stb_in (wave_gate),
132 .boundary (wave_trig),
133 .stop (buf_stop),
134 .buf_sync (buf_sync),
135 .buf_transferred (buf_transferred),
136 .oclk (oclk),
137 .enable (enable),
138 .read_addr (read_addr),
139 .d_out (d_out),
140 .stb_out (stb_out),
141 .buf_count (buf_count),
142 .buf_stat (buf_stat),
143 .debug_stat (debug_stat),
144 .buf_stat2 (buf_stat2)
145 );
146
147endmodule