Attention
This documentation is a work in progress. Expect to see errors and unfinished things.
banyan_mem Source File
1`timescale 1ns / 1ns
2
3// Single-buffered capture of raw ADC data
4// Hard-code number of ADCs at 8, at least for now
5
6module banyan_mem #(
7 parameter aw=10,
8 parameter dw=16
9) (
10 input clk, // timespec 6.1 ns
11 input [8*dw-1:0] adc_data,
12 input [7:0] banyan_mask, // must be valid in clk domain
13
14 // API in clk domain for controlling acquisition
15 // See additional comments below
16 input reset, // resets pointer and full
17 input run, // set to enable writes to memory; Modulate to take valid adc_data (See TB)
18 output [aw+3-1:0] pointer, // write location
19 output rollover,
20 output full,
21 // Note that writes are pipelined, and after clearing the run
22 // bit, about four more clk cycles are required before the last
23 // data actually shows up in RAM and can be read out.
24 // The output status (full, pointer) are all immediately but
25 // provisionally valid, pending completion of the pipelined writes.
26
27 // Peek into the data stream between switch and memory.
28 // Valid in clk domain.
29 output [8*dw-1:0] permuted_data,
30
31 // readout port, separate clock domain
32 // recommend only using this when run is low
33 input ro_clk,
34 input [aw+3-1:0] ro_addr,
35 output [dw-1:0] ro_data,
36 output [dw-1:0] ro_data2
37 // ro_data2 is based on ro_addr xored with 1<<aw
38 // You don't have to use it, but if you have a 32 bit bus, 16-bit ADCs,
39 // and are trying to pack things efficiently, it's yours for the taking.
40);
41
42// We expect banyan_mask to be set by software, and is therefore not
43// time-critical. Other uses should be aware of this extra cycle of latency,
44// motivated by the "long" time needed to count the number of bits set.
45reg [7:0] mask_d=0;
46reg [3:0] bit_cnt=0;
47always @(posedge clk) begin
48 mask_d <= banyan_mask; // time-aligned with bit_cnt and therefore done_mask
49 bit_cnt <= banyan_mask[0] + banyan_mask[1] + banyan_mask[2] + banyan_mask[3]
50 + banyan_mask[4] + banyan_mask[5] + banyan_mask[6] + banyan_mask[7];
51end
52
53// 8 bits set: count to 2^(aw)
54// 4 bits set: count to 2^(aw+1)
55// 2 bits set: count to 2^(aw+2)
56// 1 bit set: count to 2^(aw+3)
57reg [2:0] done_mask;
58always @(*) begin
59 done_mask = 0;
60 if (bit_cnt[1]) done_mask = 4;
61 if (bit_cnt[2]) done_mask = 6;
62 if (bit_cnt[3]) done_mask = 7;
63end
64
65// Simple control logic, put the user in control. Should support
66// options like one-shot fill, or circular roll until fault.
67// Expect logic like
68// if (trig | rollover) run <= trig;
69// assign reset = trig;
70// for a one-shot, or
71// if (reset | fault) run <= reset;
72// for fault capture.
73// No hidden state!
74// No double-buffering/circular readout, sorry; this is meant for
75// wideband snapshotting, where the software can't possibly keep up.
76reg full_r=0;
77reg [aw+2:0] addr_count=0;
78assign rollover = run & &(addr_count|{done_mask,{aw{1'b0}}});
79always @(posedge clk) begin
80 if (run) addr_count <= addr_count+1;
81 if (rollover | reset) addr_count <= 0;
82 if (rollover | reset) full_r <= rollover;
83end
84assign full = full_r;
85assign pointer = addr_count;
86
87// Split and time-align write-side addresses
88wire [2:0] time_state = addr_count[aw+2:aw];
89wire [aw-1:0] wr_addr;
90reg_delay #(.dw(aw), .len(4)) addr_pipe(.clk(clk), .reset(1'b0), .gate(1'b1),
91 .din(addr_count[aw-1:0]), .dout(wr_addr));
92wire run_d;
93reg_delay #(.dw(1), .len(3)) run_pipe(.clk(clk), .reset(1'b0), .gate(1'b1),
94 .din(run), .dout(run_d));
95
96// Banyan switch itself
97wire [7:0] mask_out;
98wire [dw*8-1:0] banyan_out;
99banyan #(.dw(dw), .np(8), .rl(3)) banyan(.clk(clk),
100 .time_state(time_state), .mask_in(mask_d), .data_in(adc_data),
101 .mask_out(mask_out), .data_out(banyan_out));
102assign permuted_data = banyan_out;
103
104// A new value propagates to mask_out 3 cycles after time_state changes,
105// compared to 4 for the data in banyan_out
106reg [7:0] mask_out_d=0;
107always @(posedge clk) mask_out_d <= mask_out & {8{run_d}};
108
109// Bank of 8 RAM, pretty simple
110wire [8*dw-1:0] ram_out;
111genvar ix;
112generate for (ix=0; ix<8; ix=ix+1) begin: ram_bank
113 dpram #(.dw(dw), .aw(aw)) ram(.clka(clk), .clkb(ro_clk),
114 .dina( banyan_out[(ix+1)*dw-1 -: dw]), .addra(wr_addr), .wena(mask_out_d[ix]),
115 .doutb( ram_out[(ix+1)*dw-1 -: dw]), .addrb(ro_addr[aw-1:0])
116 );
117end endgenerate
118
119// Second stage of readout decoding is one cycle delayed from the RAM addressing
120reg [2:0] stage2_addr=0;
121always @(posedge ro_clk) stage2_addr <= ro_addr[aw+3-1:aw];
122assign ro_data = ram_out[((stage2_addr )+1)*dw-1 -: dw];
123assign ro_data2 = ram_out[((stage2_addr ^ 3'b1)+1)*dw-1 -: dw];
124// So ro_data* are one cycle (plus some combinatorial time) delayed from the address provided
125// Reads are purely passive, no side effects, hence no read-enable control is provided
126
127endmodule