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

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

Working version of updated userio core+driver with debug header IO support

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