diff options
author | Martin Braun <martin.braun@ettus.com> | 2020-01-23 16:10:22 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2020-01-28 09:35:36 -0800 |
commit | bafa9d95453387814ef25e6b6256ba8db2df612f (patch) | |
tree | 39ba24b5b67072d354775272e687796bb511848d /fpga/usrp3/top/e31x/e31x.v | |
parent | 3075b981503002df3115d5f1d0b97d2619ba30f2 (diff) | |
download | uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.gz uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.bz2 uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.zip |
Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce
the size of the repository. However, over the last half-decade, the
split between the repositories has proven more burdensome than it has
been helpful. By merging the FPGA code back, it will be possible to
create atomic commits that touch both FPGA and UHD codebases. Continuous
integration testing is also simplified by merging the repositories,
because it was previously difficult to automatically derive the correct
UHD branch when testing a feature branch on the FPGA repository.
This commit also updates the license files and paths therein.
We are therefore merging the repositories again. Future development for
FPGA code will happen in the same repository as the UHD host code and
MPM code.
== Original Codebase and Rebasing ==
The original FPGA repository will be hosted for the foreseeable future
at its original local location: https://github.com/EttusResearch/fpga/
It can be used for bisecting, reference, and a more detailed history.
The final commit from said repository to be merged here is
05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as
v4.0.0.0-pre-uhd-merge.
If you have changes in the FPGA repository that you want to rebase onto
the UHD repository, simply run the following commands:
- Create a directory to store patches (this should be an empty
directory):
mkdir ~/patches
- Now make sure that your FPGA codebase is based on the same state as
the code that was merged:
cd src/fpga # Or wherever your FPGA code is stored
git rebase v4.0.0.0-pre-uhd-merge
Note: The rebase command may look slightly different depending on what
exactly you're trying to rebase.
- Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge:
git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches
Note: Make sure that only patches are stored in your output directory.
It should otherwise be empty. Make sure that you picked the correct
range of commits, and only commits you wanted to rebase were exported
as patch files.
- Go to the UHD repository and apply the patches:
cd src/uhd # Or wherever your UHD repository is stored
git am --directory fpga ~/patches/*
rm -rf ~/patches # This is for cleanup
== Contributors ==
The following people have contributed mainly to these files (this list
is not complete):
Co-authored-by: Alex Williams <alex.williams@ni.com>
Co-authored-by: Andrej Rode <andrej.rode@ettus.com>
Co-authored-by: Ashish Chaudhari <ashish@ettus.com>
Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com>
Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Derek Kozel <derek.kozel@ettus.com>
Co-authored-by: EJ Kreinar <ej@he360.com>
Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com>
Co-authored-by: Ian Buckley <ian.buckley@gmail.com>
Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Jon Kiser <jon.kiser@ni.com>
Co-authored-by: Josh Blum <josh@joshknows.com>
Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com>
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Matt Ettus <matt@ettus.com>
Co-authored-by: Michael West <michael.west@ettus.com>
Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com>
Co-authored-by: Nick Foster <nick@ettus.com>
Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Paul David <paul.david@ettus.com>
Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com>
Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-authored-by: Sylvain Munaut <tnt@246tNt.com>
Co-authored-by: Trung Tran <trung.tran@ettus.com>
Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>
Diffstat (limited to 'fpga/usrp3/top/e31x/e31x.v')
-rw-r--r-- | fpga/usrp3/top/e31x/e31x.v | 882 |
1 files changed, 882 insertions, 0 deletions
diff --git a/fpga/usrp3/top/e31x/e31x.v b/fpga/usrp3/top/e31x/e31x.v new file mode 100644 index 000000000..3902ed551 --- /dev/null +++ b/fpga/usrp3/top/e31x/e31x.v @@ -0,0 +1,882 @@ +///////////////////////////////////////////////////////////////////// +// +// Copyright 2018 Ettus Research, A National Instruments Company +// Copyright 2019 Ettus Research, A National Instruments Brand +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: e31x +// Description: +// E31x Top Level +// +///////////////////////////////////////////////////////////////////// + +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, + + // PL DDR + //input PL_DDR3_SYSCLK, + //output PL_DDR3_RESET_N, + //inout [15:0] PL_DDR3_DQ, + //inout [1:0] PL_DDR3_DQS_N, + //inout [1:0] PL_DDR3_DQS_P, + //output [14:0] PL_DDR3_ADDR, + //output [2:0] PL_DDR3_BA, + //output PL_DDR3_RAS_N, + //output PL_DDR3_CAS_N, + //output PL_DDR3_WE_N, + //output [0:0] PL_DDR3_CK_P, + //output [0:0] PL_DDR3_CK_N, + //output [0:0] PL_DDR3_CKE, + //output [1:0] PL_DDR3_DM, + //output [0:0] PL_DDR3_ODT, + + //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, + + // RF Board connections + // Change to inout/output as + // they are implemented/tested + input [34:0] DB_EXP_1_8V, + + // Front-end Band Selects + output [2:0] TX_BANDSEL, + output [2:0] RX1_BANDSEL, + output [2:0] RX2_BANDSEL, + output [1:0] RX2C_BANDSEL, + output [1:0] RX1B_BANDSEL, + output [1:0] RX1C_BANDSEL, + output [1:0] RX2B_BANDSEL, + + // Enables + output TX_ENABLE1A, + output TX_ENABLE2A, + output TX_ENABLE1B, + output TX_ENABLE2B, + + // Antenna Selects + output VCTXRX1_V1, + output VCTXRX1_V2, + output VCTXRX2_V1, + output VCTXRX2_V2, + output VCRX1_V1, + output VCRX1_V2, + output VCRX2_V1, + output VCRX2_V2, + + // Leds + output LED_TXRX1_TX, + output LED_TXRX1_RX, + output LED_RX1_RX, + output LED_TXRX2_TX, + output LED_TXRX2_RX, + output LED_RX2_RX, + + // AD9361 connections + input [7:0] CAT_CTRL_OUT, + output [3:0] CAT_CTRL_IN, + output CAT_RESET, // FIXME Fix in Pinout + output CAT_CS, + output CAT_SCLK, + output CAT_MOSI, + input CAT_MISO, + input CAT_BBCLK_OUT, //unused + output CAT_SYNC, + output CAT_TXNRX, + output CAT_ENABLE, + output CAT_ENAGC, + input CAT_RX_FRAME, + input CAT_DATA_CLK, + output CAT_TX_FRAME, + output CAT_FB_CLK, + input [11:0] CAT_P0_D, + output [11:0] CAT_P1_D, + + // pps connections + input GPS_PPS, + input PPS_EXT_IN, + + // VTCXO and the DAC that feeds it + output TCXO_DAC_SYNC_N, + output TCXO_DAC_SCLK, + output TCXO_DAC_SDIN, + input TCXO_CLK, + + // gpios, change to inout somehow + inout [5:0] PL_GPIO +); + + // Constants + localparam REG_AWIDTH = 14; // log2(0x4000) + localparam REG_DWIDTH = 32; + localparam DB_GPIO_WIDTH = 32; + localparam FP_GPIO_OFFSET = 32; // Offset within ps_gpio_* + localparam FP_GPIO_WIDTH = 6; + + //If bus_clk freq ever changes, update this parameter accordingly. + localparam BUS_CLK_RATE = 32'd100000000; //100 MHz bus_clk rate. + localparam NUM_SFP_PORTS = 0; + localparam NUM_RADIOS = 1; + localparam NUM_CHANNELS_PER_RADIO = 2; + localparam NUM_DBOARDS = 1; + localparam NUM_CHANNELS = NUM_RADIOS * NUM_CHANNELS_PER_RADIO; + + // Clocks + wire bus_clk; + wire radio_clk; + wire reg_clk; + wire clk40; + wire FCLK_CLK0; + wire FCLK_CLK1; + wire FCLK_CLK2; + wire FCLK_CLK3; + + // Resets + wire global_rst; + wire bus_rst; + wire radio_rst; + wire reg_rstn; + wire clk40_rst; + wire clk40_rstn; + wire FCLK_RESET0_N; + + // Crossbar + wire m_axi_xbar_arvalid; + wire m_axi_xbar_awvalid; + wire m_axi_xbar_bready; + wire m_axi_xbar_rready; + wire m_axi_xbar_wvalid; + wire [11:0] m_axi_xbar_arid; + wire [11:0] m_axi_xbar_awid; + wire [11:0] m_axi_xbar_wid; + wire [31:0] m_axi_xbar_araddr; + wire [31:0] m_axi_xbar_awaddr; + wire [31:0] m_axi_xbar_wdata; + wire [3:0] m_axi_xbar_wstrb; + wire m_axi_xbar_arready; + wire m_axi_xbar_awready; + wire m_axi_xbar_bvalid; + wire m_axi_xbar_rlast; + wire m_axi_xbar_rvalid; + wire m_axi_xbar_wready; + wire [1:0] m_axi_xbar_bresp; + wire [1:0] m_axi_xbar_rresp; + wire [31:0] m_axi_xbar_rdata; + + // 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; + + // DMA xport adapter to PS + wire [63:0] m_axis_dma_tdata; + wire [3:0] m_axis_dma_tuser; + wire m_axis_dma_tlast; + wire m_axis_dma_tready; + wire m_axis_dma_tvalid; + + wire [63:0] s_axis_dma_tdata; + wire [3:0] s_axis_dma_tdest; + wire s_axis_dma_tlast; + wire s_axis_dma_tready; + wire s_axis_dma_tvalid; + + ///////////////////////////////////////////////////////////////////// + // + // Resets: + // - PL - Global Reset --> Bus Reset + // --> Radio Reset + // - PS - FCLK_RESET0_N --> clk40_rst(n) + // + ////////////////////////////////////////////////////////////////////// + + // Global synchronous reset, on the bus_clk domain. De-asserts after 85 + // bus_clk cycles. Asserted by default. + por_gen por_gen ( + .clk(bus_clk), + .reset_out(global_rst) + ); + + // 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 bus_clk = FCLK_CLK3; // 200 MHz + assign reg_clk = clk40; + + wire pps; + wire clk_tcxo = TCXO_CLK; // 40 MHz + wire is_10meg, is_pps, reflck, plllck; // reference status bits + reg [3:0] tcxo_status, st_rsync; + reg [2:0] pps_reg; + + wire pps_ext = PPS_EXT_IN; + wire gps_pps = GPS_PPS; + + // A local pps signal is derived from the tcxo clock. If a reference + // at an appropriate rate (1 pps or 10 MHz) is present and selected + // a digital control loop will be invoked to tune the vcxo and lock + // the reference. + ppsloop ppslp ( + .reset(1'b0), + .xoclk(clk_tcxo), .ppsgps(gps_pps), .ppsext(pps_ext), + .refsel(pps_select), + .lpps(pps), + .is10meg(is_10meg), .ispps(is_pps), .reflck(reflck), .plllck(plllck), + .sclk(TCXO_DAC_SCLK), .mosi(TCXO_DAC_SDIN), .sync_n(TCXO_DAC_SYNC_N), + .dac_dflt(16'h7fff) + ); + + always @(posedge bus_clk) begin + // status signals originate from other than the bus_clk domain so re-sync + // before passing to e300_core + st_rsync <= {plllck, is_10meg, is_pps, reflck}; + tcxo_status <= st_rsync; + end + + // TODO: Check this logic + // 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_CLK2), + .FCLK_CLK3(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(CAT_MISO), + .SPI0_MISO_O(), + .SPI0_MISO_T(), + .SPI0_MOSI_I(1'b0), + .SPI0_MOSI_O(CAT_MOSI), + .SPI0_MOSI_T(), + .SPI0_SCLK_I(1'b0), + .SPI0_SCLK_O(CAT_SCLK), + .SPI0_SCLK_T(), + .SPI0_SS1_O(), + .SPI0_SS2_O(), + .SPI0_SS_I(1'b1), + .SPI0_SS_O(CAT_CS), + .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_araddr), + .m_axi_xbar_arprot(m_axi_xbar_arprot), + .m_axi_xbar_arready(m_axi_xbar_arready), + .m_axi_xbar_arvalid(m_axi_xbar_arvalid), + .m_axi_xbar_awaddr(m_axi_xbar_awaddr), + .m_axi_xbar_awprot(m_axi_xbar_awprot), + .m_axi_xbar_awready(m_axi_xbar_awready), + .m_axi_xbar_awvalid(m_axi_xbar_awvalid), + .m_axi_xbar_bready(m_axi_xbar_bready), + .m_axi_xbar_bresp(m_axi_xbar_bresp), + .m_axi_xbar_bvalid(m_axi_xbar_bvalid), + .m_axi_xbar_rdata(m_axi_xbar_rdata), + .m_axi_xbar_rready(m_axi_xbar_rready), + .m_axi_xbar_rresp(m_axi_xbar_rresp), + .m_axi_xbar_rvalid(m_axi_xbar_rvalid), + .m_axi_xbar_wdata(m_axi_xbar_wdata), + .m_axi_xbar_wready(m_axi_xbar_wready), + .m_axi_xbar_wstrb(m_axi_xbar_wstrb), + .m_axi_xbar_wvalid(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_tdata), + .s_axis_dma_tdest(s_axis_dma_tdest), + .s_axis_dma_tlast(s_axis_dma_tlast), + .s_axis_dma_tready(s_axis_dma_tready), + .s_axis_dma_tvalid(s_axis_dma_tvalid), + .m_axis_dma_tdata(m_axis_dma_tdata), + .m_axis_dma_tuser(m_axis_dma_tuser), + .m_axis_dma_tlast(m_axis_dma_tlast), + .m_axis_dma_tready(m_axis_dma_tready), + .m_axis_dma_tvalid(m_axis_dma_tvalid) + ); + + ///////////////////////////////////////////////////////////////////// + // + // AD9361 Interface + // + ///////////////////////////////////////////////////////////////////// + + wire [REG_DWIDTH-1:0] dboard_ctrl; + wire [REG_DWIDTH-1:0] dboard_status; + wire mimo_busclk; + wire tx_pll_lock_busclk, rx_pll_lock_busclk; + + wire codec_arst; + wire [NUM_CHANNELS*32-1:0] rx_flat, tx_flat; + + wire [11:0] rx_i0, rx_q0, tx_i0, tx_q0; + wire [11:0] rx_i1, rx_q1, tx_i1, tx_q1; + + wire rx_stb, tx_stb; + wire [NUM_CHANNELS-1:0] rx_atr, tx_atr; + + assign rx_flat = {rx_i1, 4'd0, rx_q1, 4'd0, + rx_i0, 4'd0, rx_q0, 4'd0}; + + assign tx_q0 = tx_flat[15:4]; + assign tx_i0 = tx_flat[31:20]; + assign tx_q1 = tx_flat[47:36]; + assign tx_i1 = tx_flat[63:52]; + + assign mimo_busclk = dboard_ctrl[0]; + assign codec_arst = dboard_ctrl[1]; + + synchronizer synchronizer_tx_pll_lock ( + .clk(bus_clk), .rst(1'b0), .in(CAT_CTRL_OUT[7]), .out(tx_pll_lock_busclk) + ); + + synchronizer synchronizer_rx_pll_lock ( + .clk(bus_clk), .rst(1'b0), .in(CAT_CTRL_OUT[6]), .out(rx_pll_lock_busclk) + ); + + assign dboard_status = { + 20'b0, + tcxo_status, // TCXO satus {plllck, is_10meg, is_pps, refclk} + tx_pll_lock_busclk, // TX PLL Lock + rx_pll_lock_busclk, // RX PLL Lock + 6'b0 + }; + + + e310_io e310_io ( + //.areset(codec_arst), TODO + .areset(bus_rst), + .mimo(mimo_busclk), + // Baseband sample interface + .radio_clk(radio_clk), + .radio_rst(radio_rst), + .rx_i0(rx_i1), + .rx_q0(rx_q1), + .rx_i1(rx_i0), + .rx_q1(rx_q0), + .rx_stb(rx_stb), + .tx_i0(tx_i1), + .tx_q0(tx_q1), + .tx_i1(tx_i0), + .tx_q1(tx_q0), + .tx_stb(tx_stb), + // AD9361 interface + .rx_clk(CAT_DATA_CLK), + .rx_frame(CAT_RX_FRAME), + .rx_data(CAT_P0_D), + .tx_clk(CAT_FB_CLK), + .tx_frame(CAT_TX_FRAME), + .tx_data(CAT_P1_D) + ); + + assign CAT_CTRL_IN = 4'b1; + assign CAT_ENAGC = 1'b1; + assign CAT_TXNRX = 1'b1; + assign CAT_ENABLE = 1'b1; + assign CAT_RESET = ~bus_rst; // Operates active-low, really CAT_RESET_B + assign CAT_SYNC = 1'b0; + + ///////////////////////////////////////////////////////////////////// + // + // DB GPIO Interface + // - Control Filter Banks + // - LEDs + // + ///////////////////////////////////////////////////////////////////// + + // Flattened Radio GPIO control + wire [DB_GPIO_WIDTH*NUM_CHANNELS-1:0] db_gpio_out_flat; + wire [DB_GPIO_WIDTH*NUM_CHANNELS-1:0] db_gpio_ddr_flat; + wire [DB_GPIO_WIDTH*NUM_CHANNELS-1:0] db_gpio_in_flat; + wire [32*NUM_CHANNELS-1:0] leds_flat; + + // Radio GPIO control + wire [DB_GPIO_WIDTH-1:0] db_gpio_in[0:NUM_CHANNELS-1]; + wire [DB_GPIO_WIDTH-1:0] db_gpio_out[0:NUM_CHANNELS-1]; + wire [DB_GPIO_WIDTH-1:0] db_gpio_ddr[0:NUM_CHANNELS-1]; + wire [DB_GPIO_WIDTH-1:0] db_gpio_pins[0:NUM_CHANNELS-1]; + wire [31:0] leds[0:NUM_CHANNELS-1]; + + genvar i; + generate + for (i = 0; i < NUM_CHANNELS; i = i + 1) begin + + assign db_gpio_in_flat[DB_GPIO_WIDTH*i +: DB_GPIO_WIDTH] = db_gpio_in[i]; + assign db_gpio_out[i] = db_gpio_out_flat[DB_GPIO_WIDTH*i +: DB_GPIO_WIDTH]; + assign db_gpio_ddr[i] = db_gpio_ddr_flat[DB_GPIO_WIDTH*i +: DB_GPIO_WIDTH]; + assign leds[i] = leds_flat[32*i +: 32]; + + gpio_atr_io #( + .WIDTH(DB_GPIO_WIDTH) + ) gpio_atr_db_inst ( + .clk(radio_clk), + .gpio_pins(db_gpio_pins[i]), + .gpio_ddr(db_gpio_ddr[i]), + .gpio_out(db_gpio_out[i]), + .gpio_in(db_gpio_in[i]) + ); + end + endgenerate + + // DB_GPIO and LED pin assignments with software mapping + wire [2:0] TX1_BANDSEL; + wire [2:0] TX2_BANDSEL; + + // Channel 0 + assign {VCRX1_V1, // [15:15] + VCRX1_V2, // [14:14] + VCTXRX1_V1, // [13:13] + VCTXRX1_V2, // [12:12] + TX_ENABLE1B, // [11:11] + TX_ENABLE1A, // [10:10] + RX1C_BANDSEL, // [9:8] + RX1B_BANDSEL, // [7:6] + RX1_BANDSEL, // [5:3] + TX1_BANDSEL // [2:0] + } = db_gpio_pins[1]; + + assign {LED_RX1_RX, + LED_TXRX1_TX, + LED_TXRX1_RX + } = leds[1]; + + // Channel 1 + assign {VCRX2_V1, + VCRX2_V2, + VCTXRX2_V1, + VCTXRX2_V2, + TX_ENABLE2B, + TX_ENABLE2A, + RX2C_BANDSEL, + RX2B_BANDSEL, + RX2_BANDSEL, + TX2_BANDSEL + } = db_gpio_pins[0]; + + assign {LED_RX2_RX, + LED_TXRX2_TX, + LED_TXRX2_RX + } = leds[0]; + + // It is okay to OR here as the both channels must be set to the same freq. + // This is needed so software does not have to set properties of radio core 0 + // when only using radio core 1. + assign TX_BANDSEL = TX1_BANDSEL | TX2_BANDSEL; + + ///////////////////////////////////////////////////////////////////// + // + // Front-Panel GPIO + // + ///////////////////////////////////////////////////////////////////// + + wire [FP_GPIO_WIDTH-1:0] fp_gpio_in; + wire [FP_GPIO_WIDTH-1:0] fp_gpio_out; + wire [FP_GPIO_WIDTH-1:0] fp_gpio_tri; + + gpio_atr_io #(.WIDTH(FP_GPIO_WIDTH)) fp_gpio_atr_inst ( + .clk(radio_clk), .gpio_pins(PL_GPIO), + .gpio_ddr(fp_gpio_tri), .gpio_out(fp_gpio_out), .gpio_in(fp_gpio_in) + ); + + ///////////////////////////////////////////////////////////////////// + // + // E320 Core: + // - xbar + // - Radio + // - DMA + // - DRAM + // - CEs + // + ////////////////////////////////////////////////////////////////////// + + wire [31:0] build_datestamp; + + USR_ACCESSE2 usr_access_i ( + .DATA(build_datestamp), .CFGCLK(), .DATAVALID() + ); + + e31x_core #( + .REG_AWIDTH(REG_AWIDTH), + .BUS_CLK_RATE(BUS_CLK_RATE), + .NUM_SFP_PORTS(NUM_SFP_PORTS), + .NUM_RADIOS(NUM_RADIOS), + .NUM_CHANNELS_PER_RADIO(NUM_CHANNELS_PER_RADIO), + .NUM_CHANNELS(NUM_CHANNELS), + .NUM_DBOARDS(NUM_DBOARDS), + .NUM_CHANNELS_PER_DBOARD(NUM_CHANNELS_PER_RADIO), + .FP_GPIO_WIDTH(FP_GPIO_WIDTH), + .DB_GPIO_WIDTH(DB_GPIO_WIDTH) + ) e31x_core_inst ( + + //Clocks and resets + .radio_clk(radio_clk), + .radio_rst(radio_rst), + .bus_clk(bus_clk), + .bus_rst(bus_rst), + + // Clocking and PPS Controls/Indicators + .pps_refclk(pps), + .refclk_locked(reflck), + .pps_select(pps_select), + + .s_axi_aclk(clk40), + .s_axi_aresetn(clk40_rstn), + // AXI4-Lite: Write address port (domain: s_axi_aclk) + .s_axi_awaddr(m_axi_xbar_awaddr), + .s_axi_awvalid(m_axi_xbar_awvalid), + .s_axi_awready(m_axi_xbar_awready), + // AXI4-Lite: Write data port (domain: s_axi_aclk) + .s_axi_wdata(m_axi_xbar_wdata), + .s_axi_wstrb(m_axi_xbar_wstrb), + .s_axi_wvalid(m_axi_xbar_wvalid), + .s_axi_wready(m_axi_xbar_wready), + // AXI4-Lite: Write response port (domain: s_axi_aclk) + .s_axi_bresp(m_axi_xbar_bresp), + .s_axi_bvalid(m_axi_xbar_bvalid), + .s_axi_bready(m_axi_xbar_bready), + // AXI4-Lite: Read address port (domain: s_axi_aclk) + .s_axi_araddr(m_axi_xbar_araddr), + .s_axi_arvalid(m_axi_xbar_arvalid), + .s_axi_arready(m_axi_xbar_arready), + // AXI4-Lite: Read data port (domain: s_axi_aclk) + .s_axi_rdata(m_axi_xbar_rdata), + .s_axi_rresp(m_axi_xbar_rresp), + .s_axi_rvalid(m_axi_xbar_rvalid), + .s_axi_rready(m_axi_xbar_rready), + + // Radio ATR + .rx_atr(rx_atr), + .tx_atr(tx_atr), + + // Front-Panel GPIO + .fp_gpio_in(fp_gpio_in), + .fp_gpio_tri(fp_gpio_tri), + .fp_gpio_out(fp_gpio_out), + + // PS GPIO Connection + .ps_gpio_tri(ps_gpio_tri[FP_GPIO_WIDTH+FP_GPIO_OFFSET-1: FP_GPIO_OFFSET]), + .ps_gpio_out(ps_gpio_out[FP_GPIO_WIDTH+FP_GPIO_OFFSET-1: FP_GPIO_OFFSET]), + .ps_gpio_in(ps_gpio_in[FP_GPIO_WIDTH+FP_GPIO_OFFSET-1: FP_GPIO_OFFSET]), + + // DB GPIO + .db_gpio_out_flat(db_gpio_out_flat), + .db_gpio_ddr_flat(db_gpio_ddr_flat), + .db_gpio_in_flat(db_gpio_in_flat), + .db_gpio_fab_flat(32'b0), + + // TX/RX LEDs + .leds_flat(leds_flat), + + // Radio Strobes + .rx_stb({NUM_CHANNELS{rx_stb}}), + .tx_stb({NUM_CHANNELS{tx_stb}}), + + // Radio Data + .rx(rx_flat), + .tx(tx_flat), + + // DMA to PS + .m_dma_tdata(s_axis_dma_tdata), + .m_dma_tdest(s_axis_dma_tdest), + .m_dma_tlast(s_axis_dma_tlast), + .m_dma_tready(s_axis_dma_tready), + .m_dma_tvalid(s_axis_dma_tvalid), + + .s_dma_tdata(m_axis_dma_tdata), + .s_dma_tuser(m_axis_dma_tuser), + .s_dma_tlast(m_axis_dma_tlast), + .s_dma_tready(m_axis_dma_tready), + .s_dma_tvalid(m_axis_dma_tvalid), + + .build_datestamp(build_datestamp), + .sfp_ports_info(), + .dboard_status(dboard_status), + .xadc_readback(32'h0), //Unused + .fp_gpio_ctrl(), //Unused + .dboard_ctrl(dboard_ctrl) + ); + + ///////////////////////////////////////////////////////////////////// + // + // PL DDR3 Memory Interface + // + ///////////////////////////////////////////////////////////////////// + + //wire pl_dram_clk = FCLK_CLK3; + //wire pl_dram_rst = ~FCLK_RESET0_N; + + //example_top inst_example_top + //( + // .ddr3_dq (PL_DDR3_DQ), + // .ddr3_dqs_n (PL_DDR3_DQS_N), + // .ddr3_dqs_p (PL_DDR3_DQS_P), + // .ddr3_addr (PL_DDR3_ADDR), + // .ddr3_ba (PL_DDR3_BA), + // .ddr3_ras_n (PL_DDR3_RAS_N), + // .ddr3_cas_n (PL_DDR3_CAS_N), + // .ddr3_we_n (PL_DDR3_WE_N), + // .ddr3_reset_n (PL_DDR3_RESET_N), + // .ddr3_ck_p (PL_DDR3_CK_P), + // .ddr3_ck_n (PL_DDR3_CK_N), + // .ddr3_cke (PL_DDR3_CKE), + // .ddr3_dm (PL_DDR3_DM), + // .ddr3_odt (PL_DDR3_ODT), + // .sys_clk_i (PL_DDR3_SYSCLK), + // .clk_ref_i (pl_dram_clk), + // .tg_compare_error (), + // .init_calib_complete (), + // .sys_rst (pl_dram_rst) + //); + + // 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; + + +endmodule // e31x |