source: PlatformSupport/CustomPeripherals/pcores/w3_clock_controller_v3_01_b/hdl/verilog/user_logic.v

Last change on this file was 1908, checked in by murphpo, 11 years ago
File size: 18.2 KB
Line 
1//----------------------------------------------------------------------------
2// WARP v3 Clock Controller
3// Copyright (c) 2013 Mango Communications
4// Based on the user_logic template generated by XPS 13.4
5// Original Xilinx copyright statement for user_logic template included below
6//----------------------------------------------------------------------------
7//----------------------------------------------------------------------------
8// user_logic.vhd - module
9//----------------------------------------------------------------------------
10//
11// ***************************************************************************
12// ** Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.            **
13// **                                                                       **
14// ** Xilinx, Inc.                                                          **
15// ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"         **
16// ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND       **
17// ** SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,        **
18// ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,        **
19// ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION           **
20// ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,     **
21// ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE      **
22// ** FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY              **
23// ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE               **
24// ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR        **
25// ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF       **
26// ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS       **
27// ** FOR A PARTICULAR PURPOSE.                                             **
28// **                                                                       **
29// ***************************************************************************
30//
31//----------------------------------------------------------------------------
32// Filename:          user_logic.vhd
33// Version:           3.00.a
34// Description:       User logic module.
35// Date:              Mon May 14 12:21:28 2012 (by Create and Import Peripheral Wizard)
36// Verilog Standard:  Verilog-2001
37//----------------------------------------------------------------------------
38// Naming Conventions:
39//   active low signals:                    "*_n"
40//   clock signals:                         "clk", "clk_div#", "clk_#x"
41//   reset signals:                         "rst", "rst_n"
42//   generics:                              "C_*"
43//   user defined types:                    "*_TYPE"
44//   state machine next state:              "*_ns"
45//   state machine current state:           "*_cs"
46//   combinatorial signals:                 "*_com"
47//   pipelined or register delay signals:   "*_d#"
48//   counter signals:                       "*cnt*"
49//   clock enable signals:                  "*_ce"
50//   internal version of output port:       "*_i"
51//   device pins:                           "*_pin"
52//   ports:                                 "- Names begin with Uppercase"
53//   processes:                             "*_PROCESS"
54//   component instantiations:              "<ENTITY_>I_<#|FUNC>"
55//----------------------------------------------------------------------------
56
57module user_logic
58(
59    // -- ADD USER PORTS BELOW THIS LINE ---------------
60   
61    at_boot_clk_in,
62    at_boot_clk_in_valid,
63    at_boot_clkbuf_clocks_invalid,
64    at_boot_config_sw,
65
66    samp_spi_sclk,
67    samp_spi_mosi,
68    samp_spi_miso,
69    samp_spi_cs_n,
70    samp_func,
71   
72    rfref_spi_sclk,
73    rfref_spi_mosi,
74    rfref_spi_miso,
75    rfref_spi_cs_n,
76    rfref_func,
77   
78    usr_reset0,
79    usr_reset1,
80    usr_reset2,
81    usr_reset3,
82   
83    usr_status,
84    // -- ADD USER PORTS ABOVE THIS LINE ---------------
85
86    // -- DO NOT EDIT BELOW THIS LINE ------------------
87    // -- Bus protocol ports, do not add to or delete
88    Bus2IP_Clk,                     // Bus to IP clock
89    Bus2IP_Reset,                   // Bus to IP reset
90    Bus2IP_Data,                    // Bus to IP data bus
91    Bus2IP_BE,                      // Bus to IP byte enables
92    Bus2IP_RdCE,                    // Bus to IP read chip enable
93    Bus2IP_WrCE,                    // Bus to IP write chip enable
94    IP2Bus_Data,                    // IP to Bus data bus
95    IP2Bus_RdAck,                   // IP to Bus read transfer acknowledgement
96    IP2Bus_WrAck,                   // IP to Bus write transfer acknowledgement
97    IP2Bus_Error                    // IP to Bus error response
98    // -- DO NOT EDIT ABOVE THIS LINE ------------------
99); // user_logic
100
101// -- ADD USER PARAMETERS BELOW THIS LINE ------------
102// --USER parameters added here
103// -- ADD USER PARAMETERS ABOVE THIS LINE ------------
104
105// -- DO NOT EDIT BELOW THIS LINE --------------------
106// -- Bus protocol parameters, do not add to or delete
107parameter C_SLV_DWIDTH                   = 32;
108parameter C_NUM_REG                      = 8;
109// -- DO NOT EDIT ABOVE THIS LINE --------------------
110
111// -- ADD USER PORTS BELOW THIS LINE -----------------
112
113input   at_boot_clk_in;
114input   at_boot_clk_in_valid;
115output  at_boot_clkbuf_clocks_invalid;
116input [0:1] at_boot_config_sw;
117
118output samp_spi_sclk;
119output samp_spi_mosi;
120input samp_spi_miso;
121output samp_spi_cs_n;
122output samp_func;
123
124output rfref_spi_sclk;
125output rfref_spi_mosi;
126input rfref_spi_miso;
127output rfref_spi_cs_n;
128output rfref_func;
129
130output usr_reset0;
131output usr_reset1;
132output usr_reset2;
133output usr_reset3;
134
135input [0:31] usr_status;
136
137// -- ADD USER PORTS ABOVE THIS LINE -----------------
138
139// -- DO NOT EDIT BELOW THIS LINE --------------------
140// -- Bus protocol ports, do not add to or delete
141input                                     Bus2IP_Clk;
142input                                     Bus2IP_Reset;
143input      [0 : C_SLV_DWIDTH-1]           Bus2IP_Data;
144input      [0 : C_SLV_DWIDTH/8-1]         Bus2IP_BE;
145input      [0 : C_NUM_REG-1]              Bus2IP_RdCE;
146input      [0 : C_NUM_REG-1]              Bus2IP_WrCE;
147output     [0 : C_SLV_DWIDTH-1]           IP2Bus_Data;
148output                                    IP2Bus_RdAck;
149output                                    IP2Bus_WrAck;
150output                                    IP2Bus_Error;
151// -- DO NOT EDIT ABOVE THIS LINE --------------------
152
153//----------------------------------------------------------------------------
154// Implementation
155//----------------------------------------------------------------------------
156
157    // --USER nets declarations added here, as needed for user logic
158
159    // Nets for user logic slave model s/w accessible register example
160    reg        [0 : C_SLV_DWIDTH-1]           slv_reg0;
161    reg        [0 : C_SLV_DWIDTH-1]           slv_reg1;
162    reg        [0 : C_SLV_DWIDTH-1]           slv_reg2;
163    reg        [0 : C_SLV_DWIDTH-1]           slv_reg3;
164    reg        [0 : C_SLV_DWIDTH-1]           slv_reg4;
165    reg        [0 : C_SLV_DWIDTH-1]           slv_reg5;
166    reg        [0 : C_SLV_DWIDTH-1]           slv_reg6;
167    reg        [0 : C_SLV_DWIDTH-1]           slv_reg7;
168    wire       [0 : 7]                        slv_reg_write_sel;
169    wire       [0 : 7]                        slv_reg_read_sel;
170    reg        [0 : C_SLV_DWIDTH-1]           slv_ip2bus_data;
171    wire                                      slv_read_ack;
172    wire                                      slv_write_ack;
173    integer                                   byte_index, bit_index;
174
175    // --USER logic implementation added here
176
177    // ------------------------------------------------------
178    // Example code to read/write user logic slave model s/w accessible registers
179    //
180    // Note:
181    // The example code presented here is to show you one way of reading/writing
182    // software accessible registers implemented in the user logic slave model.
183    // Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
184    // to one software accessible register by the top level template. For example,
185    // if you have four 32 bit software accessible registers in the user logic,
186    // you are basically operating on the following memory mapped registers:
187    //
188    //    Bus2IP_WrCE/Bus2IP_RdCE   Memory Mapped Register
189    //                     "1000"   C_BASEADDR + 0x0
190    //                     "0100"   C_BASEADDR + 0x4
191    //                     "0010"   C_BASEADDR + 0x8
192    //                     "0001"   C_BASEADDR + 0xC
193    //
194    // ------------------------------------------------------
195
196    wire [0:15] clock_module_status;
197   
198    assign slv_reg_write_sel = Bus2IP_WrCE[0:7];
199    assign slv_reg_read_sel  = Bus2IP_RdCE[0:7];
200
201    //Removed [1] from _ack list, so ack can be delayed following write to SPI Tx register
202    assign slv_write_ack     = Bus2IP_WrCE[0] || Bus2IP_WrCE[2] || Bus2IP_WrCE[3] || Bus2IP_WrCE[4] || Bus2IP_WrCE[5] || Bus2IP_WrCE[6] || Bus2IP_WrCE[7];
203    assign slv_read_ack      = Bus2IP_RdCE[0] || Bus2IP_RdCE[1] || Bus2IP_RdCE[2] || Bus2IP_RdCE[3] || Bus2IP_RdCE[4] || Bus2IP_RdCE[5] || Bus2IP_RdCE[6] || Bus2IP_RdCE[7];
204
205    // implement slave model register(s)
206    always @( posedge Bus2IP_Clk )
207        begin: SLAVE_REG_WRITE_PROC
208
209            if ( Bus2IP_Reset == 1 )
210                begin
211                    slv_reg0 <= 0;
212                    slv_reg1 <= 0;
213                    slv_reg2 <= 0;
214                    slv_reg3 <= 0;
215                    slv_reg4 <= 0;
216                    slv_reg5 <= 0;
217                    slv_reg6 <= 0;
218                    slv_reg7 <= 0;
219                end
220            else
221                case ( slv_reg_write_sel )
222                    8'b10000000 :
223                        for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
224                            if ( Bus2IP_BE[byte_index] == 1 )
225                                for ( bit_index = byte_index*8; bit_index <= byte_index*8+7; bit_index = bit_index+1 )
226                                    slv_reg0[bit_index] <= Bus2IP_Data[bit_index];
227                    8'b01000000 :
228                        for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
229                            if ( Bus2IP_BE[byte_index] == 1 )
230                                for ( bit_index = byte_index*8; bit_index <= byte_index*8+7; bit_index = bit_index+1 )
231                                    slv_reg1[bit_index] <= Bus2IP_Data[bit_index];
232                    8'b00100000 :
233                        for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
234                            if ( Bus2IP_BE[byte_index] == 1 )
235                                for ( bit_index = byte_index*8; bit_index <= byte_index*8+7; bit_index = bit_index+1 )
236                                    slv_reg2[bit_index] <= Bus2IP_Data[bit_index];
237                    8'b00010000 :
238                        for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
239                            if ( Bus2IP_BE[byte_index] == 1 )
240                                for ( bit_index = byte_index*8; bit_index <= byte_index*8+7; bit_index = bit_index+1 )
241                                    slv_reg3[bit_index] <= Bus2IP_Data[bit_index];
242                    8'b00001000 :
243                        for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
244                            if ( Bus2IP_BE[byte_index] == 1 )
245                                for ( bit_index = byte_index*8; bit_index <= byte_index*8+7; bit_index = bit_index+1 )
246                                    slv_reg4[bit_index] <= Bus2IP_Data[bit_index];
247                    8'b00000100 :
248                        for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
249                            if ( Bus2IP_BE[byte_index] == 1 )
250                                for ( bit_index = byte_index*8; bit_index <= byte_index*8+7; bit_index = bit_index+1 )
251                                    slv_reg5[bit_index] <= Bus2IP_Data[bit_index];
252                    8'b00000010 :
253                        for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
254                            if ( Bus2IP_BE[byte_index] == 1 )
255                                for ( bit_index = byte_index*8; bit_index <= byte_index*8+7; bit_index = bit_index+1 )
256                                    slv_reg6[bit_index] <= Bus2IP_Data[bit_index];
257                    8'b00000001 :
258                        for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
259                            if ( Bus2IP_BE[byte_index] == 1 )
260                                for ( bit_index = byte_index*8; bit_index <= byte_index*8+7; bit_index = bit_index+1 )
261                                    slv_reg7[bit_index] <= Bus2IP_Data[bit_index];
262                    default : ;
263                endcase
264
265        end // SLAVE_REG_WRITE_PROC
266
267    wire [0:7] samp_spi_rx_byte;
268    wire [0:7] rfref_spi_rx_byte;
269
270    // implement slave model register read mux
271    always @* //( slv_reg_read_sel or slv_reg0 or slv_reg1 or slv_reg2 or slv_reg3 or slv_reg4 or slv_reg5 or slv_reg6 or slv_reg7 )
272        begin: SLAVE_REG_READ_PROC
273
274            case ( slv_reg_read_sel )
275                8'b10000000 : slv_ip2bus_data <= {clock_module_status, slv_reg0[16:31]};
276                8'b01000000 : slv_ip2bus_data <= slv_reg1;
277                8'b00100000 : slv_ip2bus_data <= {16'b0, rfref_spi_rx_byte, samp_spi_rx_byte};
278                8'b00010000 : slv_ip2bus_data <= slv_reg3;
279                8'b00001000 : slv_ip2bus_data <= usr_status_d;
280                8'b00000100 : slv_ip2bus_data <= slv_reg5;
281                8'b00000010 : slv_ip2bus_data <= slv_reg6;
282                8'b00000001 : slv_ip2bus_data <= slv_reg7;
283                default : slv_ip2bus_data <= 0;
284            endcase
285
286        end // SLAVE_REG_READ_PROC
287
288    // ------------------------------------------------------------
289    // Example code to drive IP to Bus signals
290    // ------------------------------------------------------------
291
292    assign IP2Bus_Data    = slv_ip2bus_data;
293//  assign IP2Bus_WrAck   = slv_write_ack; //Overridden below
294    assign IP2Bus_RdAck   = slv_read_ack;
295    assign IP2Bus_Error   = 0;
296
297    /* Address map:
298        HDL is coded [MSB:LSB] = [0:31]
299        regX[0]  maps to 0x80000000 in C driver
300        regX[31] maps to 0x00000001 in C driver
301
302    0: Config: {clk_div_sel[2:0], 1'b0, samp_func, rfref_func, 26'b0}
303        [29:31] Clock divider bit sel (00=0.5*busclk, 01=0.25*busclk, ...) 0x00000003
304        [28   ] Reserved
305        [   27] samp buf reset (active low)     0x00000010
306        [   26] rf ref buf reset (active low)   0x00000020
307        [16:25] Reserved                        0x0000FFC0
308        [0 :15] Clock module status             0xFFFF0000
309
310    1: SPI Tx
311        [24:31] Tx data byte
312        [17:23] 7-bit register address (0x00 to 0x3F all valid)
313        [11:16] 6'b0 (always zero)
314        [ 9:10] Num bytes to Tx/Rx; must be 2'b0 for 1-byte Tx/Rx
315        [    8] RW# 1=Read, 0=Write
316        [    7] ad1 chip select mask
317        [    6] ad2 chip select mask
318        [ 0: 5] Reserved
319   
320    2: SPI Rx: {samp_rxByte, rfref_rxByte, 16'b0}
321        [24:31] SPI Rx byte for samp buf 0x00FF
322        [16:23] SPI Rx byte for rf ref buf 0xFF00
323        [ 0:15] Reserved 0xFFFF0000
324       
325    3: RW: User reset outputs
326        [31] usr_reset0
327        [30] usr_reset1
328        [29] usr_reset2
329        [28] usr_reset3
330        [0:27] reserved
331   
332    4: RO: User status inputs
333        [0:31] usr_status input
334   
335    5-15: Reserved
336    */
337
338    `define AD9512_SPI_XFER_LEN 5'd24
339
340    wire spi_mosi;
341    wire spi_sclk;
342    wire spi_cs;
343    wire spi_rnw;
344    wire spi_tx_reg_write;
345    wire [0:2] clk_div_sel;
346    wire spi_xfer_done;
347
348    wire samp_spi_cs, rfref_spi_cs;
349   
350    wire [0:31] samp_spi_rxData;
351    wire [0:31] rfref_spi_rxData;
352   
353    reg [0:31] usr_status_d;
354
355    //Register the usr_status input here, to ease timing closure of potentially fast host PLBs
356    always @(posedge Bus2IP_Clk)
357        usr_status_d <= usr_status;
358       
359    //Extract bits from IPIF slave registers and control signals
360
361    //spi_io stores 32 bits for Tx/Rx
362    // AD9512 only outputs 8-bit words during reads, always the last 8 bits of the transfer
363    assign samp_spi_rx_byte = samp_spi_rxData[24:31];
364    assign rfref_spi_rx_byte = rfref_spi_rxData[24:31];
365   
366    //SPI clock divider selection
367    assign clk_div_sel = slv_reg0[29:31]; //0x3 from driver
368
369    //SPI device resets (active low)
370    assign samp_func = slv_reg0[27]; //0x10 from driver
371    assign rfref_func = slv_reg0[26]; //0x20 from driver
372
373    //SPI device chip selects (active high; inverted before use below)
374    assign samp_spi_cs = slv_reg1[7]; //0x01000000 from driver
375    assign rfref_spi_cs = slv_reg1[6]; //0x02000000 from driver
376
377    //User reset outputs
378    assign usr_reset0 = slv_reg3[31];
379    assign usr_reset1 = slv_reg3[30];
380    assign usr_reset2 = slv_reg3[29];
381    assign usr_reset3 = slv_reg3[28];
382   
383    //Use the IPIC write-enable for the SPI Tx register as the SPI go
384    // The bus will be paused until this core ACKs the write
385    assign spi_tx_reg_write = Bus2IP_WrCE[1];
386
387    //spi_tx_reg_write (Bus2IP_WrCE[1]) de-asserts as soon as transaction is ACK'd
388    // so this mux switches back to the generic ACK as soon as the SPI xfer is done
389    //Thus, the duration of assertion for spi_xfer_done doesn't really matter
390    //A bit fast-n-loose, but works ok
391    assign IP2Bus_WrAck = spi_tx_reg_write ? spi_xfer_done : slv_write_ack;
392
393    //SPI device chip selects are active low
394    //assign samp_spi_cs_n = ~(samp_spi_cs & spi_cs);
395    assign rfref_spi_cs_n = ~(rfref_spi_cs & spi_cs);
396   
397    //Mask each device's SPI clock output by its CS; no point toggling signals that will be ignored
398    //assign samp_spi_sclk = (spi_sclk & samp_spi_cs);
399    assign rfref_spi_sclk = (spi_sclk & rfref_spi_cs);
400
401    //All SPI devices driven by same serial data output; CS signals control who listens
402    //assign samp_spi_mosi = samp_spi_cs ? spi_mosi : 1'b0;
403    assign rfref_spi_mosi = rfref_spi_cs ? spi_mosi : 1'b0;
404   
405    warp_spi_io #(.SPI_XFER_LEN(`AD9512_SPI_XFER_LEN)) spi_io
406    (
407        .sys_clk(Bus2IP_Clk),
408        .reset(Bus2IP_Reset),
409        .go(spi_tx_reg_write),
410        .done(spi_xfer_done),
411        .clkDiv(clk_div_sel),
412
413        .currBitNum(),
414
415        .txData(slv_reg1),
416
417        .rxData1(samp_spi_rxData),
418        .rxData2(rfref_spi_rxData),
419        .rxData3(),
420        .rxData4(),
421       
422        .spi_cs(spi_cs),
423        .spi_sclk(spi_sclk),
424
425        .spi_mosi(spi_mosi),
426       
427        .spi_miso1(samp_spi_miso),
428        .spi_miso2(rfref_spi_miso),
429        .spi_miso3(1'b0),
430        .spi_miso4(1'b0)
431    );
432   
433    /* At-boot Clock Config Logic
434        This logic writes registers in the sampling clock AD9512 to:
435        -Select the clock source (on-board oscillator or off-board via clock mod header)
436        -Set the AD9512->FPGA divider to 1 (defaults to 2 on AD9512 reset)
437    */
438    wire at_boot_spi_mosi;
439    wire at_boot_spi_sclk;
440    wire at_boot_spi_csn;
441
442    at_boot_reg_writer at_boot_reg_writer_inst (
443        .clk(at_boot_clk_in),
444        .clk_valid(at_boot_clk_in_valid),
445        .clk_src_sel((at_boot_config_sw[0] | at_boot_config_sw[1])),
446        .spi_running(at_boot_clkbuf_clocks_invalid),
447       
448        .spi_mosi(at_boot_spi_mosi),
449        .spi_sclk(at_boot_spi_sclk),
450        .spi_csn(at_boot_spi_csn)
451    );
452   
453    //Mux the sampling clock SPI output signals between the at-boot and software-driven logic
454    // at-boot logic doesn't care about SPI MISO
455    assign samp_spi_cs_n = at_boot_clkbuf_clocks_invalid ? (at_boot_spi_csn)  : (~(samp_spi_cs & spi_cs));
456    assign samp_spi_sclk = at_boot_clkbuf_clocks_invalid ? (at_boot_spi_sclk) : (spi_sclk & samp_spi_cs);
457    assign samp_spi_mosi = at_boot_clkbuf_clocks_invalid ? (at_boot_spi_mosi) : (samp_spi_cs ? spi_mosi : 1'b0);
458   
459    assign clock_module_status = {14'b0, at_boot_config_sw};
460
461endmodule
Note: See TracBrowser for help on using the repository browser.