1 |
4 |
jeaander |
//////////////////////////////////////////////////////////////////////
|
2 |
|
|
//// ////
|
3 |
|
|
//// sport_top.v ////
|
4 |
|
|
//// ////
|
5 |
|
|
//// ////
|
6 |
|
|
//// This file is part of the SPORT controller ////
|
7 |
|
|
//// http://www.opencores.org/projects/sport/ ////
|
8 |
|
|
//// ////
|
9 |
|
|
//// ////
|
10 |
|
|
//// Author(s): ////
|
11 |
|
|
//// Jeff Anderson ////
|
12 |
|
|
//// jeaander@opencores.org ////
|
13 |
|
|
//// ////
|
14 |
|
|
//// ////
|
15 |
|
|
//// All additional information is available in the README.txt ////
|
16 |
|
|
//// file. ////
|
17 |
|
|
//// ////
|
18 |
|
|
//////////////////////////////////////////////////////////////////////
|
19 |
|
|
//// ////
|
20 |
|
|
//// Copyright (C) 2014 Authors ////
|
21 |
|
|
//// ////
|
22 |
|
|
//// This source file may be used and distributed without ////
|
23 |
|
|
//// restriction provided that this copyright statement is not ////
|
24 |
|
|
//// removed from the file and that any derivative work contains ////
|
25 |
|
|
//// the original copyright notice and the associated disclaimer. ////
|
26 |
|
|
//// ////
|
27 |
|
|
//// This source file is free software; you can redistribute it ////
|
28 |
|
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
29 |
|
|
//// Public License as published by the Free Software Foundation; ////
|
30 |
|
|
//// either version 2.1 of the License, or (at your option) any ////
|
31 |
|
|
//// later version. ////
|
32 |
|
|
//// ////
|
33 |
|
|
//// This source is distributed in the hope that it will be ////
|
34 |
|
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
35 |
|
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
36 |
|
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
37 |
|
|
//// details. ////
|
38 |
|
|
//// ////
|
39 |
|
|
//// You should have received a copy of the GNU Lesser General ////
|
40 |
|
|
//// Public License along with this source; if not, download it ////
|
41 |
|
|
//// from http://www.opencores.org/lgpl.shtml ////
|
42 |
|
|
//// ////
|
43 |
|
|
//// The SPORT protocol is maintained by Analog Devices, Inc ////
|
44 |
|
|
//// This product has been tested to interoperate with certified ////
|
45 |
|
|
//// devices, but has not been certified itself. This product ////
|
46 |
|
|
//// should be certified through prior to claiming strict ////
|
47 |
|
|
//// adherence to the standard. ////
|
48 |
|
|
//// ////
|
49 |
|
|
//////////////////////////////////////////////////////////////////////
|
50 |
|
|
//
|
51 |
|
|
// Revisions at end of file
|
52 |
|
|
//
|
53 |
|
|
|
54 |
|
|
|
55 |
|
|
// synopsys translate_off
|
56 |
|
|
`include "timescale.v"
|
57 |
|
|
// synopsys translate_on
|
58 |
|
|
`include "sport_defines.v"
|
59 |
|
|
|
60 |
|
|
module sport_top(
|
61 |
|
|
|
62 |
|
|
DTxPRI,
|
63 |
|
|
DTxSEC,
|
64 |
|
|
TSCLKx,
|
65 |
|
|
TFSx,
|
66 |
|
|
DRxPRI,
|
67 |
|
|
DRxSEC,
|
68 |
|
|
RSCLKx,
|
69 |
|
|
RFSx,
|
70 |
|
|
|
71 |
|
|
rx_int,
|
72 |
|
|
rxclk,
|
73 |
|
|
txclk,
|
74 |
|
|
|
75 |
|
|
wb_clk_i,
|
76 |
|
|
wb_rst_i,
|
77 |
|
|
wb_dat_i,
|
78 |
|
|
wb_dat_o,
|
79 |
|
|
wb_cyc_i,
|
80 |
|
|
wb_stb_i,
|
81 |
|
|
wb_we_i,
|
82 |
|
|
wb_adr_i,
|
83 |
|
|
wb_ack_o,
|
84 |
|
|
wb_err_o,
|
85 |
|
|
wb_rty_o
|
86 |
|
|
);
|
87 |
|
|
//to PHY layer
|
88 |
|
|
output DTxPRI;
|
89 |
|
|
output DTxSEC;
|
90 |
|
|
output TSCLKx;
|
91 |
|
|
output TFSx;
|
92 |
|
|
input DRxPRI;
|
93 |
|
|
input DRxSEC;
|
94 |
|
|
output RSCLKx;
|
95 |
|
|
output RFSx;
|
96 |
|
|
|
97 |
|
|
//wishbone interface
|
98 |
|
|
input wb_clk_i;
|
99 |
|
|
input wb_rst_i;
|
100 |
|
|
input [`WB_WIDTH-1:0] wb_dat_i;
|
101 |
|
|
output [`WB_WIDTH-1:0] wb_dat_o;
|
102 |
|
|
input wb_cyc_i;
|
103 |
|
|
input wb_stb_i;
|
104 |
|
|
input wb_we_i;
|
105 |
|
|
input [`WB_ADDR_WIDTH-1:0] wb_adr_i;
|
106 |
|
|
output wb_ack_o;
|
107 |
|
|
output wb_err_o;
|
108 |
|
|
output wb_rty_o;
|
109 |
|
|
|
110 |
|
|
//interrupt signals back to chip
|
111 |
|
|
output rx_int;
|
112 |
|
|
input rxclk;
|
113 |
|
|
input txclk;
|
114 |
|
|
|
115 |
|
|
//intermediate signals
|
116 |
|
|
wire rst;
|
117 |
|
|
reg [`WB_WIDTH:0] data;
|
118 |
|
|
reg [2:0] state, next_state;
|
119 |
|
|
reg [2:0] rxstate, next_rxstate;
|
120 |
|
|
wire clk;
|
121 |
|
|
reg lock_cfg;
|
122 |
|
|
|
123 |
|
|
reg [31:0] rxPri, rxSec;
|
124 |
|
|
|
125 |
|
|
wire [4:0] rxsampleCnt;
|
126 |
|
|
wire [`SPORT_FIFODEPTH-1:0] rxpacketCnt;
|
127 |
|
|
wire [4:0] txsampleCnt;
|
128 |
|
|
wire [`SPORT_FIFODEPTH-1:0] txpacketCnt;
|
129 |
|
|
wire [31:0] word_in;
|
130 |
|
|
wire [31:0] word_out;
|
131 |
|
|
wire rxsecEn;
|
132 |
|
|
wire rxlateFS_earlyFSn;
|
133 |
|
|
wire txsecEn;
|
134 |
|
|
wire txlateFS_earlyFSn;
|
135 |
|
|
wire tx_actHi;
|
136 |
|
|
wire rx_actHi;
|
137 |
|
|
wire msbFirst;
|
138 |
|
|
wire tx_start, rx_start;
|
139 |
|
|
|
140 |
|
|
//registers for clock gating between clock domains
|
141 |
|
|
reg [4:0] rxsampleCnt_rxint;
|
142 |
|
|
reg [`SPORT_FIFODEPTH-1:0] rxpacketCnt_rxint;
|
143 |
|
|
reg [4:0] txsampleCnt_txint;
|
144 |
|
|
reg [`SPORT_FIFODEPTH-1:0] txpacketCnt_txint;
|
145 |
|
|
reg rxsecEn_rxint;
|
146 |
|
|
reg rxlateFS_earlyFSn_rxint;
|
147 |
|
|
reg txsecEn_txint;
|
148 |
|
|
reg txlateFS_earlyFSn_txint;
|
149 |
|
|
reg tx_actHi_txint;
|
150 |
|
|
reg rx_actHi_rxint;
|
151 |
|
|
reg msbFirst_txint;
|
152 |
|
|
reg tx_start_txint, rx_start_rxint;
|
153 |
|
|
reg [4:0] rxsampleCnt_rx;
|
154 |
|
|
reg [`SPORT_FIFODEPTH-1:0] rxpacketCnt_rx;
|
155 |
|
|
reg [4:0] txsampleCnt_tx;
|
156 |
|
|
reg [`SPORT_FIFODEPTH-1:0] txpacketCnt_tx;
|
157 |
|
|
reg rxsecEn_rx;
|
158 |
|
|
reg rxlateFS_earlyFSn_rx;
|
159 |
|
|
reg txsecEn_tx;
|
160 |
|
|
reg txlateFS_earlyFSn_tx;
|
161 |
|
|
reg tx_actHi_tx;
|
162 |
|
|
reg rx_actHi_rx;
|
163 |
|
|
reg msbFirst_tx;
|
164 |
|
|
reg tx_start_tx, rx_start_rx;
|
165 |
|
|
reg rxidle;
|
166 |
|
|
reg rx;
|
167 |
|
|
reg rxFS;
|
168 |
|
|
reg txidle;
|
169 |
|
|
reg tx;
|
170 |
|
|
reg txFS;
|
171 |
|
|
reg [31:0] word_outM, word_outL;
|
172 |
|
|
|
173 |
|
|
reg txfs, rxfs;
|
174 |
|
|
wire [31:0] data_out;
|
175 |
|
|
|
176 |
|
|
/***************************** RX logic **********************************************************/
|
177 |
|
|
assign RSCLKx = rxclk;
|
178 |
|
|
assign RFSx = rx_actHi_rxint? rxFS:~rxFS;
|
179 |
|
|
|
180 |
|
|
//main RX state machine
|
181 |
|
|
always @(posedge rxclk or posedge rst) begin
|
182 |
|
|
if (rst) rxstate <= `RESET;
|
183 |
|
|
else rxstate <= next_rxstate;
|
184 |
|
|
end
|
185 |
|
|
|
186 |
|
|
always @(*) begin
|
187 |
|
|
next_rxstate = `IDLE;
|
188 |
|
|
rxidle = 1'b0;
|
189 |
|
|
rx = 1'b0;
|
190 |
|
|
rxfs = 1'b0;
|
191 |
|
|
case (state)
|
192 |
|
|
`RESET: begin next_rxstate = `IDLE; end
|
193 |
|
|
`IDLE: begin
|
194 |
|
|
rxidle = 1'b1;
|
195 |
|
|
if (rx_start_rxint) next_rxstate = `FS;
|
196 |
|
|
else next_rxstate = `IDLE;
|
197 |
|
|
end
|
198 |
|
|
`FS: begin
|
199 |
|
|
rxfs = 1'b1;
|
200 |
|
|
next_rxstate = `RX;
|
201 |
|
|
end
|
202 |
|
|
`RX: begin
|
203 |
|
|
rx = 1'b1;
|
204 |
|
|
if (rxsampleCnt_rx == rxsampleCnt_rxint) next_rxstate = `IDLE;
|
205 |
|
|
else if (rxpacketCnt_rx == rxpacketCnt_rxint) next_rxstate = `FS;
|
206 |
|
|
else next_rxstate = `RX;
|
207 |
|
|
end
|
208 |
|
|
default: next_rxstate = `IDLE;
|
209 |
|
|
endcase
|
210 |
|
|
end
|
211 |
|
|
|
212 |
|
|
//input shift registers
|
213 |
|
|
always @(posedge rxclk or posedge rst) begin
|
214 |
|
|
if (rst) begin
|
215 |
|
|
rxPri <= 32'h0;
|
216 |
|
|
rxSec <= 32'h0;
|
217 |
|
|
end
|
218 |
|
|
else begin
|
219 |
|
|
rxPri <= {rxPri[30:0],DRxPRI};
|
220 |
|
|
rxSec <= {rxSec[30:0],DRxSEC};
|
221 |
|
|
end
|
222 |
|
|
end
|
223 |
|
|
|
224 |
|
|
//counter for message length
|
225 |
|
|
always @(posedge rxclk or posedge rst) begin
|
226 |
|
|
if (rst) rxsampleCnt_rx <= 5'h0;
|
227 |
|
|
else if (rx) begin
|
228 |
|
|
if (rxsecEn_rxint) rxsampleCnt_rx <= rxsampleCnt_rx+2;
|
229 |
|
|
else rxsampleCnt_rx <= rxsampleCnt_rx+1;
|
230 |
|
|
end
|
231 |
|
|
else rxsampleCnt_rx <= 5'h0;
|
232 |
|
|
end
|
233 |
|
|
|
234 |
|
|
always @(posedge rxclk or posedge rst) begin
|
235 |
|
|
if (rst) rxpacketCnt_rx <= 5'h0;
|
236 |
|
|
else if (rx) begin
|
237 |
|
|
if (rxsecEn_rxint) rxpacketCnt_rx <= rxpacketCnt_rx+2;
|
238 |
|
|
else rxpacketCnt_rx <= rxpacketCnt_rx+1;
|
239 |
|
|
end
|
240 |
|
|
else rxpacketCnt_rx <= 5'h0;
|
241 |
|
|
end
|
242 |
|
|
|
243 |
|
|
//framesync signal
|
244 |
|
|
always @(posedge rxclk or posedge rst) begin
|
245 |
|
|
if (rst) rxFS <= 1'b0;
|
246 |
|
|
else rxFS <= rxlateFS_earlyFSn_rxint? rx : rxfs;
|
247 |
|
|
end
|
248 |
|
|
|
249 |
|
|
/***************************** TX logic **********************************************************/
|
250 |
|
|
assign TSCLKx = txclk;
|
251 |
|
|
assign TFSx = tx_actHi_txint? txFS:~txFS;
|
252 |
|
|
|
253 |
|
|
//main TX state machine
|
254 |
|
|
always @(posedge txclk or posedge rst) begin
|
255 |
|
|
if (rst) state <= `RESET;
|
256 |
|
|
else state <= next_state;
|
257 |
|
|
end
|
258 |
|
|
|
259 |
|
|
always @(*) begin
|
260 |
|
|
next_state = `IDLE;
|
261 |
|
|
txidle = 1'b0;
|
262 |
|
|
tx = 1'b0;
|
263 |
|
|
txfs = 1'b0;
|
264 |
|
|
case (state)
|
265 |
|
|
`RESET: begin next_state = `IDLE; end
|
266 |
|
|
`IDLE: begin
|
267 |
|
|
txidle = 1'b1;
|
268 |
|
|
if (tx_start_txint) next_state = `FS;
|
269 |
|
|
else next_state = `IDLE;
|
270 |
|
|
end
|
271 |
|
|
`FS: begin
|
272 |
|
|
txfs = 1'b1;
|
273 |
|
|
next_state = `TX;
|
274 |
|
|
end
|
275 |
|
|
`TX: begin
|
276 |
|
|
tx = 1'b1;
|
277 |
|
|
if (txsampleCnt_tx == txsampleCnt_txint) next_state = `IDLE;
|
278 |
|
|
else if (txpacketCnt_tx == txpacketCnt_txint) next_state = `FS;
|
279 |
|
|
else next_state = `TX;
|
280 |
|
|
end
|
281 |
|
|
default: next_state = `IDLE;
|
282 |
|
|
endcase
|
283 |
|
|
end
|
284 |
|
|
|
285 |
|
|
//counter for message length
|
286 |
|
|
always @(posedge txclk or posedge rst) begin
|
287 |
|
|
if (rst) txsampleCnt_tx <= 5'h0;
|
288 |
|
|
else if (tx) begin
|
289 |
|
|
if (txsecEn_txint) txsampleCnt_tx <= txsampleCnt_tx+2;
|
290 |
|
|
else txsampleCnt_tx <= txsampleCnt_tx+1;
|
291 |
|
|
end
|
292 |
|
|
else txsampleCnt_tx <= 5'h0;
|
293 |
|
|
end
|
294 |
|
|
|
295 |
|
|
always @(posedge txclk or posedge rst) begin
|
296 |
|
|
if (rst) txpacketCnt_tx <= 5'h0;
|
297 |
|
|
else if (tx) begin
|
298 |
|
|
if (txsecEn_txint) txpacketCnt_tx <= txpacketCnt_tx+2;
|
299 |
|
|
else txpacketCnt_tx <= txpacketCnt_tx+1;
|
300 |
|
|
end
|
301 |
|
|
else txpacketCnt_tx <= 5'h0;
|
302 |
|
|
end
|
303 |
|
|
|
304 |
|
|
//logic for routing output data to ports
|
305 |
|
|
assign DTxPRI = msbFirst? word_outM[31]:word_outL[31];
|
306 |
|
|
assign DTxSEC = txsecEn_tx? (msbFirst? word_outM[16]:word_outL[16]):1'b0;
|
307 |
|
|
|
308 |
|
|
//output word MSB first
|
309 |
|
|
always @(posedge txclk or posedge rst) begin
|
310 |
|
|
if (rst) word_outM <= 32'h0;
|
311 |
|
|
else if (tx) word_outM <= {word_outM[30:0],1'b0};
|
312 |
|
|
else if (txfs) word_outM <= data_out;
|
313 |
|
|
end
|
314 |
|
|
|
315 |
|
|
//output word LSB first
|
316 |
|
|
always @(posedge txclk or posedge rst) begin
|
317 |
|
|
if (rst) word_outL <= 32'h0;
|
318 |
|
|
else if (tx) word_outL <= {word_outL[30:0],1'b0};
|
319 |
|
|
else if (txfs) word_outL <= {data_out[0],data_out[1],data_out[2],data_out[3],data_out[4],data_out[5],data_out[6],data_out[7],
|
320 |
|
|
data_out[8],data_out[9],data_out[10],data_out[11],data_out[12],data_out[13],data_out[14],data_out[15],
|
321 |
|
|
data_out[16],data_out[17],data_out[18],data_out[19],data_out[20],data_out[21],data_out[22],data_out[23],
|
322 |
|
|
data_out[24],data_out[25],data_out[26],data_out[27],data_out[28],data_out[29],data_out[30],data_out[31]};
|
323 |
|
|
end
|
324 |
|
|
|
325 |
|
|
//framesync signal
|
326 |
|
|
always @(posedge txclk or posedge rst) begin
|
327 |
|
|
if (rst) txFS <= 1'b0;
|
328 |
|
|
else txFS <= txlateFS_earlyFSn_txint? tx : txfs;
|
329 |
|
|
end
|
330 |
|
|
|
331 |
|
|
/***************************** input FIFO *******************************************************/
|
332 |
|
|
|
333 |
|
|
fifo_sport datafifowrite(clk,txclk,wb_data_i,data_out,rst,wb_wr_en,wei_rd_en,fullwrite,emptywrite);
|
334 |
|
|
fifo_sport datafiforead(rxclk,clk,wb_data_i,data_o,rst,wb_wr_en,wei_rd_en,fullread,emptyread);
|
335 |
|
|
|
336 |
|
|
|
337 |
|
|
/***************************** WB interface *******************************************************/
|
338 |
|
|
//gate clocks at change in clock domains
|
339 |
|
|
|
340 |
|
|
always @(posedge rxclk or posedge rst) begin
|
341 |
|
|
if (rst) rxsampleCnt_rxint <= 5'h0;
|
342 |
|
|
else rxsampleCnt_rxint <= rxsampleCnt;
|
343 |
|
|
end
|
344 |
|
|
|
345 |
|
|
always @(posedge rxclk or posedge rst) begin
|
346 |
|
|
if (rst) rxpacketCnt_rxint <= `SPORT_FIFODEPTH'h0;
|
347 |
|
|
else rxpacketCnt_rxint <= rxpacketCnt;
|
348 |
|
|
end
|
349 |
|
|
|
350 |
|
|
always @(posedge txclk or posedge rst) begin
|
351 |
|
|
if (rst) txsampleCnt_txint <= 5'h0;
|
352 |
|
|
else txsampleCnt_txint <= txsampleCnt;
|
353 |
|
|
end
|
354 |
|
|
|
355 |
|
|
always @(posedge txclk or posedge rst) begin
|
356 |
|
|
if (rst) txpacketCnt_txint <= `SPORT_FIFODEPTH'h0;
|
357 |
|
|
else txpacketCnt_txint <= txpacketCnt;
|
358 |
|
|
end
|
359 |
|
|
|
360 |
|
|
always @(posedge rxclk or posedge rst) begin
|
361 |
|
|
if (rst) rxsecEn_rxint <= 1'b0;
|
362 |
|
|
else rxsecEn_rxint <= rxsecEn;
|
363 |
|
|
end
|
364 |
|
|
|
365 |
|
|
always @(posedge rxclk or posedge rst) begin
|
366 |
|
|
if (rst) rxlateFS_earlyFSn_rxint <= 1'b0;
|
367 |
|
|
else rxlateFS_earlyFSn_rxint <= rxlateFS_earlyFSn;
|
368 |
|
|
|
369 |
|
|
end
|
370 |
|
|
|
371 |
|
|
always @(posedge txclk or posedge rst) begin
|
372 |
|
|
if (rst) txlateFS_earlyFSn_txint <= 1'b0;
|
373 |
|
|
else txlateFS_earlyFSn_txint <= txlateFS_earlyFSn;
|
374 |
|
|
|
375 |
|
|
end
|
376 |
|
|
|
377 |
|
|
always @(posedge txclk or posedge rst) begin
|
378 |
|
|
if (rst) txsecEn_txint <= 1'b0;
|
379 |
|
|
else txsecEn_txint <= txsecEn;
|
380 |
|
|
end
|
381 |
|
|
|
382 |
|
|
always @(posedge txclk or posedge rst) begin
|
383 |
|
|
if (rst) txlateFS_earlyFSn_txint <= 1'b0;
|
384 |
|
|
else txlateFS_earlyFSn_txint <= txlateFS_earlyFSn;
|
385 |
|
|
end
|
386 |
|
|
|
387 |
|
|
always @(posedge txclk or posedge rst) begin
|
388 |
|
|
if (rst) tx_actHi_txint <= 1'b0;
|
389 |
|
|
else tx_actHi_txint <= tx_actHi;
|
390 |
|
|
end
|
391 |
|
|
|
392 |
|
|
always @(posedge rxclk or posedge rst) begin
|
393 |
|
|
if (rst) rx_actHi_rxint <= 1'b0;
|
394 |
|
|
else rx_actHi_rxint <= rx_actHi;
|
395 |
|
|
end
|
396 |
|
|
|
397 |
|
|
always @(posedge txclk or posedge rst) begin
|
398 |
|
|
if (rst) msbFirst_txint <= 1'b0;
|
399 |
|
|
else msbFirst_txint <= msbFirst;
|
400 |
|
|
end
|
401 |
|
|
|
402 |
|
|
always @(posedge txclk or posedge rst) begin
|
403 |
|
|
if (rst) tx_start_txint <= 1'b0;
|
404 |
|
|
else tx_start_txint <= tx_start;
|
405 |
|
|
end
|
406 |
|
|
|
407 |
|
|
always @(posedge rxclk or posedge rst) begin
|
408 |
|
|
if (rst) rx_start_rxint <= 1'b0;
|
409 |
|
|
else rx_start_rxint <= rx_start;
|
410 |
|
|
end
|
411 |
|
|
|
412 |
|
|
wb_interface_sport wb_interface(wb_rst_i,wb_clk_i,wb_stb_i,wb_ack_o,wb_adr_i,wb_we_i,wb_dat_i,wb_sel_i,
|
413 |
|
|
wb_dat_o,wb_cyc_i,wb_cti_i,wb_err_o,wb_rty_o,rxsampleCnt,
|
414 |
|
|
rxpacketCnt,txsampleCnt,txpacketCnt,word_in,word_out,rxsecEn,rxlateFS_earlyFSn,
|
415 |
|
|
txsecEn,txlateFS_earlyFSn,tx_actHi,rx_actHi,msbFirst,tx_start, rx_start,rx_int);
|
416 |
|
|
|
417 |
|
|
endmodule
|
418 |
|
|
|
419 |
|
|
////////////////////////////////////////////////////////////////////
|
420 |
|
|
// CVS Revision History
|
421 |
|
|
//
|
422 |
|
|
// $Log: $
|
423 |
|
|
//
|