///////////////////////////////////////////////////////////////////// // // Copyright 2018-2019 Ettus Research, A National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // // Module: e31x // Description: // E31x Top Level Idle // ///////////////////////////////////////////////////////////////////// module e31x ( // PS Connections inout [53:0] MIO, input PS_SRSTB, input PS_CLK, input PS_PORB, inout DDR_CLK, inout DDR_CLK_N, inout DDR_CKE, inout DDR_CS_N, inout DDR_RAS_N, inout DDR_CAS_N, inout DDR_WEB, inout [2:0] DDR_BANKADDR, inout [14:0] DDR_ADDR, inout DDR_ODT, inout DDR_DRSTB, inout [31:0] DDR_DQ, inout [3:0] DDR_DM, inout [3:0] DDR_DQS, inout [3:0] DDR_DQS_N, inout DDR_VRP, inout DDR_VRN, //AVR SPI IO input AVR_CS_R, output AVR_IRQ, output AVR_MISO_R, input AVR_MOSI_R, input AVR_SCK_R, input ONSWITCH_DB, // pps connections input GPS_PPS, input PPS_EXT_IN, // gpios, change to inout somehow inout [5:0] PL_GPIO, // RF Board connections inout [99:0] DB_IO ); // Clocks wire bus_clk; wire radio_clk; wire reg_clk; wire clk40; wire FCLK_CLK0; wire FCLK_CLK1; // Resets wire global_rst; wire bus_rst; wire radio_rst; wire reg_rstn; wire clk40_rst; wire clk40_rstn; wire FCLK_RESET0_N; // PMU wire [31:0] m_axi_pmu_araddr; wire [2:0] m_axi_pmu_arprot; wire m_axi_pmu_arready; wire m_axi_pmu_arvalid; wire [31:0] m_axi_pmu_awaddr; wire [2:0] m_axi_pmu_awprot; wire m_axi_pmu_awready; wire m_axi_pmu_awvalid; wire m_axi_pmu_bready; wire [1:0] m_axi_pmu_bresp; wire m_axi_pmu_bvalid; wire [31:0] m_axi_pmu_rdata; wire m_axi_pmu_rready; wire [1:0] m_axi_pmu_rresp; wire m_axi_pmu_rvalid; wire [31:0] m_axi_pmu_wdata; wire m_axi_pmu_wready; wire [3:0] m_axi_pmu_wstrb; wire m_axi_pmu_wvalid; ///////////////////////////////////////////////////////////////////// // // Resets: // - PL - Bus Reset // Radio Reset // - PS - FCLK_RESET0_N --> clk40_rst(n) // ////////////////////////////////////////////////////////////////////// // Synchronous reset for the bus_clk domain reset_sync bus_reset_gen ( .clk(bus_clk), .reset_in(~FCLK_RESET0_N), //.reset_in(~clocks_locked), .reset_out(bus_rst) ); // PS-based Resets // // // Synchronous reset for the clk40 domain. This is derived from the PS reset 0. reset_sync clk40_reset_gen ( .clk(clk40), .reset_in(~FCLK_RESET0_N), .reset_out(clk40_rst) ); // Invert for various modules. assign clk40_rstn = ~clk40_rst; assign reg_rstn = clk40_rstn; ///////////////////////////////////////////////////////////////////// // // Clocks and PPS // ///////////////////////////////////////////////////////////////////// wire [1:0] pps_select; assign clk40 = FCLK_CLK1; // 40 MHz assign bus_clk = FCLK_CLK0; // 100 MHz assign reg_clk = clk40; reg [2:0] pps_reg; wire pps_ext = PPS_EXT_IN; wire gps_pps = GPS_PPS; // connect PPS input to GPIO so ntpd can use it always @ (posedge bus_clk) pps_reg <= bus_rst ? 3'b000 : {pps_reg[1:0], GPS_PPS}; assign ps_gpio_in[8] = pps_reg[2]; // 62 ///////////////////////////////////////////////////////////////////// // // Power Button // ////////////////////////////////////////////////////////////////////// // register the debounced onswitch signal to detect edges, // Note: ONSWITCH_DB is low active reg [1:0] onswitch_edge; always @ (posedge bus_clk) onswitch_edge <= bus_rst ? 2'b00 : {onswitch_edge[0], ONSWITCH_DB}; wire button_press = ~ONSWITCH_DB & onswitch_edge[0] & onswitch_edge[1]; wire button_release = ONSWITCH_DB & ~onswitch_edge[0] & ~onswitch_edge[1]; // stretch the pulse so IRQs don't get lost reg [7:0] button_press_reg, button_release_reg; always @ (posedge bus_clk) if (bus_rst) begin button_press_reg <= 8'h00; button_release_reg <= 8'h00; end else begin button_press_reg <= {button_press_reg[6:0], button_press}; button_release_reg <= {button_release_reg[6:0], button_release}; end wire button_press_irq = |button_press_reg; wire button_release_irq = |button_release_reg; ///////////////////////////////////////////////////////////////////// // // Interrupts Fabric to PS // ////////////////////////////////////////////////////////////////////// wire [15:0] IRQ_F2P; wire pmu_irq; assign IRQ_F2P = {12'b0, pmu_irq, // Interrupt 32 button_release_irq, // Interrupt 31 button_press_irq, // Interrupt 30 1'b0}; ///////////////////////////////////////////////////////////////////// // // PS Connections // ////////////////////////////////////////////////////////////////////// wire [63:0] ps_gpio_in; wire [63:0] ps_gpio_out; wire [63:0] ps_gpio_tri; e31x_ps_bd e31x_ps_bd_inst ( // DDR Interface .DDR_VRN(DDR_VRN), .DDR_VRP(DDR_VRP), .DDR_addr(DDR_ADDR), .DDR_ba(DDR_BANKADDR), .DDR_cas_n(DDR_CAS_N), .DDR_ck_n(DDR_CLK_N), .DDR_ck_p(DDR_CLK), .DDR_cke(DDR_CKE), .DDR_cs_n(DDR_CS_N), .DDR_dm(DDR_DM), .DDR_dq(DDR_DQ), .DDR_dqs_n(DDR_DQS_N), .DDR_dqs_p(DDR_DQS), .DDR_odt(DDR_ODT), .DDR_ras_n(DDR_RAS_N), .DDR_reset_n(DDR_RESET_N), .DDR_we_n(DDR_WE_N), // Clocks .FCLK_CLK0(FCLK_CLK0), .FCLK_CLK1(FCLK_CLK1), .FCLK_CLK2(), .FCLK_CLK3(), // Resets .FCLK_RESET0_N(FCLK_RESET0_N), // GPIO .GPIO_0_tri_i(ps_gpio_in), .GPIO_0_tri_o(ps_gpio_out), .GPIO_0_tri_t(ps_gpio_tri), // Interrupts .IRQ_F2P(IRQ_F2P), // MIO .MIO(MIO), .PS_CLK(PS_CLK), .PS_PORB(PS_PORB), .PS_SRSTB(PS_SRSTB), // SPI .SPI0_MISO_I(), .SPI0_MISO_O(), .SPI0_MISO_T(), .SPI0_MOSI_I(), .SPI0_MOSI_O(), .SPI0_MOSI_T(), .SPI0_SCLK_I(), .SPI0_SCLK_O(), .SPI0_SCLK_T(), .SPI0_SS1_O(), .SPI0_SS2_O(), .SPI0_SS_I(), .SPI0_SS_O(), .SPI0_SS_T(), .SPI1_MISO_I(), .SPI1_MISO_O(), .SPI1_MISO_T(), .SPI1_MOSI_I(), .SPI1_MOSI_O(), .SPI1_MOSI_T(), .SPI1_SCLK_I(), .SPI1_SCLK_O(), .SPI1_SCLK_T(), .SPI1_SS1_O(), .SPI1_SS2_O(), .SPI1_SS_I(), .SPI1_SS_O(), .SPI1_SS_T(), // USB .USBIND_0_port_indctl(), .USBIND_0_vbus_pwrfault(), .USBIND_0_vbus_pwrselect(), .bus_clk(bus_clk), .bus_rstn(~bus_rst), .clk40(clk40), .clk40_rstn(clk40_rstn), .S_AXI_GP0_ACLK(clk40), .S_AXI_GP0_ARESETN(clk40_rstn), // XBAR Regport .m_axi_xbar_araddr(), .m_axi_xbar_arprot(), .m_axi_xbar_arready(), .m_axi_xbar_arvalid(), .m_axi_xbar_awaddr(), .m_axi_xbar_awprot(), .m_axi_xbar_awready(), .m_axi_xbar_awvalid(), .m_axi_xbar_bready(), .m_axi_xbar_bresp(), .m_axi_xbar_bvalid(), .m_axi_xbar_rdata(), .m_axi_xbar_rready(), .m_axi_xbar_rresp(), .m_axi_xbar_rvalid(), .m_axi_xbar_wdata(), .m_axi_xbar_wready(), .m_axi_xbar_wstrb(), .m_axi_xbar_wvalid(), // PMU .m_axi_pmu_araddr(m_axi_pmu_araddr), .m_axi_pmu_arprot(m_axi_pmu_arprot), .m_axi_pmu_arready(m_axi_pmu_arready), .m_axi_pmu_arvalid(m_axi_pmu_arvalid), .m_axi_pmu_awaddr(m_axi_pmu_awaddr), .m_axi_pmu_awprot(m_axi_pmu_awprot), .m_axi_pmu_awready(m_axi_pmu_awready), .m_axi_pmu_awvalid(m_axi_pmu_awvalid), .m_axi_pmu_bready(m_axi_pmu_bready), .m_axi_pmu_bresp(m_axi_pmu_bresp), .m_axi_pmu_bvalid(m_axi_pmu_bvalid), .m_axi_pmu_rdata(m_axi_pmu_rdata), .m_axi_pmu_rready(m_axi_pmu_rready), .m_axi_pmu_rresp(m_axi_pmu_rresp), .m_axi_pmu_rvalid(m_axi_pmu_rvalid), .m_axi_pmu_wdata(m_axi_pmu_wdata), .m_axi_pmu_wready(m_axi_pmu_wready), .m_axi_pmu_wstrb(m_axi_pmu_wstrb), .m_axi_pmu_wvalid(m_axi_pmu_wvalid), // DMA .s_axis_dma_tdata(), .s_axis_dma_tkeep(), .s_axis_dma_tlast(), .s_axis_dma_tready(), .s_axis_dma_tvalid(1'b0), .m_axis_dma_tdata(), .m_axis_dma_tkeep(), .m_axis_dma_tlast(), .m_axis_dma_tready(1'b1), .m_axis_dma_tvalid() ); ///////////////////////////////////////////////////////////////////// // // PMU // ////////////////////////////////////////////////////////////////////// axi_pmu inst_axi_pmu ( .s_axi_aclk(clk40), // TODO: Original design used bus_clk .s_axi_areset(clk40_rst), .ss(AVR_CS_R), .mosi(AVR_MOSI_R), .sck(AVR_SCK_R), .miso(AVR_MISO_R), // AXI4-Lite: Write address port (domain: s_axi_aclk) .s_axi_awaddr(m_axi_pmu_awaddr), .s_axi_awvalid(m_axi_pmu_awvalid), .s_axi_awready(m_axi_pmu_awready), // AXI4-Lite: Write data port (domain: s_axi_aclk) .s_axi_wdata(m_axi_pmu_wdata), .s_axi_wstrb(m_axi_pmu_wstrb), .s_axi_wvalid(m_axi_pmu_wvalid), .s_axi_wready(m_axi_pmu_wready), // AXI4-Lite: Write response port (domain: s_axi_aclk) .s_axi_bresp(m_axi_pmu_bresp), .s_axi_bvalid(m_axi_pmu_bvalid), .s_axi_bready(m_axi_pmu_bready), // AXI4-Lite: Read address port (domain: s_axi_aclk) .s_axi_araddr(m_axi_pmu_araddr), .s_axi_arvalid(m_axi_pmu_arvalid), .s_axi_arready(m_axi_pmu_arready), // AXI4-Lite: Read data port (domain: s_axi_aclk) .s_axi_rdata(m_axi_pmu_rdata), .s_axi_rresp(m_axi_pmu_rresp), .s_axi_rvalid(m_axi_pmu_rvalid), .s_axi_rready(m_axi_pmu_rready), .s_axi_irq(pmu_irq) ); assign AVR_IRQ = 1'b0; localparam DB_E31X_IDLE_OUT = { 1'b0, /* DB_EXP_18_24 (99) */ 13'b0000000000000, /* leds & rx bandsels */ 1'b0, /* CAT_FB_CLK (85) */ 1'b0, /* CAT_TX_FRAME (84) */ 1'b0, /* CAT_RX_DATA_CLK (83) */ 25'b0000_0000_0000_0000_0000_0000_0, /* CAT_RX_FRAME(81), CAT_P0 & CAT_P1 (58)*/ 1'b0, /* CAT_SYNC(57) */ 4'b0000, /* CAT_ENAGC(56), CAT_BBCLK_OUT (55), CAT_ENABLE(54), CAT_TXNRX(53) */ 3'b000, /* DB_EXP_1_8_V_{33,34,32} */ 2'b00, /* CAT_CTRL_IN[1:0] (49,48) */ 1'b0, /* CAT_MISO (47) */ 4'b0000, /* CAT_{MOSI,SCLK,CS,RESETn) (46,45, 44, 43) */ 1'b0, /* DB_1_8V_31 (42) */ 8'h00, /* CAT_CTRL_OUT (41:34) */ 1'b0, /* DB_1_8V_11 (33) */ 1'b0, /* CAT_CTRL_IN3 (32) */ 1'b0, /* DB_1_8V_10 (31) */ 1'b0, /* CAT_CTRL_IN2 (30) */ 1'b0, /* DB_1_8V_9 (29) */ 1'b0, /* VCRX2_V2 (28) */ 1'b0, /* DB_1_8V_8 (25) */ 1'b0, /* VCRX2_V1 (26) */ 1'b0, /* DB_1_8V_7 (25) */ 1'b0, /* VCRX1_V2 (24) */ 1'b0, /* DB_1_8V_6 (23) */ 1'b0, /* VCRX1_V1 (22) */ 1'b0, /* DB_1_8V_5 (21) */ 1'b0, /* VCTXRX1_V2 (20) */ 1'b0, /* DB_1_8V_4 (19) */ 1'b0, /* VCTXRX1_V1 (18) */ 1'b0, /* DB_1_8V_3 (17) */ 1'b0, /* VCTXRX2_V1 (16) */ 1'b1, /* DB_1_8V_2 (15) */ 15'd0}; localparam DB_E31X_IDLE_DDR = { 1'b0, /* DB_EXP_18_24 (99) */ 13'b0101010101010, /* leds & rx bandsels */ 1'b0, /* CAT_FB_CLK (85) */ 1'b0, /* CAT_TX_FRAME (84) */ 1'b0, /* CAT_RX_DATA_CLK (83) */ 25'b0000_0000_0000_0000_0000_0000_0, /* CAT_RX_FRAME(81), CAT_P0 & CAT_P1 (58) */ 1'b0, /* CAT_SYNC(57) */ 4'b0001, /* CAT_ENAGC(56), CAT_BBCLK_OUT (55), CAT_ENABLE(54), CAT_TXNRX(53) */ 3'b000, /* DB_EXP_1_8_V_{32,33,34,} (52, 51, 50) */ 2'b00, /* CAT_CTRL_IN[1:0] (49,48) */ 1'b0, /* CAT_MISO (47) */ 4'b0111, /* CAT_{MOSI,SCLK,CS,RESETn) (46, 45, 44, 43) */ 1'b0, /* DB_1_8V_31 (42) */ 8'h00, /* CAT_CTRL_OUT (41:34) */ 1'b0, /* DB_1_8V_11 (33) */ 1'b0, /* CAT_CTRL_IN3 (32) */ 1'b0, /* DB_1_8V_10 (31) */ 1'b0, /* CAT_CTRL_IN2 (30) */ 1'b0, /* DB_1_8V_9 (29) */ 1'b0, /* VCRX2_V2 (28) */ 1'b0, /* DB_1_8V_8 (25) */ 1'b0, /* VCRX2_V1 (26) */ 1'b0, /* DB_1_8V_7 (24) */ 1'b0, /* VCRX1_V2 (24) */ 1'b0, /* DB_1_8V_6 (23) */ 1'b0, /* VCRX1_V1 (22) */ 1'b0, /* DB_1_8V_5 (21) */ 1'b0, /* VCTXRX1_V1 (20) */ 1'b0, /* DB_1_8V_4 (19) */ 1'b0, /* VCTXRX1_V2 (18) */ 1'b1, /* DB_1_8V_3 (17) */ 1'b0, /* VCTXRX2_V1 (16) */ 1'b1, /* DB_1_8V_2 (15) */ 15'd0}; localparam NUM_DB_IO_PINS = 100; wire [NUM_DB_IO_PINS-1:0] db_ddr = DB_E31X_IDLE_DDR; wire [NUM_DB_IO_PINS-1:0] db_out = DB_E31X_IDLE_OUT; wire [NUM_DB_IO_PINS-1:0] db_in; genvar k; generate for (k = 0; k < NUM_DB_IO_PINS; k = k+1) begin IOBUF db_io_i(.O(db_in[k]), .IO(DB_IO[k]), .I(db_out[k]), .T(~db_ddr[k])); end endgenerate endmodule // e31x