1/////////////////////////////////////////////////////////////////////
2//
3// Copyright 2018-2019 Ettus Research, A National Instruments Brand
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6//
7// Module: e31x
8// Description:
9//   E31x Top Level Idle
10//
11/////////////////////////////////////////////////////////////////////
12
13module e31x (
14
15  // PS Connections
16  inout [53:0]  MIO,
17  input         PS_SRSTB,
18  input         PS_CLK,
19  input         PS_PORB,
20  inout         DDR_CLK,
21  inout         DDR_CLK_N,
22  inout         DDR_CKE,
23  inout         DDR_CS_N,
24  inout         DDR_RAS_N,
25  inout         DDR_CAS_N,
26  inout         DDR_WEB,
27  inout [2:0]   DDR_BANKADDR,
28  inout [14:0]  DDR_ADDR,
29  inout         DDR_ODT,
30  inout         DDR_DRSTB,
31  inout [31:0]  DDR_DQ,
32  inout [3:0]   DDR_DM,
33  inout [3:0]   DDR_DQS,
34  inout [3:0]   DDR_DQS_N,
35  inout         DDR_VRP,
36  inout         DDR_VRN,
37
38  //AVR SPI IO
39  input         AVR_CS_R,
40  output        AVR_IRQ,
41  output        AVR_MISO_R,
42  input         AVR_MOSI_R,
43  input         AVR_SCK_R,
44
45  input         ONSWITCH_DB,
46
47  // pps connections
48  input         GPS_PPS,
49  input         PPS_EXT_IN,
50
51  // gpios, change to inout somehow
52  inout [5:0]   PL_GPIO,
53
54  // RF Board connections
55  inout [99:0] DB_IO
56);
57
58  // Clocks
59  wire bus_clk;
60  wire radio_clk;
61  wire reg_clk;
62  wire clk40;
63  wire FCLK_CLK0;
64  wire FCLK_CLK1;
65
66  // Resets
67  wire global_rst;
68  wire bus_rst;
69  wire radio_rst;
70  wire reg_rstn;
71  wire clk40_rst;
72  wire clk40_rstn;
73  wire FCLK_RESET0_N;
74
75  // PMU
76  wire [31:0] m_axi_pmu_araddr;
77  wire [2:0]  m_axi_pmu_arprot;
78  wire        m_axi_pmu_arready;
79  wire        m_axi_pmu_arvalid;
80  wire [31:0] m_axi_pmu_awaddr;
81  wire [2:0]  m_axi_pmu_awprot;
82  wire        m_axi_pmu_awready;
83  wire        m_axi_pmu_awvalid;
84  wire        m_axi_pmu_bready;
85  wire [1:0]  m_axi_pmu_bresp;
86  wire        m_axi_pmu_bvalid;
87  wire [31:0] m_axi_pmu_rdata;
88  wire        m_axi_pmu_rready;
89  wire [1:0]  m_axi_pmu_rresp;
90  wire        m_axi_pmu_rvalid;
91  wire [31:0] m_axi_pmu_wdata;
92  wire        m_axi_pmu_wready;
93  wire [3:0]  m_axi_pmu_wstrb;
94  wire        m_axi_pmu_wvalid;
95
96  /////////////////////////////////////////////////////////////////////
97  //
98  // Resets:
99  //  - PL - Bus Reset
100  //         Radio Reset
101  //  - PS - FCLK_RESET0_N --> clk40_rst(n)
102  //
103  //////////////////////////////////////////////////////////////////////
104
105  // Synchronous reset for the bus_clk domain
106  reset_sync bus_reset_gen (
107    .clk(bus_clk),
108    .reset_in(~FCLK_RESET0_N),
109    //.reset_in(~clocks_locked),
110    .reset_out(bus_rst)
111  );
112
113
114  // PS-based Resets //
115  //
116  // Synchronous reset for the clk40 domain. This is derived from the PS reset 0.
117  reset_sync clk40_reset_gen (
118    .clk(clk40),
119    .reset_in(~FCLK_RESET0_N),
120    .reset_out(clk40_rst)
121  );
122  // Invert for various modules.
123  assign clk40_rstn = ~clk40_rst;
124  assign reg_rstn = clk40_rstn;
125
126  /////////////////////////////////////////////////////////////////////
127  //
128  // Clocks and PPS
129  //
130  /////////////////////////////////////////////////////////////////////
131
132  wire [1:0] pps_select;
133
134  assign clk40   = FCLK_CLK1;   // 40 MHz
135  assign bus_clk = FCLK_CLK0;   // 100 MHz
136  assign reg_clk = clk40;
137
138  reg [2:0] pps_reg;
139
140  wire pps_ext = PPS_EXT_IN;
141  wire gps_pps = GPS_PPS;
142
143  // connect PPS input to GPIO so ntpd can use it
144  always @ (posedge bus_clk)
145    pps_reg <= bus_rst ? 3'b000 : {pps_reg[1:0], GPS_PPS};
146  assign ps_gpio_in[8] = pps_reg[2]; // 62
147
148  /////////////////////////////////////////////////////////////////////
149  //
150  // Power Button
151  //
152  //////////////////////////////////////////////////////////////////////
153
154  // register the debounced onswitch signal to detect edges,
155  // Note: ONSWITCH_DB is low active
156  reg [1:0] onswitch_edge;
157  always @ (posedge bus_clk)
158    onswitch_edge <= bus_rst ? 2'b00 : {onswitch_edge[0], ONSWITCH_DB};
159
160  wire button_press = ~ONSWITCH_DB & onswitch_edge[0] & onswitch_edge[1];
161  wire button_release = ONSWITCH_DB & ~onswitch_edge[0] & ~onswitch_edge[1];
162
163  // stretch the pulse so IRQs don't get lost
164  reg [7:0] button_press_reg, button_release_reg;
165  always @ (posedge bus_clk)
166    if (bus_rst) begin
167      button_press_reg <= 8'h00;
168      button_release_reg <= 8'h00;
169    end else begin
170      button_press_reg <= {button_press_reg[6:0], button_press};
171      button_release_reg <= {button_release_reg[6:0], button_release};
172    end
173
174  wire button_press_irq = |button_press_reg;
175  wire button_release_irq = |button_release_reg;
176
177  /////////////////////////////////////////////////////////////////////
178  //
179  // Interrupts Fabric to PS
180  //
181  //////////////////////////////////////////////////////////////////////
182
183  wire [15:0] IRQ_F2P;
184  wire pmu_irq;
185  assign IRQ_F2P = {12'b0,
186                    pmu_irq,            // Interrupt 32
187                    button_release_irq, // Interrupt 31
188                    button_press_irq,   // Interrupt 30
189                    1'b0};
190
191  /////////////////////////////////////////////////////////////////////
192  //
193  // PS Connections
194  //
195  //////////////////////////////////////////////////////////////////////
196
197  wire [63:0] ps_gpio_in;
198  wire [63:0] ps_gpio_out;
199  wire [63:0] ps_gpio_tri;
200
201  e31x_ps_bd e31x_ps_bd_inst (
202
203    // DDR Interface
204    .DDR_VRN(DDR_VRN),
205    .DDR_VRP(DDR_VRP),
206    .DDR_addr(DDR_ADDR),
207    .DDR_ba(DDR_BANKADDR),
208    .DDR_cas_n(DDR_CAS_N),
209    .DDR_ck_n(DDR_CLK_N),
210    .DDR_ck_p(DDR_CLK),
211    .DDR_cke(DDR_CKE),
212    .DDR_cs_n(DDR_CS_N),
213    .DDR_dm(DDR_DM),
214    .DDR_dq(DDR_DQ),
215    .DDR_dqs_n(DDR_DQS_N),
216    .DDR_dqs_p(DDR_DQS),
217    .DDR_odt(DDR_ODT),
218    .DDR_ras_n(DDR_RAS_N),
219    .DDR_reset_n(DDR_RESET_N),
220    .DDR_we_n(DDR_WE_N),
221
222    // Clocks
223    .FCLK_CLK0(FCLK_CLK0),
224    .FCLK_CLK1(FCLK_CLK1),
225    .FCLK_CLK2(),
226    .FCLK_CLK3(),
227
228    // Resets
229    .FCLK_RESET0_N(FCLK_RESET0_N),
230
231    // GPIO
232    .GPIO_0_tri_i(ps_gpio_in),
233    .GPIO_0_tri_o(ps_gpio_out),
234    .GPIO_0_tri_t(ps_gpio_tri),
235
236    // Interrupts
237    .IRQ_F2P(IRQ_F2P),
238
239    // MIO
240    .MIO(MIO),
241
242    .PS_CLK(PS_CLK),
243    .PS_PORB(PS_PORB),
244    .PS_SRSTB(PS_SRSTB),
245
246    // SPI
247    .SPI0_MISO_I(),
248    .SPI0_MISO_O(),
249    .SPI0_MISO_T(),
250    .SPI0_MOSI_I(),
251    .SPI0_MOSI_O(),
252    .SPI0_MOSI_T(),
253    .SPI0_SCLK_I(),
254    .SPI0_SCLK_O(),
255    .SPI0_SCLK_T(),
256    .SPI0_SS1_O(),
257    .SPI0_SS2_O(),
258    .SPI0_SS_I(),
259    .SPI0_SS_O(),
260    .SPI0_SS_T(),
261
262    .SPI1_MISO_I(),
263    .SPI1_MISO_O(),
264    .SPI1_MISO_T(),
265    .SPI1_MOSI_I(),
266    .SPI1_MOSI_O(),
267    .SPI1_MOSI_T(),
268    .SPI1_SCLK_I(),
269    .SPI1_SCLK_O(),
270    .SPI1_SCLK_T(),
271    .SPI1_SS1_O(),
272    .SPI1_SS2_O(),
273    .SPI1_SS_I(),
274    .SPI1_SS_O(),
275    .SPI1_SS_T(),
276
277    // USB
278    .USBIND_0_port_indctl(),
279    .USBIND_0_vbus_pwrfault(),
280    .USBIND_0_vbus_pwrselect(),
281
282    .bus_clk(bus_clk),
283    .bus_rstn(~bus_rst),
284    .clk40(clk40),
285    .clk40_rstn(clk40_rstn),
286    .S_AXI_GP0_ACLK(clk40),
287    .S_AXI_GP0_ARESETN(clk40_rstn),
288
289    // XBAR Regport
290    .m_axi_xbar_araddr(),
291    .m_axi_xbar_arprot(),
292    .m_axi_xbar_arready(),
293    .m_axi_xbar_arvalid(),
294    .m_axi_xbar_awaddr(),
295    .m_axi_xbar_awprot(),
296    .m_axi_xbar_awready(),
297    .m_axi_xbar_awvalid(),
298    .m_axi_xbar_bready(),
299    .m_axi_xbar_bresp(),
300    .m_axi_xbar_bvalid(),
301    .m_axi_xbar_rdata(),
302    .m_axi_xbar_rready(),
303    .m_axi_xbar_rresp(),
304    .m_axi_xbar_rvalid(),
305    .m_axi_xbar_wdata(),
306    .m_axi_xbar_wready(),
307    .m_axi_xbar_wstrb(),
308    .m_axi_xbar_wvalid(),
309
310    // PMU
311    .m_axi_pmu_araddr(m_axi_pmu_araddr),
312    .m_axi_pmu_arprot(m_axi_pmu_arprot),
313    .m_axi_pmu_arready(m_axi_pmu_arready),
314    .m_axi_pmu_arvalid(m_axi_pmu_arvalid),
315    .m_axi_pmu_awaddr(m_axi_pmu_awaddr),
316    .m_axi_pmu_awprot(m_axi_pmu_awprot),
317    .m_axi_pmu_awready(m_axi_pmu_awready),
318    .m_axi_pmu_awvalid(m_axi_pmu_awvalid),
319    .m_axi_pmu_bready(m_axi_pmu_bready),
320    .m_axi_pmu_bresp(m_axi_pmu_bresp),
321    .m_axi_pmu_bvalid(m_axi_pmu_bvalid),
322    .m_axi_pmu_rdata(m_axi_pmu_rdata),
323    .m_axi_pmu_rready(m_axi_pmu_rready),
324    .m_axi_pmu_rresp(m_axi_pmu_rresp),
325    .m_axi_pmu_rvalid(m_axi_pmu_rvalid),
326    .m_axi_pmu_wdata(m_axi_pmu_wdata),
327    .m_axi_pmu_wready(m_axi_pmu_wready),
328    .m_axi_pmu_wstrb(m_axi_pmu_wstrb),
329    .m_axi_pmu_wvalid(m_axi_pmu_wvalid),
330
331    // DMA
332    .s_axis_dma_tdata(),
333    .s_axis_dma_tkeep(),
334    .s_axis_dma_tlast(),
335    .s_axis_dma_tready(),
336    .s_axis_dma_tvalid(1'b0),
337    .m_axis_dma_tdata(),
338    .m_axis_dma_tkeep(),
339    .m_axis_dma_tlast(),
340    .m_axis_dma_tready(1'b1),
341    .m_axis_dma_tvalid()
342  );
343
344  /////////////////////////////////////////////////////////////////////
345  //
346  // PMU
347  //
348  //////////////////////////////////////////////////////////////////////
349
350  axi_pmu inst_axi_pmu (
351    .s_axi_aclk(clk40),  // TODO: Original design used bus_clk
352    .s_axi_areset(clk40_rst),
353
354    .ss(AVR_CS_R),
355    .mosi(AVR_MOSI_R),
356    .sck(AVR_SCK_R),
357    .miso(AVR_MISO_R),
358
359    // AXI4-Lite: Write address port (domain: s_axi_aclk)
360    .s_axi_awaddr(m_axi_pmu_awaddr),
361    .s_axi_awvalid(m_axi_pmu_awvalid),
362    .s_axi_awready(m_axi_pmu_awready),
363    // AXI4-Lite: Write data port (domain: s_axi_aclk)
364    .s_axi_wdata(m_axi_pmu_wdata),
365    .s_axi_wstrb(m_axi_pmu_wstrb),
366    .s_axi_wvalid(m_axi_pmu_wvalid),
367    .s_axi_wready(m_axi_pmu_wready),
368    // AXI4-Lite: Write response port (domain: s_axi_aclk)
369    .s_axi_bresp(m_axi_pmu_bresp),
370    .s_axi_bvalid(m_axi_pmu_bvalid),
371    .s_axi_bready(m_axi_pmu_bready),
372    // AXI4-Lite: Read address port (domain: s_axi_aclk)
373    .s_axi_araddr(m_axi_pmu_araddr),
374    .s_axi_arvalid(m_axi_pmu_arvalid),
375    .s_axi_arready(m_axi_pmu_arready),
376    // AXI4-Lite: Read data port (domain: s_axi_aclk)
377    .s_axi_rdata(m_axi_pmu_rdata),
378    .s_axi_rresp(m_axi_pmu_rresp),
379    .s_axi_rvalid(m_axi_pmu_rvalid),
380    .s_axi_rready(m_axi_pmu_rready),
381
382    .s_axi_irq(pmu_irq)
383  );
384
385  assign AVR_IRQ = 1'b0;
386
387  localparam DB_E31X_IDLE_OUT = {
388    1'b0,              /* DB_EXP_18_24 (99) */
389    13'b0000000000000, /* leds & rx bandsels */
390    1'b0,              /* CAT_FB_CLK (85) */
391    1'b0,              /* CAT_TX_FRAME (84) */
392    1'b0,              /* CAT_RX_DATA_CLK (83) */
393    25'b0000_0000_0000_0000_0000_0000_0, /* CAT_RX_FRAME(81), CAT_P0 & CAT_P1 (58)*/
394    1'b0,              /* CAT_SYNC(57) */
395    4'b0000,           /* CAT_ENAGC(56), CAT_BBCLK_OUT (55), CAT_ENABLE(54), CAT_TXNRX(53) */
396    3'b000,            /* DB_EXP_1_8_V_{33,34,32} */
397    2'b00,             /* CAT_CTRL_IN[1:0] (49,48) */
398    1'b0,              /* CAT_MISO (47) */
399    4'b0000,           /* CAT_{MOSI,SCLK,CS,RESETn) (46,45, 44, 43) */
400    1'b0,              /* DB_1_8V_31 (42) */
401    8'h00,             /* CAT_CTRL_OUT (41:34) */
402    1'b0,              /* DB_1_8V_11 (33) */
403    1'b0,              /* CAT_CTRL_IN3 (32) */
404    1'b0,              /* DB_1_8V_10 (31) */
405    1'b0,              /* CAT_CTRL_IN2 (30) */
406    1'b0,              /* DB_1_8V_9 (29) */
407    1'b0,              /* VCRX2_V2 (28) */
408    1'b0,              /* DB_1_8V_8 (25) */
409    1'b0,              /* VCRX2_V1 (26) */
410    1'b0,              /* DB_1_8V_7 (25) */
411    1'b0,              /* VCRX1_V2 (24) */
412    1'b0,              /* DB_1_8V_6 (23) */
413    1'b0,              /* VCRX1_V1 (22) */
414    1'b0,              /* DB_1_8V_5 (21) */
415    1'b0,              /* VCTXRX1_V2 (20) */
416    1'b0,              /* DB_1_8V_4 (19) */
417    1'b0,              /* VCTXRX1_V1 (18) */
418    1'b0,              /* DB_1_8V_3 (17) */
419    1'b0,              /* VCTXRX2_V1 (16) */
420    1'b1,              /* DB_1_8V_2 (15) */
421    15'd0};
422
423  localparam DB_E31X_IDLE_DDR = {
424    1'b0,              /* DB_EXP_18_24 (99) */
425    13'b0101010101010, /* leds & rx bandsels */
426    1'b0,              /* CAT_FB_CLK (85) */
427    1'b0,              /* CAT_TX_FRAME (84) */
428    1'b0,              /* CAT_RX_DATA_CLK (83) */
429    25'b0000_0000_0000_0000_0000_0000_0, /* CAT_RX_FRAME(81), CAT_P0 & CAT_P1 (58) */
430    1'b0,              /* CAT_SYNC(57) */
431    4'b0001,           /* CAT_ENAGC(56), CAT_BBCLK_OUT (55), CAT_ENABLE(54), CAT_TXNRX(53) */
432    3'b000,            /* DB_EXP_1_8_V_{32,33,34,} (52, 51, 50) */
433    2'b00,             /* CAT_CTRL_IN[1:0] (49,48) */
434    1'b0,              /* CAT_MISO (47) */
435    4'b0111,           /* CAT_{MOSI,SCLK,CS,RESETn) (46, 45, 44, 43) */
436    1'b0,              /* DB_1_8V_31 (42) */
437    8'h00,             /* CAT_CTRL_OUT (41:34) */
438    1'b0,              /* DB_1_8V_11 (33) */
439    1'b0,              /* CAT_CTRL_IN3 (32) */
440    1'b0,              /* DB_1_8V_10 (31) */
441    1'b0,              /* CAT_CTRL_IN2 (30) */
442    1'b0,              /* DB_1_8V_9 (29) */
443    1'b0,              /* VCRX2_V2 (28) */
444    1'b0,              /* DB_1_8V_8 (25) */
445    1'b0,              /* VCRX2_V1 (26) */
446    1'b0,              /* DB_1_8V_7 (24) */
447    1'b0,              /* VCRX1_V2 (24) */
448    1'b0,              /* DB_1_8V_6 (23) */
449    1'b0,              /* VCRX1_V1 (22) */
450    1'b0,              /* DB_1_8V_5 (21) */
451    1'b0,              /* VCTXRX1_V1 (20) */
452    1'b0,              /* DB_1_8V_4 (19) */
453    1'b0,              /* VCTXRX1_V2 (18) */
454    1'b1,              /* DB_1_8V_3 (17) */
455    1'b0,              /* VCTXRX2_V1 (16) */
456    1'b1,              /* DB_1_8V_2 (15) */
457    15'd0};
458
459  localparam NUM_DB_IO_PINS   = 100;
460
461  wire [NUM_DB_IO_PINS-1:0] db_ddr = DB_E31X_IDLE_DDR;
462  wire [NUM_DB_IO_PINS-1:0] db_out = DB_E31X_IDLE_OUT;
463  wire [NUM_DB_IO_PINS-1:0] db_in;
464
465
466  genvar k;
467  generate
468    for (k = 0; k < NUM_DB_IO_PINS; k = k+1) begin
469      IOBUF db_io_i(.O(db_in[k]), .IO(DB_IO[k]), .I(db_out[k]), .T(~db_ddr[k]));
470    end
471  endgenerate
472
473endmodule // e31x
474