Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top...
[debian/gnuradio] / usrp2 / fpga / eth / demo / verilog / demo_wishbone_master.v
1 module demo_wishbone_master(\r
2   Reset_n,\r
3   Clk,\r
4 \r
5   //--- UART interface\r
6 \r
7   // Pulsed when RxData_i is valid\r
8   RxValid_i,\r
9   RxData_i,\r
10 \r
11   // Asserted when ready for a new Tx byte\r
12   TxReady_i,\r
13 \r
14   // Pulsed when TxData_o is valid\r
15   TxValid_o,\r
16   TxData_o,\r
17 \r
18   //--- Wishbone interface\r
19   STB_ETH_O,\r
20   STB_PDM_O,\r
21   STB_PG_O,\r
22   CYC_O,\r
23   ADR_O,\r
24   WE_O, \r
25   DAT_O,\r
26   DAT_I,\r
27   ACK_I\r
28 );\r
29 \r
30   input         Reset_n;\r
31   input         Clk;\r
32 \r
33   //--- UART interface\r
34 \r
35   // Pulsed when RxData_i is valid\r
36   input         RxValid_i;\r
37   input [7:0]   RxData_i;\r
38 \r
39   // Asserted when ready for a new Tx byte\r
40   input         TxReady_i;\r
41 \r
42   // Pulsed when TxData_o is valid\r
43   output        TxValid_o;\r
44   output [7:0]  TxData_o;\r
45 \r
46   output        STB_ETH_O;\r
47   output        STB_PDM_O;\r
48   output        STB_PG_O;\r
49   output        CYC_O;\r
50   output [14:0] ADR_O;\r
51   output        WE_O;\r
52   output [15:0] DAT_O;\r
53   input [15:0]  DAT_I;\r
54   input         ACK_I;\r
55 \r
56   //-------------------------------------------------------------------------\r
57   // Local declarations\r
58   //-------------------------------------------------------------------------\r
59 \r
60   reg          TxValid_o;\r
61   reg [7:0]    TxData_o;\r
62   reg          STB_ETH_O;\r
63   reg          STB_PDM_O;\r
64   reg          STB_PG_O;\r
65   reg          CYC_O;\r
66   reg [14:0]   ADR_O;\r
67   reg          WE_O;\r
68   reg [15:0]   DAT_O;\r
69 \r
70   //-------------------------------------------------------------------------\r
71   // Instantiation of sub-modules\r
72   //-------------------------------------------------------------------------\r
73 \r
74   //--- Transmit FSM --------------------------------------------------------\r
75 \r
76   parameter    TX_STATE_IDLE  = 0;\r
77   parameter    TX_STATE_INIT  = 1;\r
78   parameter    TX_STATE_OK    = 2;\r
79   parameter    TX_STATE_ERROR = 3;\r
80   parameter    TX_STATE_VALUE = 4;\r
81   parameter    TX_STATE_LF    = 5;\r
82 \r
83   reg [2:0]    TxState;\r
84   reg [3:0]    TxIndex;\r
85   reg          TxLast;\r
86 \r
87   wire [15:0]  TxValue16;\r
88   wire [3:0]   TxHexDigit;\r
89   wire [7:0]   TxHexChar;\r
90   reg          TxOK;\r
91   reg          TxERROR;\r
92   reg          TxValue;\r
93 \r
94   always @( negedge Reset_n or posedge Clk )\r
95     if ( ~Reset_n )\r
96       begin\r
97         TxState   <= TX_STATE_INIT;\r
98         TxIndex   <= 0;\r
99         TxLast    <= 0;\r
100 \r
101         TxValid_o <= 0;\r
102         TxData_o  <= 'b0;\r
103       end\r
104     else\r
105       begin\r
106         TxValid_o <= 0;\r
107 \r
108         // Don't do anything in cycle following TxValid_o being pulsed\r
109         if ( ~TxValid_o )\r
110           begin\r
111             casez ( TxState )\r
112               TX_STATE_INIT:\r
113                 casez ( TxIndex )\r
114                   0: TxData_o <= "R";\r
115                   1: TxData_o <= "E";\r
116                   2: TxData_o <= "A";\r
117                   3: TxData_o <= "D";\r
118                   4: TxData_o <= "Y";\r
119                   default: TxLast <= 1;\r
120                 endcase\r
121               \r
122               TX_STATE_OK:\r
123                 casez ( TxIndex )\r
124                   0: TxData_o <= "O";\r
125                   1: TxData_o <= "K";\r
126                   default: TxLast <= 1;\r
127                 endcase\r
128 \r
129               TX_STATE_ERROR:\r
130                 casez ( TxIndex )\r
131                   0: TxData_o <= "E";\r
132                   1: TxData_o <= "R";\r
133                   2: TxData_o <= "R";\r
134                   3: TxData_o <= "O";\r
135                   4: TxData_o <= "R";\r
136                   default: TxLast <= 1;\r
137                 endcase\r
138 \r
139               TX_STATE_VALUE:\r
140                 casez ( TxIndex )\r
141                   0,1,2,3: TxData_o <= TxHexChar;\r
142                   default: TxLast <= 1;\r
143                 endcase\r
144 \r
145               TX_STATE_LF:\r
146                 ;\r
147 \r
148               default:\r
149                 begin\r
150                   if ( TxOK )\r
151                     TxState <= TX_STATE_OK;\r
152                   else if ( TxERROR )\r
153                     TxState <= TX_STATE_ERROR;\r
154                   else if ( TxValue )\r
155                     begin                         \r
156                       TxState <= TX_STATE_VALUE;\r
157                       TxIndex <= 0;\r
158                     end\r
159                 end\r
160             endcase\r
161 \r
162             if ( (TxState != TX_STATE_IDLE) & TxReady_i )\r
163               begin\r
164                 TxValid_o <= 1;\r
165 \r
166                 if ( TxLast )\r
167                   begin\r
168                     if ( TxState == TX_STATE_LF )\r
169                       begin\r
170                         TxData_o <= 10; // LF\r
171                         TxState  <= TX_STATE_IDLE;\r
172                         TxIndex  <= 0;\r
173                         TxLast   <= 0;\r
174                       end\r
175                     else\r
176                       begin\r
177                         TxData_o <= 13; // CR\r
178                         TxState  <= TX_STATE_LF;\r
179                       end\r
180                   end\r
181                 else\r
182                   TxIndex <= TxIndex + 1;\r
183               end\r
184           end\r
185       end\r
186 \r
187   assign TxHexDigit = (TxIndex==0) ? TxValue16[15:12] :\r
188                       (TxIndex==1) ? TxValue16[11: 8] :\r
189                       (TxIndex==2) ? TxValue16[ 7: 4] :\r
190                                      TxValue16[ 3: 0];\r
191 \r
192   assign TxHexChar = (TxHexDigit <= 9) ? (TxHexDigit + "0") :\r
193                                          (TxHexDigit + "A"-'hA);\r
194 \r
195   //--- Receive FSM ---------------------------------------------------------\r
196 \r
197   parameter RX_STATE_IDLE           = 0;\r
198   parameter RX_STATE_VALUE16_FIRST  = 1;\r
199   parameter RX_STATE_VALUE16        = 2;\r
200   parameter RX_STATE_COMMENT        = 3;\r
201   parameter RX_STATE_CMD            = 4;\r
202 \r
203   reg [2:0] RxState;\r
204 \r
205   wire IsWhiteSpace = ( RxData_i==" "  ) |\r
206                       ( RxData_i=="\t" ) |\r
207                       ( RxData_i==","  ) |\r
208                       ( RxData_i==10   ) |\r
209                       ( RxData_i==13   );\r
210   wire IsHexDigit = (( RxData_i >= "0" ) & ( RxData_i <= "9" )) |\r
211                     (( RxData_i >= "a" ) & ( RxData_i <= "f" )) |\r
212                       (( RxData_i >= "A" ) & ( RxData_i <= "F" ));\r
213   wire [3:0] RxHexValue =\r
214                (( RxData_i >= "0" ) & ( RxData_i <= "9" )) ? RxData_i[3:0] :\r
215                (( RxData_i >= "a" ) & ( RxData_i <= "f" )) ? (RxData_i-"a"+'hA) :\r
216                (( RxData_i >= "A" ) & ( RxData_i <= "F" )) ? (RxData_i-"A"+'hA) : 0;\r
217 \r
218   reg [15:0] RxValue16;\r
219   reg        RxWrite;\r
220   reg        RxWrData;\r
221 \r
222   reg [15:0] RegAddr;\r
223   reg [15:0] RegRdData;\r
224 \r
225   assign     TxValue16 = RegRdData;\r
226 \r
227   always @( negedge Reset_n or posedge Clk )\r
228     if ( ~Reset_n )\r
229       begin\r
230         RxState   <= RX_STATE_IDLE;\r
231 \r
232         RxValue16 <= 16'h0;\r
233         RxWrite   <= 0;\r
234         RxWrData  <= 0;\r
235 \r
236         RegAddr   <= 'b0;\r
237         RegRdData <= 'b0;\r
238 \r
239         STB_ETH_O <= 0;\r
240         STB_PDM_O <= 0;\r
241         STB_PG_O  <= 0;\r
242         CYC_O     <= 0;\r
243         ADR_O     <= 0;\r
244         WE_O      <= 0;\r
245         DAT_O     <= 0;\r
246 \r
247         TxOK      <= 0;\r
248         TxERROR   <= 0;\r
249         TxValue   <= 0;\r
250       end\r
251     else\r
252       begin\r
253         TxOK    <= 0;\r
254         TxERROR <= 0;\r
255         TxValue <= 0;\r
256 \r
257         if ( RxState == RX_STATE_CMD )\r
258           begin\r
259             STB_ETH_O <= ( RegAddr[15:12] == 4'h0 );\r
260             STB_PG_O  <= ( RegAddr[15:12] == 4'h1 );\r
261             STB_PDM_O <= ( RegAddr[15]    == 1'b1 );\r
262 \r
263             CYC_O <= 1;\r
264             ADR_O <= RegAddr[14:0];\r
265             WE_O  <= RxWrite;\r
266 \r
267             if ( ACK_I )\r
268               begin\r
269                 // Register transaction is completing!\r
270                 CYC_O     <= 0;\r
271                 STB_ETH_O <= 0;\r
272                 STB_PDM_O <= 0;\r
273                 STB_PG_O  <= 0;\r
274 \r
275                 // Latch data read in case of a read\r
276                 RegRdData <= DAT_I;\r
277 \r
278                 if ( RxWrite )\r
279                   // Transaction was a register write\r
280                   TxOK <= 1;\r
281                 else\r
282                   TxValue <= 1;\r
283 \r
284                 RxState <= RX_STATE_IDLE;\r
285               end\r
286           end\r
287         else if ( (TxState == TX_STATE_IDLE) & RxValid_i )\r
288           begin\r
289             // A byte has been received!\r
290 \r
291             casez ( RxState )\r
292               RX_STATE_IDLE:\r
293                 if ( (RxData_i == "w") | (RxData_i == "W") )\r
294                   begin\r
295                     // Write Register Command: W rrrr dddd\r
296                     RxState  <= RX_STATE_VALUE16_FIRST;\r
297                     RxWrite  <= 1;\r
298                     RxWrData <= 0;\r
299                   end\r
300                 else if ( (RxData_i == "r") | (RxData_i == "R") )\r
301                   begin\r
302                     // Read Register Command: R rrrr\r
303                     RxState <= RX_STATE_VALUE16_FIRST;\r
304                     RxWrite <= 0;\r
305                   end\r
306                 else if ( RxData_i == "/" )\r
307                   begin\r
308                     // Comment!\r
309                     RxState <= RX_STATE_COMMENT;\r
310                   end\r
311                 else if ( ~IsWhiteSpace )\r
312                   // Unknown command!\r
313                   TxERROR <= 1;\r
314 \r
315               RX_STATE_COMMENT:\r
316                 if ( (RxData_i == 13) | (RxData_i == 10) )\r
317                   // CR or LF - end of comment\r
318                   RxState <= RX_STATE_IDLE;\r
319 \r
320               RX_STATE_VALUE16_FIRST:\r
321                 if ( IsHexDigit )\r
322                   begin\r
323                     RxValue16 <= { 12'b0, RxHexValue };\r
324                     RxState <= RX_STATE_VALUE16;\r
325                   end\r
326                 else if ( ~IsWhiteSpace )\r
327                   begin\r
328                     // Unexpected character!\r
329                     TxERROR <= 1;\r
330                     RxState <= RX_STATE_IDLE;\r
331                   end\r
332 \r
333               RX_STATE_VALUE16:\r
334                 if ( IsHexDigit )\r
335                   RxValue16 <= { RxValue16[11:0], RxHexValue };\r
336                 else if ( IsWhiteSpace )\r
337                   begin\r
338                     // Done collecting 16-bit value\r
339                     if ( RxWrite )\r
340                       begin\r
341                         // This is a register write\r
342                         if ( RxWrData )\r
343                           begin\r
344                             // Second time around - just received write data\r
345                             DAT_O   <= RxValue16;\r
346                             RxState <= RX_STATE_CMD;\r
347                           end\r
348                         else\r
349                           begin\r
350                             // Just received register address - expecting second argument\r
351                             RegAddr <= RxValue16;\r
352                             RxState <= RX_STATE_VALUE16_FIRST;\r
353                             RxWrData <= 1; // Now receive the write data\r
354                           end\r
355                       end\r
356                     else\r
357                       begin\r
358                         // This is a register read\r
359                         RegAddr <= RxValue16;\r
360                         RxState <= RX_STATE_CMD;\r
361                       end\r
362                   end\r
363                 else\r
364                   begin\r
365                     // Unexpected character!\r
366                     TxERROR <= 1;\r
367                     RxState <= RX_STATE_IDLE;\r
368                   end\r
369 \r
370               default:\r
371                 TxERROR <= 1;\r
372             endcase\r
373           end\r
374       end\r
375   \r
376 endmodule\r