1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
module chan_fifo_reader
( reset, tx_clock, tx_strobe, adc_time, samples_format,
fifodata, pkt_waiting, rdreq, skip, tx_q, tx_i,
underrun, tx_empty, debug, rssi, threshhold, rssi_wait) ;
input wire reset ;
input wire tx_clock ;
input wire tx_strobe ; //signal to output tx_i and tx_q
input wire [31:0] adc_time ; //current time
input wire [3:0] samples_format ;// not useful at this point
input wire [31:0] fifodata ; //the data input
input wire pkt_waiting ; //signal the next packet is ready
output reg rdreq ; //actually an ack to the current fifodata
output reg skip ; //finish reading current packet
output reg [15:0] tx_q ; //top 16 bit output of fifodata
output reg [15:0] tx_i ; //bottom 16 bit output of fifodata
output reg underrun ;
output reg tx_empty ; //cause 0 to be the output
input wire [31:0] rssi;
input wire [31:0] threshhold;
input wire [31:0] rssi_wait;
output wire [14:0] debug;
assign debug = {reader_state, trash, skip, timestamp[4:0], adc_time[4:0]};
// Should not be needed if adc clock rate < tx clock rate
// Used only to debug
`define JITTER 5
//Samples format
// 16 bits interleaved complex samples
`define QI16 4'b0
// States
parameter IDLE = 3'd0;
parameter HEADER = 3'd1;
parameter TIMESTAMP = 3'd2;
parameter WAIT = 3'd3;
parameter WAITSTROBE = 3'd4;
parameter SEND = 3'd5;
// Header format
`define PAYLOAD 8:2
`define ENDOFBURST 27
`define STARTOFBURST 28
`define RSSI_FLAG 26
/* State registers */
reg [2:0] reader_state;
/* Local registers */
reg [6:0] payload_len;
reg [6:0] read_len;
reg [31:0] timestamp;
reg burst;
reg trash;
reg rssi_flag;
reg [31:0] time_wait;
always @(posedge tx_clock)
begin
if (reset)
begin
reader_state <= IDLE;
rdreq <= 0;
skip <= 0;
underrun <= 0;
burst <= 0;
tx_empty <= 1;
tx_q <= 0;
tx_i <= 0;
trash <= 0;
rssi_flag <= 0;
time_wait <= 0;
end
else
begin
case (reader_state)
IDLE:
begin
/*
* reset all the variables and wait for a tx_strobe
* it is assumed that the ram connected to this fifo_reader
* is a short hand fifo meaning that the header to the next packet
* is already available to this fifo_reader when pkt_waiting is on
*/
skip <=0;
time_wait <= 0;
if (pkt_waiting == 1)
begin
reader_state <= HEADER;
rdreq <= 1;
underrun <= 0;
end
if (burst == 1 && pkt_waiting == 0)
underrun <= 1;
if (tx_strobe == 1)
tx_empty <= 1 ;
end
/* Process header */
HEADER:
begin
if (tx_strobe == 1)
tx_empty <= 1 ;
rssi_flag <= fifodata[`RSSI_FLAG]&fifodata[`STARTOFBURST];
//Check Start/End burst flag
if (fifodata[`STARTOFBURST] == 1
&& fifodata[`ENDOFBURST] == 1)
burst <= 0;
else if (fifodata[`STARTOFBURST] == 1)
burst <= 1;
else if (fifodata[`ENDOFBURST] == 1)
burst <= 0;
if (trash == 1 && fifodata[`STARTOFBURST] == 0)
begin
skip <= 1;
reader_state <= IDLE;
rdreq <= 0;
end
else
begin
payload_len <= fifodata[`PAYLOAD] ;
read_len <= 0;
rdreq <= 1;
reader_state <= TIMESTAMP;
end
end
TIMESTAMP:
begin
timestamp <= fifodata;
reader_state <= WAIT;
if (tx_strobe == 1)
tx_empty <= 1 ;
rdreq <= 0;
end
// Decide if we wait, send or discard samples
WAIT:
begin
if (tx_strobe == 1)
tx_empty <= 1 ;
time_wait <= time_wait + 32'd1;
// Outdated
if ((timestamp < adc_time) ||
(time_wait >= rssi_wait && rssi_wait != 0 && rssi_flag))
begin
trash <= 1;
reader_state <= IDLE;
skip <= 1;
end
// Let's send it
else if ((timestamp <= adc_time + `JITTER
&& timestamp > adc_time)
|| timestamp == 32'hFFFFFFFF)
begin
if (rssi <= threshhold || rssi_flag == 0)
begin
trash <= 0;
reader_state <= WAITSTROBE;
end
else
reader_state <= WAIT;
end
else
reader_state <= WAIT;
// Wait a little bit more
//else if (timestamp > adc_time + `JITTER)
// reader_state <= WAIT;
end
// Wait for the transmit chain to be ready
WAITSTROBE:
begin
// If end of payload...
if (read_len == payload_len)
begin
reader_state <= IDLE;
skip <= 1;
if (tx_strobe == 1)
tx_empty <= 1 ;
end
else if (tx_strobe == 1)
begin
reader_state <= SEND;
rdreq <= 1;
end
end
// Send the samples to the tx_chain
SEND:
begin
reader_state <= WAITSTROBE;
read_len <= read_len + 7'd1;
tx_empty <= 0;
rdreq <= 0;
case(samples_format)
`QI16:
begin
tx_i <= fifodata[15:0];
tx_q <= fifodata[31:16];
end
// Assume 16 bits complex samples by default
default:
begin
tx_i <= fifodata[15:0];
tx_q <= fifodata[31:16];
end
endcase
end
default:
begin
//error handling
reader_state <= IDLE;
end
endcase
end
end
endmodule
|