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

Last change on this file was 5565, checked in by murphpo, 8 years ago

Updated w3_userio pcore with hw/sw control source logic for debug header. This allows all 16 pins of the debug header to be connected to the userio core. Software configures each pin's value as sw (set by C via a register) or hw (driven by an on-chip debug signals).

File size: 30.1 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:           1.03.a
28// Description:       User logic module.
29// Date:              Fri Nov 09 20:37:15 2012 (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    //I/O tied to top-level pins, connected to devices on board
58    output [6:0]    hexdisp_left,
59    output          hexdisp_left_dp,
60    output [6:0]    hexdisp_right,
61    output          hexdisp_right_dp,
62
63    output [3:0]    leds_red,
64    output [3:0]    leds_green,
65    output          rfa_led_red,
66    output          rfa_led_green,
67    output          rfb_led_red,
68    output          rfb_led_green,
69
70    input [3:0]     dipsw,
71    input           pb_u,
72    input           pb_m,
73    input           pb_d,
74   
75    input  [15:0]   usr_dbg_hdr_out, //on-chip signals driven out to debug header pins
76    output [15:0]   usr_dbg_hdr_in,  //debug header pins driven to on-chip signals
77    inout  [15:0] dbg_hdr,           //top-level IOBs for debug header pins
78
79    //I/O optionally connected to internal signals for non-software access to user I/O
80    input [6:0]     usr_hexdisp_left,
81    input           usr_hexdisp_left_dp,
82    input [6:0]     usr_hexdisp_right,
83    input           usr_hexdisp_right_dp,
84
85    input [3:0]     usr_leds_red,
86    input [3:0]     usr_leds_green,
87
88    input           usr_rfa_led_red,
89    input           usr_rfa_led_green,
90    input           usr_rfb_led_red,
91    input           usr_rfb_led_green,
92
93    output [3:0]    usr_dipsw,
94    output          usr_pb_u,
95    output          usr_pb_m,
96    output          usr_pb_d,
97
98    //Clock signal for DNA_PORT.CLK port (must be <100MHz)
99    input           DNA_Port_Clk,
100  // -- ADD USER PORTS ABOVE THIS LINE ---------------
101
102  // -- DO NOT EDIT BELOW THIS LINE ------------------
103  // -- Bus protocol ports, do not add to or delete
104input                                     Bus2IP_Clk,
105input                                     Bus2IP_Resetn,
106input      [C_SLV_DWIDTH-1 : 0]           Bus2IP_Data,
107input      [C_SLV_DWIDTH/8-1 : 0]         Bus2IP_BE,
108input      [C_NUM_REG-1 : 0]              Bus2IP_RdCE,
109input      [C_NUM_REG-1 : 0]              Bus2IP_WrCE,
110output     [C_SLV_DWIDTH-1 : 0]           IP2Bus_Data,
111output                                    IP2Bus_RdAck,
112output                                    IP2Bus_WrAck,
113output                                    IP2Bus_Error
114  // -- DO NOT EDIT ABOVE THIS LINE ------------------
115); // user_logic
116
117// -- ADD USER PARAMETERS BELOW THIS LINE ------------
118parameter HEXDISP_ACTIVE_HIGH = 0;
119parameter INCLUDE_DNA_READ_LOGIC = 1;
120// -- ADD USER PARAMETERS ABOVE THIS LINE ------------
121
122// -- DO NOT EDIT BELOW THIS LINE --------------------
123// -- Bus protocol parameters, do not add to or delete
124parameter C_NUM_REG                      = 15;
125parameter C_SLV_DWIDTH                   = 32;
126// -- DO NOT EDIT ABOVE THIS LINE --------------------
127
128//----------------------------------------------------------------------------
129// Implementation
130//----------------------------------------------------------------------------
131
132  // --USER nets declarations added here, as needed for user logic
133
134  // Nets for user logic slave model s/w accessible register example
135  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg0;
136  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg1;
137  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg2;
138  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg3;
139  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg4;
140  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg5;
141  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg6;
142  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg7;
143  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg8;
144  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg9;
145  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg10;
146  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg11;
147  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg12;
148  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg13;
149  reg        [C_SLV_DWIDTH-1 : 0]           slv_reg14;
150  wire       [14 : 0]                       slv_reg_write_sel;
151  wire       [14 : 0]                       slv_reg_read_sel;
152  reg        [C_SLV_DWIDTH-1 : 0]           slv_ip2bus_data;
153  wire                                      slv_read_ack;
154  wire                                      slv_write_ack;
155  integer                                   byte_index, bit_index;
156
157  // USER logic implementation added here
158
159  // ------------------------------------------------------
160  // Example code to read/write user logic slave model s/w accessible registers
161  //
162  // Note:
163  // The example code presented here is to show you one way of reading/writing
164  // software accessible registers implemented in the user logic slave model.
165  // Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
166  // to one software accessible register by the top level template. For example,
167  // if you have four 32 bit software accessible registers in the user logic,
168  // you are basically operating on the following memory mapped registers:
169  //
170  //    Bus2IP_WrCE/Bus2IP_RdCE   Memory Mapped Register
171  //                     "1000"   C_BASEADDR + 0x0
172  //                     "0100"   C_BASEADDR + 0x4
173  //                     "0010"   C_BASEADDR + 0x8
174  //                     "0001"   C_BASEADDR + 0xC
175  //
176  // ------------------------------------------------------
177
178  assign
179    slv_reg_write_sel = Bus2IP_WrCE[14:0],
180    slv_reg_read_sel  = Bus2IP_RdCE[14:0],
181    slv_write_ack     = Bus2IP_WrCE[0] || Bus2IP_WrCE[1] || Bus2IP_WrCE[2] || Bus2IP_WrCE[3] || Bus2IP_WrCE[4] || Bus2IP_WrCE[5] || Bus2IP_WrCE[6] || Bus2IP_WrCE[7] || Bus2IP_WrCE[8] || Bus2IP_WrCE[9] || Bus2IP_WrCE[10] || Bus2IP_WrCE[11] || Bus2IP_WrCE[12] || Bus2IP_WrCE[13] || Bus2IP_WrCE[14],
182    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] || Bus2IP_RdCE[8] || Bus2IP_RdCE[9] || Bus2IP_RdCE[10] || Bus2IP_RdCE[11] || Bus2IP_RdCE[12] || Bus2IP_RdCE[13] || Bus2IP_RdCE[14];
183
184  // implement slave model register(s)
185  always @( posedge Bus2IP_Clk )
186    begin
187
188      if ( Bus2IP_Resetn == 1'b0 )
189        begin
190          slv_reg0 <= 32'h3F000000; //Defaults: hex map mode on for both displays, RF LEDs controlled by usr_ ports
191          slv_reg1 <= 0;
192          slv_reg2 <= 0;
193          slv_reg3 <= 0;
194          slv_reg4 <= 0;
195          slv_reg5 <= 0;
196          slv_reg6 <= 0;
197          slv_reg7 <= 0;
198          slv_reg8 <= 0;
199          slv_reg9 <= 0;
200          slv_reg10 <= 0;
201          slv_reg11 <= 0;
202          slv_reg12 <= 0;
203          slv_reg13 <= 0;
204          slv_reg14 <= 0;
205        end
206      else
207        case ( slv_reg_write_sel )
208          15'b100000000000000 :
209            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
210              if ( Bus2IP_BE[byte_index] == 1 )
211                slv_reg0[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
212          15'b010000000000000 :
213            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
214              if ( Bus2IP_BE[byte_index] == 1 )
215                slv_reg1[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
216          15'b001000000000000 :
217            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
218              if ( Bus2IP_BE[byte_index] == 1 )
219                slv_reg2[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
220          15'b000100000000000 :
221            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
222              if ( Bus2IP_BE[byte_index] == 1 )
223                slv_reg3[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
224          15'b000010000000000 :
225            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
226              if ( Bus2IP_BE[byte_index] == 1 )
227                slv_reg4[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
228          15'b000001000000000 :
229            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
230              if ( Bus2IP_BE[byte_index] == 1 )
231                slv_reg5[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
232          15'b000000100000000 :
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                slv_reg6[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
236          15'b000000010000000 :
237            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
238              if ( Bus2IP_BE[byte_index] == 1 )
239                slv_reg7[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
240          15'b000000001000000 :
241            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
242              if ( Bus2IP_BE[byte_index] == 1 )
243                slv_reg8[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
244          15'b000000000100000 :
245            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
246              if ( Bus2IP_BE[byte_index] == 1 )
247                slv_reg9[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
248          15'b000000000010000 :
249            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
250              if ( Bus2IP_BE[byte_index] == 1 )
251                slv_reg10[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
252          15'b000000000001000 :
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                slv_reg11[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
256          15'b000000000000100 :
257            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
258              if ( Bus2IP_BE[byte_index] == 1 )
259                slv_reg12[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
260          15'b000000000000010 :
261            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
262              if ( Bus2IP_BE[byte_index] == 1 )
263                slv_reg13[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
264          15'b000000000000001 :
265            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
266              if ( Bus2IP_BE[byte_index] == 1 )
267                slv_reg14[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
268          default : begin
269            slv_reg0 <= slv_reg0;
270            slv_reg1 <= slv_reg1;
271            slv_reg2 <= slv_reg2;
272            slv_reg3 <= slv_reg3;
273            slv_reg4 <= slv_reg4;
274            slv_reg5 <= slv_reg5;
275            slv_reg6 <= slv_reg6;
276            slv_reg7 <= slv_reg7;
277            slv_reg8 <= slv_reg8;
278            slv_reg9 <= slv_reg9;
279            slv_reg10 <= slv_reg10;
280            slv_reg11 <= slv_reg11;
281            slv_reg12 <= slv_reg12;
282            slv_reg13 <= slv_reg13;
283            slv_reg14 <= slv_reg14;
284            end
285        endcase
286
287    end // SLAVE_REG_WRITE_PROC
288
289    wire pb_u_db;
290    wire pb_m_db;
291    wire pb_d_db;
292    wire [3:0] dipsw_db;
293    reg [56:0] fpga_dna_value = 57'b0;
294
295    wire [15:0] dbg_hdr_read_val;
296   
297  // implement slave model register read mux
298  always @*
299    begin 
300
301      case ( slv_reg_read_sel )
302        15'b100000000000000 : slv_ip2bus_data <= slv_reg0;
303        15'b010000000000000 : slv_ip2bus_data <= slv_reg1;
304        15'b001000000000000 : slv_ip2bus_data <= slv_reg2;
305        15'b000100000000000 : slv_ip2bus_data <= slv_reg3;
306        15'b000010000000000 : slv_ip2bus_data <= slv_reg4;
307        15'b000001000000000 : slv_ip2bus_data <= slv_reg5;
308        15'b000000100000000 : slv_ip2bus_data <= {25'b0, pb_u_db, pb_m_db, pb_d_db, dipsw_db};
309        15'b000000010000000 : slv_ip2bus_data <= slv_reg7;
310        15'b000000001000000 : slv_ip2bus_data <= slv_reg8;
311        15'b000000000100000 : slv_ip2bus_data <= slv_reg9;
312        15'b000000000010000 : slv_ip2bus_data <= slv_reg10;
313        15'b000000000001000 : slv_ip2bus_data <= fpga_dna_value[56:25];//25:56]; //32 LSB
314        15'b000000000000100 : slv_ip2bus_data <= {7'b0, fpga_dna_value[24:0]};//0:24]}; //25 MSB
315        15'b000000000000010 : slv_ip2bus_data <= {slv_reg13[31:16], dbg_hdr_read_val};
316        15'b000000000000001 : slv_ip2bus_data <= slv_reg14;
317        default : slv_ip2bus_data <= 0;
318      endcase
319
320    end // SLAVE_REG_READ_PROC
321
322  // ------------------------------------------------------------
323  // Example code to drive IP to Bus signals
324  // ------------------------------------------------------------
325
326assign IP2Bus_Data = (slv_read_ack == 1'b1) ? slv_ip2bus_data :  0 ;
327  assign IP2Bus_WrAck = slv_write_ack;
328  assign IP2Bus_RdAck = slv_read_ack;
329  assign IP2Bus_Error = 0;
330
331//User IO Implementation
332    /* Address map:
333        HDL is coded [31:0], adopting Xilinx's convention for AXI IPIF cores
334        All registers are 32-bits
335            regX[31]  maps to 0x80000000 in C driver
336            regX[0]   maps to 0x00000001 in C driver
337
338    0: Control RW
339        [31:30] = Reserved
340        [   29] = Left hex data mode (0=user supplies bit-per-segment; 1=user supplies 4-bit hex)   0x20000000
341        [   28] = Right hex data mode (0=user supplies bit-per-segment; 1=user supplies 4-bit hex)  0x10000000
342      Control source for LEDs: 0=software controlled, 1=usr_ port controlled
343        [27:24] = {rfb_red rfb_green rfa_red rfa_green} 0x0F000000
344        [23:16] = {leds_red leds_green}                 0x00FF0000
345        [15: 8] = {hexdisp_left{a b c d e f g dp}}      0x0000FF00
346        [ 7: 0] = {hexdisp_right{a b c d e f g dp}}     0x000000FF
347    1: Left hex display RW
348        [31: 9] = reserved
349        [    8] = DP (controlled directly; doesn't depend on data mode) 0x100
350        [ 6: 0] = Data value ([6:4] ignored when data mode = 1)         0x03F
351    2: Right hex display RW
352        [31: 9] = reserved
353        [    8] = DP (controlled directly; doesn't depend on data mode) 0x100
354        [ 6: 0] = Data value ([6:4] ignored when data mode = 1)         0x03F
355    3: Red user LEDs RW
356        [31: 4] = reserved
357        [ 3: 0] = Data value (1=LED illuminated) 0xF, with 0x1 mapped to lowest LED
358    4: Green user LEDs RW
359        [31: 4] = reserved
360        [ 3: 0] = Data value (1=LED illuminated) 0xF, with 0x1 mapped to lowest LED
361    5: RF LEDs RW
362        [31: 4] = reserved
363        [    3] = rfb_red   0x8
364        [    2] = rfb_green 0x4
365        [    1] = rfa_red   0x2
366        [    0] = rfa_green 0x1
367    6: Switch/button inputs RO
368        [31: 7] = reserved
369        [    6] = pb_up         0x40
370        [    5] = pb_mid        0x20
371        [    4] = pb_down       0x10
372        [ 3: 0] = DIP switch    0x0F (with 0x1 mapped to right-most switch)
373
374    7: PWM Gen Param: PWM period RW
375        [31:16] = PWN period
376        [15: 0] = PWM output deassert thresh
377
378    8: PWM Gen Param: PWM output deassert thresh RW
379        [31:29] = reserved
380        [28: 0] =
381       
382    9: PWM Gen Param: PWM ramp step RW
383        [31]    = ramp enabled
384        [30:16] = pwm_param_ramp_min
385        [15: 0] = pwm_param_ramp_max
386
387    10: HW Output control sel RW
388        [31:28] = Reserved
389      HW Control source for LEDs: 0=usr_ ports, 1=pwm gen (same ctrlSrc masks as reg0)
390        [27:24] = {rfb_red rfb_green rfa_red rfa_green} 0x0F000000
391        [23:16] = {leds_red leds_green}                 0x00FF0000
392        [15: 8] = {hexdisp_left{a b c d e f g dp}}      0x0000FF00
393        [ 7: 0] = {hexdisp_right{a b c d e f g dp}}     0x000000FF
394
395    11: FPGA DNA LSB
396        [31: 0] = 32LSB of FPGA DNA
397
398    12: FPGA DNA MSB
399        [31:25] = reserved
400        [24: 0] = FPGA DNA 25MSB
401       
402    13: Debug Header IO
403        [31:15] = Reserved
404        [15: 0] = IOB data. Bits corresponding to inputs contain input values. Bits
405                   corresponding to outputs contain output values. Bits corresponding to
406                   unused pins contain would-be output values (whatever software last wrote).
407    14: Debug Header IO control
408        [31:16] = IOB direction control, 1 bit per pin; only C_DBG_HDR_WIDTH LSB are used
409        [15: 0] = Debug header output source select (0=sw via reg13, 1=usr_dbg_hdr_out port)
410   */
411    integer ii;
412
413    wire [27:0] all_outputs_ctrl_source;
414    wire [27:0] all_outputs_hw_ctrl_source;
415    wire [27:0] all_outputs_sw_val;
416    wire [27:0] all_outputs_hw_val;
417    reg  [27:0] all_outputs;
418    reg  [27:0] all_outputs_d1;
419
420    reg  [27:0] all_outputs_d2;     
421
422    wire [6:0] leftHex_mapped;
423    wire [6:0] rightHex_mapped;
424
425    wire [6:0] leftHex_sw_val;
426    wire [6:0] rightHex_sw_val;
427
428    reg [7:0] pb_u_d = 0;
429    reg [7:0] pb_m_d = 0;
430    reg [7:0] pb_d_d = 0;
431    reg [7:0] dipsw_d0 = 0;
432    reg [7:0] dipsw_d1 = 0;
433    reg [7:0] dipsw_d2 = 0;
434    reg [7:0] dipsw_d3 = 0;
435
436
437    //PWM generator
438    reg [9:0] pwm_clock_counter = 0;
439    wire      pwm_clock_en;
440    assign pwm_clock_en = (pwm_clock_counter == 0);
441   
442    wire [15:0] pwm_param_period;
443    wire [15:0] pwm_param_thresh_sw;
444    wire [15:0] pwm_param_thresh;
445    reg  [15:0] pwm_param_thresh_d;
446
447    wire        pwm_param_ramp_en;
448
449    wire [14:0] pwm_param_ramp_min;
450    wire [15:0] pwm_param_ramp_max;
451
452    wire        pwm_ramp_count_dir_toggle;
453    reg pwm_ramp_count_dir_toggle_d = 0;
454
455    reg         pwm_ramp_count_dir = 0;
456   
457    assign pwm_ramp_count_dir_toggle = (((pwm_ramp_counter > pwm_param_ramp_max) | (pwm_ramp_counter < pwm_param_ramp_min)));
458   
459    assign pwm_param_period     = slv_reg7[31:16];
460    assign pwm_param_thresh_sw  = slv_reg7[15:0];
461
462    assign pwm_param_ramp_en    = slv_reg9[31];
463    assign pwm_param_ramp_min   = slv_reg9[30:16];
464    assign pwm_param_ramp_max   = slv_reg9[15:0];
465   
466    assign pwm_param_thresh = pwm_param_ramp_en ? pwm_ramp_counter : pwm_param_thresh_sw;
467   
468    reg [15:0] pwm_period_counter = 0;
469    reg [15:0] pwm_ramp_counter = 0;
470
471    reg pwm_out = 0;
472   
473    // Debug header
474    wire [15:0] dbg_hdr_dir;
475    wire [15:0] dbg_hdr_src_sel;
476   
477    reg [15:0] dbg_hdr_dir_d1;
478    reg [15:0] dbg_hdr_dir_d2;
479
480    reg [15:0] dbg_hdr_src_sel_d1;
481    reg [15:0] dbg_hdr_src_sel_d2;
482
483    reg [15:0] dbg_hdr_sw_dout_d1;
484    reg [15:0] dbg_hdr_sw_dout_d2;
485    reg [15:0] dbg_hdr_hw_dout_d1;
486    reg [15:0] dbg_hdr_hw_dout_d2;
487
488    wire [15:0] dbg_hdr_din;
489    wire [15:0] dbg_hdr_pin_in;
490    reg  [15:0] dbg_hdr_din_d1;
491    reg  [15:0] dbg_hdr_din_d2;
492   
493    // Debug header logic
494    assign dbg_hdr_src_sel = slv_reg14[15:0];
495    assign dbg_hdr_dir = slv_reg14[31:16];
496
497    assign dbg_hdr_read_val = dbg_hdr_din_d2; //software read value
498    assign usr_dbg_hdr_in = dbg_hdr_read_val; //output to user logic
499 
500    // Pipeline regs for register bits. These registers reduce timing challenge in routing
501    //  signals between WARP v3 debug header and the shared AXI interconnect data bus
502    always @(posedge Bus2IP_Clk)
503    begin
504        dbg_hdr_dir_d1 <= dbg_hdr_dir;
505        dbg_hdr_dir_d2 <= dbg_hdr_dir_d1;
506
507        dbg_hdr_src_sel_d1 <= dbg_hdr_src_sel;
508        dbg_hdr_src_sel_d2 <= dbg_hdr_src_sel_d1;
509       
510        dbg_hdr_sw_dout_d1 <= slv_reg13[15:0];
511        dbg_hdr_sw_dout_d2 <= dbg_hdr_sw_dout_d1;
512
513        dbg_hdr_hw_dout_d1 <= usr_dbg_hdr_out;
514        dbg_hdr_hw_dout_d2 <= dbg_hdr_hw_dout_d1;
515       
516        dbg_hdr_din_d1 <= dbg_hdr_din;
517        dbg_hdr_din_d2 <= dbg_hdr_din_d1;
518    end
519   
520    //Generate array of IOBs for top-level debug header pins
521    // Each pin has individually controlled IOB
522    //  Tri-state sets direction (software sets tri-state value per pin)
523    //  IOB input (fabric -> pin) driven by hw or sw; source selected by software
524    //  IOB output (pin -> fabric) drives sw register and usr_ output port
525    genvar idx;
526    generate
527        for(idx=0; idx<16; idx=idx+1) begin: DBG_HDR_IOBS
528            // Treat pin as input if hdr_dir == 1
529            //  For inputs tri-state IOB (assign output = Z) and capture input in slv_reg13
530            //  For outputs enable IOB (drive output from slv_reg13), and return output value
531            IOBUF iob_dbg_hdr (
532                .IO(dbg_hdr[idx]),  //Top-level pin
533                .O(dbg_hdr_pin_in[idx]), //IOB -> Fabric (when IOB is input)
534                .I(dbg_hdr_src_sel_d2[idx] ? dbg_hdr_hw_dout_d2[idx] : dbg_hdr_sw_dout_d2[idx]), //Fabric -> IOB (when IOB is output)
535                .T(dbg_hdr_dir_d2[idx])   //Tri-state (1=use IOB as input)
536            );
537           
538            // Software accessible register captures input value for inputs and output value for outputs
539            assign dbg_hdr_din[idx] = dbg_hdr_dir_d2[idx] ? dbg_hdr_pin_in[idx] : (dbg_hdr_src_sel_d2[idx] ? dbg_hdr_hw_dout_d2[idx] : dbg_hdr_sw_dout_d2[idx]);
540        end
541    endgenerate 
542
543    always @(posedge Bus2IP_Clk)
544    begin
545        pwm_clock_counter <= pwm_clock_counter + 1;
546
547        if(pwm_period_counter >= pwm_param_period)
548            pwm_period_counter <= 0;
549        else if(pwm_clock_en)
550            pwm_period_counter <= pwm_period_counter + 1;
551
552        pwm_param_thresh_d <= pwm_param_thresh;
553       
554        pwm_out <= (pwm_period_counter < pwm_param_thresh_d);
555    end
556
557    always @(posedge Bus2IP_Clk)
558    begin
559        pwm_ramp_count_dir_toggle_d <= pwm_ramp_count_dir_toggle;
560
561        //pwm_ramp_count_dir=0 counts up
562        if(~pwm_param_ramp_en)
563            pwm_ramp_counter <= {1'b0,pwm_param_ramp_min};
564        else if(pwm_clock_en & (pwm_period_counter==0))
565            if(pwm_ramp_count_dir)
566                pwm_ramp_counter <= pwm_ramp_counter + 16'hFFFE;
567            else
568                pwm_ramp_counter <= pwm_ramp_counter + 1'b1;
569
570        if(~pwm_param_ramp_en)
571            pwm_ramp_count_dir <= 0;
572        else if(pwm_ramp_count_dir_toggle & ~pwm_ramp_count_dir_toggle_d)
573            pwm_ramp_count_dir <= ~pwm_ramp_count_dir;
574
575    end
576
577   
578    //Shift registers for debouncing mechanical inputs
579    always @(posedge Bus2IP_Clk)
580    begin
581        pb_u_d[7:0] <= {pb_u_d[6:0], pb_u};
582        pb_m_d[7:0] <= {pb_m_d[6:0], pb_m};
583        pb_d_d[7:0] <= {pb_d_d[6:0], pb_d};
584        dipsw_d0[7:0] <= {dipsw_d0[6:0], dipsw[0]};
585        dipsw_d1[7:0] <= {dipsw_d1[6:0], dipsw[1]};
586        dipsw_d2[7:0] <= {dipsw_d2[6:0], dipsw[2]};
587        dipsw_d3[7:0] <= {dipsw_d3[6:0], dipsw[3]};
588    end
589   
590    //Assert debounced signals only if inputs are high 8 consecutive cycles
591    assign pb_u_db = (pb_u_d == 8'hff);
592    assign pb_m_db = (pb_m_d == 8'hff);
593    assign pb_d_db = (pb_d_d == 8'hff);
594
595    //Swap MSB:LSB here, to undo endian swaps relative to schematic labels
596    assign dipsw_db = {(dipsw_d0==8'hff), (dipsw_d1==8'hff), (dipsw_d2==8'hff), (dipsw_d3==8'hff)};
597   
598    //Logic to map 4-bit hex value to 7-bit value for hex display
599    sevenSegmentMap leftHexMap  (.data(slv_reg1[3:0]), .disp(leftHex_mapped));
600    sevenSegmentMap rightHexMap (.data(slv_reg2[3:0]), .disp(rightHex_mapped));
601
602    //Select which 7-bit value is used as the software-supplied value for hex displays
603    // User either supplies 4-bit value to be interpretted as hex value
604    //  or raw 7-bit (bit-per-diode) value
605    assign leftHex_sw_val =  slv_reg0[29] ? leftHex_mapped :  slv_reg1[6:0];
606    assign rightHex_sw_val = slv_reg0[28] ? rightHex_mapped : slv_reg2[6:0];
607
608    //Extract the mux control values from the software register
609    assign all_outputs_ctrl_source    = slv_reg0[27:0];
610    assign all_outputs_hw_ctrl_source = slv_reg10[27:0];
611
612    //Extract and concatenate the software-controlled output values
613    assign all_outputs_sw_val[27:0] = {
614        slv_reg5[3],            //[27]      rgb_red LED
615        slv_reg5[2],            //[26]      rgb_green LED
616        slv_reg5[1],            //[25]      rga_red LED
617        slv_reg5[0],            //[24]      rga_green LED
618        slv_reg4[3:0],          //[23:20]   green LEDs
619        slv_reg3[3:0],          //[19:16]   red LEDs
620        slv_reg2[8],            //[15]      right hex DP
621        rightHex_sw_val[6:0],   //[14:8]    right hex mapped
622        slv_reg1[8],            //[7]       left hex DP
623        leftHex_sw_val[6:0]     //[6:0]     left hex mapped
624    };
625
626    //Concatenate the top-level inputs for hardware-controlled output values
627    assign all_outputs_hw_val[27:24] = {usr_rfb_led_red, usr_rfb_led_green, usr_rfa_led_red, usr_rfa_led_green};
628    assign all_outputs_hw_val[23:16] = {usr_leds_green, usr_leds_red};
629    assign all_outputs_hw_val[15:8] = {usr_hexdisp_right_dp, usr_hexdisp_right};
630    assign all_outputs_hw_val[7:0] = {usr_hexdisp_left_dp, usr_hexdisp_left};
631
632    //Mux between hardware and software control for each output
633    // Source control = 0 -> Software register bit controls output
634    // Source control = 1 -> Hardware control
635    //   Hardware control mode = 0 -> usr_ port controls
636    //   Hardware control mode = 1 -> pwm module controls
637    always @*
638    begin
639    for(ii=0; ii<28; ii=ii+1)
640        all_outputs[ii] = all_outputs_ctrl_source[ii] ? (all_outputs_hw_ctrl_source[ii] ? pwm_out : all_outputs_hw_val[ii]) : all_outputs_sw_val[ii];
641    end
642
643    always @(posedge Bus2IP_Clk)
644    begin
645        all_outputs_d1 <= all_outputs;
646       
647        // HDL parameter HEXDISP_ACTIVE_HIGH defines the type at build-time
648        // User values are always interpreted as 1==illuminated
649        // Mux on active high/low here so _d2 DFFs can be packed into IOBs
650        all_outputs_d2[15:0] <= HEXDISP_ACTIVE_HIGH ? all_outputs_d1[15:0] : ~all_outputs_d1[15:0];
651        all_outputs_d2[27:16] <= all_outputs_d1[27:16];
652    end
653   
654    //Map the mux outputs to the top-level outputs
655    assign {rfb_led_red, rfb_led_green, rfa_led_red, rfa_led_green} = all_outputs_d2[27:24];
656
657    assign leds_green[3:0] = all_outputs_d2[23:20];
658    assign leds_red[3:0] =   all_outputs_d2[19:16];
659
660    assign hexdisp_left_dp   = all_outputs_d2[7];
661    assign hexdisp_left[6:0] = all_outputs_d2[6:0];
662
663    assign hexdisp_right_dp   = all_outputs_d2[15];
664    assign hexdisp_right[6:0] = all_outputs_d2[14:8];
665
666    //Assign the usr_ output ports to the de-bounced top-level inputs
667    assign usr_dipsw[3:0] = dipsw_db[3:0];
668    assign usr_pb_u = pb_u_db;
669    assign usr_pb_m = pb_m_db;
670    assign usr_pb_d = pb_d_db;
671
672    generate
673    if(INCLUDE_DNA_READ_LOGIC) begin
674        wire dna_port_read, dna_port_shift, dna_port_clk_gated, dna_port_dout;
675        //Instantiate the DNA_PORT module, for reading the FPGA's unique ID
676        // Two MSB are always [1 0]? Accordint to isim at least
677        DNA_PORT #(.SIM_DNA_VALUE(57'h123456789abcdef)) dna_port_inst (
678            .DIN(1'b0),
679            .READ(dna_port_read),
680            .SHIFT(dna_port_shift),
681            .CLK(dna_port_clk_gated),
682            .DOUT(dna_port_dout)
683        );
684       
685        reg [6:0] dna_read_counter = 7'b0;
686
687        //Only clock the DNA_PORT primitive while actively shifting data out
688        assign dna_port_clk_gated = (DNA_Port_Clk & (dna_read_counter>7'd60) & (dna_read_counter<7'h7f));
689
690        //Count-limited counter, that starts at configuration and runs exactly once
691        always @(posedge DNA_Port_Clk)
692        begin
693            if(dna_read_counter == 7'h7f)
694                dna_read_counter <= 7'h7f;
695            else
696                dna_read_counter <= dna_read_counter + 1;
697        end
698
699        //dna read states, as function of dna_read_counter value:
700        //  0-63: Do nothing (just in case things needs to settle before DNA_PORT is accessible)
701        //    64: Toggle READ signal (loads DNA value into DNA_PORT 57-bit shift register)
702        //    65: Read DNA[0] from shift register DOUT; assert SHIFT
703        //66-121: Read DNA[1:56] from shif register DOUT; SHIFT stays asserted
704        //   122: De-assert SHIFT and READ
705       
706        assign dna_port_read = (dna_read_counter == 7'd63);
707        assign dna_port_shift = ((dna_read_counter>= 7'd65) && (dna_read_counter<=122));
708       
709        //Capture the shift register output in a single big register
710        wire dna_capt;
711        assign dna_capt = ((dna_read_counter>= 7'd65) && (dna_read_counter<=121));
712        always @(posedge DNA_Port_Clk)
713        begin
714            if (dna_capt)
715                fpga_dna_value[dna_read_counter-7'd65] = dna_port_dout;
716        end
717    end
718    endgenerate
719 
720endmodule
721
722
723module sevenSegmentMap
724(
725    input       [3:0]   data,
726    output  reg [6:0]   disp
727);
728
729always @(data[3:0])
730    case (data[3:0])
731    4'b0000 : disp <= ~(7'b1000000);   // 0
732    4'b0001 : disp <= ~(7'b1111001);   // 1
733    4'b0010 : disp <= ~(7'b0100100);   // 2
734    4'b0011 : disp <= ~(7'b0110000);   // 3
735    4'b0100 : disp <= ~(7'b0011001);   // 4
736    4'b0101 : disp <= ~(7'b0010010);   // 5
737    4'b0110 : disp <= ~(7'b0000010);   // 6
738    4'b0111 : disp <= ~(7'b1111000);   // 7
739    4'b1000 : disp <= ~(7'b0000000);   // 8
740    4'b1001 : disp <= ~(7'b0010000);   // 9
741    4'b1010 : disp <= ~(7'b0001000);   // A
742    4'b1011 : disp <= ~(7'b0000011);   // b
743    4'b1100 : disp <= ~(7'b1000110);   // C
744    4'b1101 : disp <= ~(7'b0100001);   // d
745    4'b1110 : disp <= ~(7'b0000110);   // E
746    4'b1111 : disp <= ~(7'b0001110);   // F
747    default : disp <=  (7'b0000000);
748    endcase
749
750endmodule
Note: See TracBrowser for help on using the repository browser.