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

Last change on this file was 2445, checked in by murphpo, 10 years ago
File size: 14.4 KB
Line 
1//----------------------------------------------------------------------------
2// user_logic.v - module
3//----------------------------------------------------------------------------
4// ***************************************************************************
5// ** Copyright (c) 1995-2012 Xilinx, Inc.  All rights reserved.            **
6// **                                                                       **
7// ** Xilinx, Inc.                                                          **
8// ** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"         **
9// ** AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND       **
10// ** SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,        **
11// ** OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,        **
12// ** APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION           **
13// ** THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,     **
14// ** AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE      **
15// ** FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY              **
16// ** WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE               **
17// ** IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR        **
18// ** REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF       **
19// ** INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS       **
20// ** FOR A PARTICULAR PURPOSE.                                             **
21// **                                                                       **
22// ***************************************************************************
23//
24//----------------------------------------------------------------------------
25// Filename:          user_logic.v
26// Version:           3.01.a
27// Description:       User logic module.
28// Date:              Sat Feb 23 21:53:35 2013 (by Create and Import Peripheral Wizard)
29// Verilog Standard:  Verilog-2001
30//----------------------------------------------------------------------------
31// Naming Conventions:
32//   active low signals:                    "*_n"
33//   clock signals:                         "clk", "clk_div#", "clk_#x"
34//   reset signals:                         "rst", "rst_n"
35//   generics:                              "C_*"
36//   user defined types:                    "*_TYPE"
37//   state machine next state:              "*_ns"
38//   state machine current state:           "*_cs"
39//   combinatorial signals:                 "*_com"
40//   pipelined or register delay signals:   "*_d#"
41//   counter signals:                       "*cnt*"
42//   clock enable signals:                  "*_ce"
43//   internal version of output port:       "*_i"
44//   device pins:                           "*_pin"
45//   ports:                                 "- Names begin with Uppercase"
46//   processes:                             "*_PROCESS"
47//   component instantiations:              "<ENTITY_>I_<#|FUNC>"
48//----------------------------------------------------------------------------
49
50`uselib lib=unisims_ver
51`uselib lib=proc_common_v3_00_a
52
53module user_logic
54(
55  // -- ADD USER PORTS BELOW THIS LINE ---------------
56    spi_sclk,
57    spi_mosi,
58    spi_miso,
59    spi_cs_n,
60   
61    spi_enable_n,
62    cfg_req_n,
63    cfg_sel,
64   
65  // -- ADD USER PORTS ABOVE THIS LINE ---------------
66
67  // -- DO NOT EDIT BELOW THIS LINE ------------------
68  // -- Bus protocol ports, do not add to or delete
69  Bus2IP_Clk,                     // Bus to IP clock
70  Bus2IP_Resetn,                  // Bus to IP reset
71  Bus2IP_Data,                    // Bus to IP data bus
72  Bus2IP_BE,                      // Bus to IP byte enables
73  Bus2IP_RdCE,                    // Bus to IP read chip enable
74  Bus2IP_WrCE,                    // Bus to IP write chip enable
75  IP2Bus_Data,                    // IP to Bus data bus
76  IP2Bus_RdAck,                   // IP to Bus read transfer acknowledgement
77  IP2Bus_WrAck,                   // IP to Bus write transfer acknowledgement
78  IP2Bus_Error                    // IP to Bus error response
79  // -- DO NOT EDIT ABOVE THIS LINE ------------------
80); // user_logic
81
82// -- ADD USER PARAMETERS BELOW THIS LINE ------------
83// --USER parameters added here
84// -- ADD USER PARAMETERS ABOVE THIS LINE ------------
85
86// -- DO NOT EDIT BELOW THIS LINE --------------------
87// -- Bus protocol parameters, do not add to or delete
88parameter C_NUM_REG                      = 8;
89parameter C_SLV_DWIDTH                   = 32;
90// -- DO NOT EDIT ABOVE THIS LINE --------------------
91
92// -- ADD USER PORTS BELOW THIS LINE -----------------
93
94output  spi_sclk;
95output  spi_mosi;
96input   spi_miso;
97output  spi_cs_n;
98output  spi_enable_n;
99output  cfg_req_n;
100output [2:0] cfg_sel;
101
102// -- ADD USER PORTS ABOVE THIS LINE -----------------
103
104// -- DO NOT EDIT BELOW THIS LINE --------------------
105// -- Bus protocol ports, do not add to or delete
106input                                     Bus2IP_Clk;
107input                                     Bus2IP_Resetn;
108input      [C_SLV_DWIDTH-1 : 0]           Bus2IP_Data;
109input      [C_SLV_DWIDTH/8-1 : 0]         Bus2IP_BE;
110input      [C_NUM_REG-1 : 0]              Bus2IP_RdCE;
111input      [C_NUM_REG-1 : 0]              Bus2IP_WrCE;
112output     [C_SLV_DWIDTH-1 : 0]           IP2Bus_Data;
113output                                    IP2Bus_RdAck;
114output                                    IP2Bus_WrAck;
115output                                    IP2Bus_Error;
116// -- DO NOT EDIT ABOVE THIS LINE --------------------
117
118//----------------------------------------------------------------------------
119// Implementation
120//----------------------------------------------------------------------------
121
122  // --USER nets declarations added here, as needed for user logic
123
124  // Nets for user logic slave model s/w accessible register example
125  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg0;
126  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg1;
127  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg2;
128  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg3;
129  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg4;
130  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg5;
131  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg6;
132  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg7;
133  wire       [7 : 0]                        slv_reg_write_sel;
134  wire       [7 : 0]                        slv_reg_read_sel;
135  reg        [C_SLV_DWIDTH-1 : 0]           slv_ip2bus_data;
136  wire                                      slv_read_ack;
137  wire                                      slv_write_ack;
138  integer                                   byte_index, bit_index;
139
140  // USER logic implementation added here
141
142  // ------------------------------------------------------
143  // Example code to read/write user logic slave model s/w accessible registers
144  //
145  // Note:
146  // The example code presented here is to show you one way of reading/writing
147  // software accessible registers implemented in the user logic slave model.
148  // Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
149  // to one software accessible register by the top level template. For example,
150  // if you have four 32 bit software accessible registers in the user logic,
151  // you are basically operating on the following memory mapped registers:
152  //
153  //    Bus2IP_WrCE/Bus2IP_RdCE   Memory Mapped Register
154  //                     "1000"   C_BASEADDR + 0x0
155  //                     "0100"   C_BASEADDR + 0x4
156  //                     "0010"   C_BASEADDR + 0x8
157  //                     "0001"   C_BASEADDR + 0xC
158  //
159  // ------------------------------------------------------
160
161    wire [7:0] spi_rx_byte;
162
163    assign slv_reg_write_sel = Bus2IP_WrCE[7:0];
164    assign slv_reg_read_sel  = Bus2IP_RdCE[7:0];
165
166    //Removed [6] from _ack list, so slv_reg1 ack can be delayed following write to SPI Tx register
167    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];
168    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];
169
170  // implement slave model register(s)
171  always @( posedge Bus2IP_Clk )
172    begin
173
174      if ( Bus2IP_Resetn == 1'b0 )
175        begin
176          slv_reg0 <= 0;
177          slv_reg1 <= 0;
178          slv_reg2 <= 0;
179          slv_reg3 <= 0;
180          slv_reg4 <= 0;
181          slv_reg5 <= 0;
182          slv_reg6 <= 0;
183          slv_reg7 <= 0;
184        end
185      else
186        case ( slv_reg_write_sel )
187          8'b10000000 :
188            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
189              if ( Bus2IP_BE[byte_index] == 1 )
190                slv_reg0[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
191          8'b01000000 :
192            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
193              if ( Bus2IP_BE[byte_index] == 1 )
194                slv_reg1[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
195          8'b00100000 :
196            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
197              if ( Bus2IP_BE[byte_index] == 1 )
198                slv_reg2[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
199          8'b00010000 :
200            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
201              if ( Bus2IP_BE[byte_index] == 1 )
202                slv_reg3[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
203          8'b00001000 :
204            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
205              if ( Bus2IP_BE[byte_index] == 1 )
206                slv_reg4[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
207          8'b00000100 :
208            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
209              if ( Bus2IP_BE[byte_index] == 1 )
210                slv_reg5[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
211          8'b00000010 :
212            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
213              if ( Bus2IP_BE[byte_index] == 1 )
214                slv_reg6[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
215          8'b00000001 :
216            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
217              if ( Bus2IP_BE[byte_index] == 1 )
218                slv_reg7[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
219          default : begin
220            slv_reg0 <= slv_reg0;
221            slv_reg1 <= slv_reg1;
222            slv_reg2 <= slv_reg2;
223            slv_reg3 <= slv_reg3;
224            slv_reg4 <= slv_reg4;
225            slv_reg5 <= slv_reg5;
226            slv_reg6 <= slv_reg6;
227            slv_reg7 <= slv_reg7;
228                    end
229        endcase
230
231    end // SLAVE_REG_WRITE_PROC
232
233  // implement slave model register read mux
234  always @*
235    begin 
236
237      case ( slv_reg_read_sel )
238        8'b10000000 : slv_ip2bus_data <= slv_reg0;
239        8'b01000000 : slv_ip2bus_data <= slv_reg1;
240        8'b00100000 : slv_ip2bus_data <= spi_rxData;
241        8'b00010000 : slv_ip2bus_data <= slv_reg3;
242        8'b00001000 : slv_ip2bus_data <= slv_reg4;
243        8'b00000100 : slv_ip2bus_data <= slv_reg5;
244        8'b00000010 : slv_ip2bus_data <= slv_reg6;
245        8'b00000001 : slv_ip2bus_data <= slv_reg7;
246        default : slv_ip2bus_data <= 0;
247      endcase
248
249    end // SLAVE_REG_READ_PROC
250
251  // ------------------------------------------------------------
252  // Example code to drive IP to Bus signals
253  // ------------------------------------------------------------
254
255  assign IP2Bus_Data = (slv_read_ack == 1'b1) ? slv_ip2bus_data :  0 ;
256//  assign IP2Bus_WrAck   = slv_write_ack; //Overridden below
257  assign IP2Bus_RdAck = slv_read_ack;
258  assign IP2Bus_Error = 0;
259
260    /* Address map:
261        HDL is coded [MSB:LSB] = [31:0]
262        regX[31]  maps to 0x80000000 in C driver
263        regX[0] maps to 0x00000001 in C driver
264
265    0: Config:
266        [ 3: 0] Clock divider bit sel (00=0.5*busclk, 01=0.25*busclk, ...) 0x0000000F
267        [30:10] Reserved
268        [   31] Chip select
269
270    1: SPI Tx
271        [ 7: 0] Tx data byte
272        [31: 8] Reserved
273   
274    2: SPI Rx: {samp_rxByte, 24'b0}
275        [ 7: 0] SPI Rx byte
276        [31: 8] Reserved 0xFFFFFF00
277
278    3: FPGA config control:
279        [    0] SPI Enable (inverted below - reg active high, output active low) - gives FPGA SPI master control of SD card
280        [    1] Config request (inverted below - reg active high, output active low) - asserting this bit will reconfigure FPGA!
281        [ 7: 2] Reserved
282        [10: 8] Bitstream selection (slot on SD card, [0 to 7])
283        [31:11] Reserved
284   
285    4-15: Reserved
286    */
287    `define SIMPLE_SPI_XFER_LEN 5'd8
288
289    wire spi_tx_reg_write;
290    wire [3:0] clk_div_sel;
291    wire spi_xfer_done;
292
293    wire [31:0] spi_rxData;
294   
295    //SPI clock divider selection
296    assign clk_div_sel = slv_reg0[3:0]; //0x3 from driver
297
298    //SPI device chip selects (active high; inverted before use below)
299    assign spi_cs_n = ~slv_reg0[31]; //0x80000000 from driver
300   
301    //Use the IPIC write-enable for the SPI Tx register as the SPI go
302    // The bus will be paused until this core ACKs the write
303    assign spi_tx_reg_write = Bus2IP_WrCE[6];//WrCE/RdCE busses are addressed CE[7:0]=slv_reg[0:7]
304
305    //spi_tx_reg_write (Bus2IP_WrCE[6]) de-asserts as soon as transaction is ACK'd
306    // so this mux switches back to the generic ACK as soon as the SPI xfer is done
307    //Thus, the duration of assertion for spi_xfer_done doesn't really matter
308    //A bit fast-n-loose, but works ok
309    assign IP2Bus_WrAck = spi_tx_reg_write ? spi_xfer_done : slv_write_ack;
310
311    //FPGA config control bits, driven to CPLD
312    //Active low ctrl sigs here allow PULLUP in CoolRunner-II CPLD to help avoid accidental reconfigs
313    //  (no CPLD PULLDOWN available in C2 parts)
314    assign spi_enable_n = ~slv_reg3[0];
315    assign cfg_req_n = ~slv_reg3[1];
316    assign cfg_sel[2:0] = slv_reg3[10:8];
317   
318    warp_spi_io #(.SPI_XFER_LEN(`SIMPLE_SPI_XFER_LEN)) spi_io
319    (
320        .sys_clk(Bus2IP_Clk),
321        .reset(~Bus2IP_Resetn), //warp_spi_io reset is active high
322        .go(spi_tx_reg_write),
323        .done(spi_xfer_done),
324        .clkDiv(clk_div_sel),
325
326        .currBitNum(),
327
328        .txData(slv_reg1),
329
330        .rxData1(spi_rxData),
331        .rxData2(),
332        .rxData3(),
333        .rxData4(),
334       
335        .spi_cs(),
336        .spi_sclk(spi_sclk),
337
338        .spi_mosi(spi_mosi),
339       
340        .spi_miso1(spi_miso),
341        .spi_miso2(1'b0),
342        .spi_miso3(1'b0),
343        .spi_miso4(1'b0)
344    );
345   
346endmodule
Note: See TracBrowser for help on using the repository browser.