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

Last change on this file was 3909, checked in by welsh, 10 years ago

Updating clock controller software.

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