diff options
Diffstat (limited to 'fpga/usrp3/top/b200/b200.v')
-rw-r--r-- | fpga/usrp3/top/b200/b200.v | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/fpga/usrp3/top/b200/b200.v b/fpga/usrp3/top/b200/b200.v new file mode 100644 index 000000000..811842f32 --- /dev/null +++ b/fpga/usrp3/top/b200/b200.v @@ -0,0 +1,365 @@ +// +// Copyright 2013 Ettus Research LLC +// Copyright 2017 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + + +/*********************************************************** + * B200 Module Declaration + **********************************************************/ +module b200 ( + // SPI Interfaces + output cat_ce, + input cat_miso, + output cat_mosi, + output cat_sclk, + + input fx3_ce, + output fx3_miso, + input fx3_mosi, + input fx3_sclk, + + output pll_ce, + output pll_mosi, + output pll_sclk, + + // UART + // By default these provide an FX3 UART console output. Under compile time control they can alternatively + // provide 2 (1.8V) GPIO pins which are logically bits [9:8] of the fp_gpio bus. + // Used as a UART RXD is an input and TXD an output electrically. + // input FPGA_RXD0, // These pins goto 3 pin 0.1" header on B2x0 and + // output FPGA_TXD0, // carry FX3 UART. + inout FPGA_RXD0, // These pins goto 3 pin 0.1" header J400 on B2x0 and + inout FPGA_TXD0, // carry FX3 UART. + + // Catalina Controls + output codec_enable, + output codec_en_agc, + output codec_reset, + output codec_sync, + output codec_txrx, + output [3:0] codec_ctrl_in, // These should be outputs + input [7:0] codec_ctrl_out, // MUST BE INPUT + + // Catalina Data + input codec_data_clk_p, // Clock from CAT (RX) + output codec_fb_clk_p, // Clock to CAT (TX) + input [11:0] rx_codec_d, + output [11:0] tx_codec_d, + input rx_frame_p, + output tx_frame_p, + + input cat_clkout_fpga, + + //always on 40MHz clock + input codec_main_clk_p, + input codec_main_clk_n, + + // Debug Bus + output [31:0] debug, + output [1:0] debug_clk, + + // GPIF, FX3 Slave FIFO + output IFCLK, // pclk + input FX3_EXTINT, + output GPIF_CTL0, // n_slcs + output GPIF_CTL1, // n_slwr + output GPIF_CTL2, // n_sloe + output GPIF_CTL3, // n_slrd + output GPIF_CTL7, // n_pktend + input GPIF_CTL4, // slfifo_flags[0] + input GPIF_CTL5, // slfifo_flags[1] + input GPIF_CTL6, // Serial settings bus from FX3. SDA + input GPIF_CTL8, // Serial settings bus from FX3. SCL + output GPIF_CTL11, // slfifo_addr[1] + output GPIF_CTL12, // slfifo_addr[0] + inout [31:0] GPIF_D, + input GPIF_CTL9, // global_reset + + // GPS + input gps_lock, + output gps_rxd, + input gps_txd, // FPGA has pullup for unpopulated GPS + input gps_txd_nmea, // FPGA has pullup for unpopulated GPS + + // LEDS + output LED_RX1, + output LED_RX2, + output LED_TXRX1_RX, + output LED_TXRX1_TX, + output LED_TXRX2_RX, + output LED_TXRX2_TX, + + // GPIO Header J504 - 10 pin 0.1" 3.3V. + // Only present on Rev6 and later boards...these pins unused on Rev5 and earlier. + // NOTE: These pins are allocated from complimentry pairs and could potentially be used + // as differential style I/O. + `ifdef TARGET_B210 + inout [7:0] fp_gpio, + `endif + // Misc Hardware Control + output ref_sel, + input pll_lock, + input FPGA_CFG_CS, // Driven by FX3 gpio. + input AUX_PWR_ON, // Driven by FX3 gpio. + + // PPS + input PPS_IN_EXT, + input PPS_IN_INT, + + // RF Hardware Control + output SFDX1_RX, + output SFDX1_TX, + output SFDX2_RX, + output SFDX2_TX, + output SRX1_RX, + output SRX1_TX, + output SRX2_RX, + output SRX2_TX, + output tx_bandsel_a, + output tx_bandsel_b, + output tx_enable1, + output tx_enable2, + output rx_bandsel_a, + output rx_bandsel_b, + output rx_bandsel_c + ); + + wire reset_global = GPIF_CTL9; + + /////////////////////////////////////////////////////////////////////// + // generate clocks from always on codec main clk + /////////////////////////////////////////////////////////////////////// + wire bus_clk, gpif_clk, radio_clk; + wire locked; + b200_clk_gen gen_clks + ( + .CLK_IN1_40_P(codec_main_clk_p), .CLK_IN1_40_N(codec_main_clk_n), + .CLK_OUT1_40_int(), .CLK_OUT2_100_gpif(gpif_clk), .CLK_OUT3_100_bus(), + .RESET(reset_global), .LOCKED(locked) + ); + + // Bus Clock and GPIF Clock both same 100MHz clock. + assign bus_clk = gpif_clk; + + + //hold-off logic for clocks ready + reg [15:0] clocks_ready_count; + reg clocks_ready; + always @(posedge bus_clk or posedge reset_global or negedge locked) begin + if (reset_global | !locked) begin + clocks_ready_count <= 16'b0; + clocks_ready <= 1'b0; + end + else if (!clocks_ready) begin + clocks_ready_count <= clocks_ready_count + 1'b1; + clocks_ready <= (clocks_ready_count == 16'hffff); + end + end + + /////////////////////////////////////////////////////////////////////// + // drive output clocks + /////////////////////////////////////////////////////////////////////// + wire [1:0] debug_clk_int; + //S6CLK2PIN S6CLK2PIN_dbg0 (.I(debug_clk_int[0]), .O(debug_clk[0])); + //S6CLK2PIN S6CLK2PIN_dbg1 (.I(debug_clk_int[1]), .O(debug_clk[1])); + assign debug_clk[1:0] = 2'b0; + S6CLK2PIN S6CLK2PIN_gpif (.I(gpif_clk), .O(IFCLK)); + + /////////////////////////////////////////////////////////////////////// + // Create sync reset signals + /////////////////////////////////////////////////////////////////////// + wire gpif_rst, bus_rst, radio_rst; + reset_sync gpif_sync(.clk(gpif_clk), .reset_in(!clocks_ready), .reset_out(gpif_rst)); + reset_sync bus_sync(.clk(bus_clk), .reset_in(!clocks_ready), .reset_out(bus_rst)); + reset_sync radio_sync(.clk(radio_clk), .reset_in(!clocks_ready), .reset_out(radio_rst)); + + /////////////////////////////////////////////////////////////////////// + // I/O + /////////////////////////////////////////////////////////////////////// + wire [31:0] rx_data0, rx_data1; + wire [31:0] tx_data0, tx_data1; + wire mimo; + + b200_io b200_io_i0 + ( + .reset(reset), + .mimo(mimo), + + // Baseband sample interface + .radio_clk(radio_clk), + + .rx_i0(rx_data0[31:20]), + .rx_q0(rx_data0[15:4]), + .rx_i1(rx_data1[31:20]), + .rx_q1(rx_data1[15:4]), + + .tx_i0(tx_data0[31:20]), + .tx_q0(tx_data0[15:4]), + .tx_i1(tx_data1[31:20]), + .tx_q1(tx_data1[15:4]), + + // Catalina interface + .rx_clk(codec_data_clk_p), + .rx_frame(rx_frame_p), + .rx_data(rx_codec_d), + + .tx_clk(codec_fb_clk_p), + .tx_frame(tx_frame_p), + .tx_data(tx_codec_d) + ); + + assign {rx_data0[19:16],rx_data0[3:0],rx_data1[19:16],rx_data1[3:0]} = 16'h0; + + /////////////////////////////////////////////////////////////////////// + // SPI connections + /////////////////////////////////////////////////////////////////////// + wire mosi, miso, sclk; + wire [7:0] sen; + + //AD9361 Slave + assign cat_ce = sen[0]; + assign cat_mosi = ~sen[0] & mosi; + assign cat_sclk = ~sen[0] & sclk; + assign miso = cat_miso; //PLL does not have a miso + + //ADF4001 Slave + assign pll_ce = sen[1]; + assign pll_mosi = ~sen[1] & mosi; + assign pll_sclk = ~sen[1] & sclk; + + //FX3 Master + //The following signals are routed to the FX3 and were used by an obsolete + //bit-banging SPI engine. + // fx3_ce, fx3_sclk, fx3_mosi <Unused> + assign fx3_miso = 1'bZ; //Safe state because we cannot guarantee the + //direction of this pin in the FX3 + + /////////////////////////////////////////////////////////////////////// + // bus signals + /////////////////////////////////////////////////////////////////////// + wire [63:0] ctrl_tdata, resp_tdata, rx_tdata, tx_tdata; + wire ctrl_tlast, resp_tlast, rx_tlast, tx_tlast; + wire ctrl_tvalid, resp_tvalid, rx_tvalid, tx_tvalid; + wire ctrl_tready, resp_tready, rx_tready, tx_tready; + + + /////////////////////////////////////////////////////////////////////// + // frontend assignments + // Most B2x0's have frontends swapped (radio0 to FE2), but some hardware revisions do not. + // The ATR pins are mapped from radio to frontend here based on the swap_atr_n bit. + /////////////////////////////////////////////////////////////////////// + wire swap_atr_n; + wire [7:0] radio0_gpio, radio1_gpio; + reg [7:0] fe0_gpio, fe1_gpio; + always @(posedge radio_clk) begin //Registers in the IOB + fe0_gpio <= swap_atr_n ? radio1_gpio : radio0_gpio; + fe1_gpio <= swap_atr_n ? radio0_gpio : radio1_gpio; + end + assign {tx_enable1, SFDX1_RX, SFDX1_TX, SRX1_RX, SRX1_TX, LED_RX1, LED_TXRX1_RX, LED_TXRX1_TX} = fe0_gpio; + assign {tx_enable2, SFDX2_RX, SFDX2_TX, SRX2_RX, SRX2_TX, LED_RX2, LED_TXRX2_RX, LED_TXRX2_TX} = fe1_gpio; + + wire [31:0] misc_outs; reg [31:0] misc_outs_r; + + always @(posedge bus_clk) misc_outs_r <= misc_outs; //register misc ios to ease routing to flop + + wire codec_arst; + + assign { swap_atr_n, tx_bandsel_a, tx_bandsel_b, rx_bandsel_a, rx_bandsel_b, rx_bandsel_c, codec_arst, mimo, ref_sel } = misc_outs_r[8:0]; + + assign codec_ctrl_in = 4'b1; + assign codec_en_agc = 1'b1; + assign codec_txrx = 1'b1; + assign codec_enable = 1'b1; + assign codec_reset = ~codec_arst; // Codec Reset // RESETB // Operates active-low + assign codec_sync = 1'b0; + + /////////////////////////////////////////////////////////////////////// + // b200 core + /////////////////////////////////////////////////////////////////////// + wire [9:0] fp_gpio_in, fp_gpio_out, fp_gpio_ddr; + + b200_core #(.EXTRA_BUFF_SIZE(12)) b200_core + ( + .bus_clk(bus_clk), .bus_rst(bus_rst), + .tx_tdata(tx_tdata), .tx_tlast(tx_tlast), .tx_tvalid(tx_tvalid), .tx_tready(tx_tready), + .rx_tdata(rx_tdata), .rx_tlast(rx_tlast), .rx_tvalid(rx_tvalid), .rx_tready(rx_tready), + .ctrl_tdata(ctrl_tdata), .ctrl_tlast(ctrl_tlast), .ctrl_tvalid(ctrl_tvalid), .ctrl_tready(ctrl_tready), + .resp_tdata(resp_tdata), .resp_tlast(resp_tlast), .resp_tvalid(resp_tvalid), .resp_tready(resp_tready), + + .radio_clk(radio_clk), .radio_rst(radio_rst), + .rx0(rx_data0), .rx1(rx_data1), + .tx0(tx_data0), .tx1(tx_data1), + .fe0_gpio_out(radio0_gpio), .fe1_gpio_out(radio1_gpio), + .fp_gpio_in(fp_gpio_in), .fp_gpio_out(fp_gpio_out), .fp_gpio_ddr(fp_gpio_ddr), + + .pps_int(PPS_IN_INT), .pps_ext(PPS_IN_EXT), + + .rxd(gps_txd), .txd(gps_rxd), + .sclk(sclk), .sen(sen), .mosi(mosi), .miso(miso), + .rb_misc({31'b0, pll_lock}), .misc_outs(misc_outs), + + .debug_scl(GPIF_CTL8), .debug_sda(GPIF_CTL6), +`ifdef DEBUG_UART + .debug_txd(FPGA_TXD0), .debug_rxd(FPGA_RXD0), +`else + .debug_txd(), .debug_rxd(1'b0), +`endif + + .lock_signals(codec_ctrl_out[7:6]), + .debug() + ); + +`ifdef TARGET_B210 + `ifdef DEBUG_UART + gpio_atr_io #(.WIDTH(8)) gpio_atr_io_inst ( // B210 with UART + .clk(radio_clk), .gpio_pins(fp_gpio), + .gpio_ddr(fp_gpio_ddr[7:0]), .gpio_out(fp_gpio_out[7:0]), .gpio_in(fp_gpio_in[7:0]) + ); + assign fp_gpio_in[9:8] = 2'b00; + `else + gpio_atr_io #(.WIDTH(10)) gpio_atr_io_inst ( // B210 no UART + .clk(radio_clk), .gpio_pins({FPGA_RXD0, FPGA_TXD0, fp_gpio}), + .gpio_ddr(fp_gpio_ddr), .gpio_out(fp_gpio_out), .gpio_in(fp_gpio_in) + ); + `endif +`else + `ifdef DEBUG_UART + assign fp_gpio_in = 10'h000; // B200 with UART + `else + gpio_atr_io #(.WIDTH(2)) gpio_atr_io_inst ( // B200 no UART + .clk(radio_clk), .gpio_pins({FPGA_RXD0, FPGA_TXD0}), + .gpio_ddr(fp_gpio_ddr[9:8]), .gpio_out(fp_gpio_out[9:8]), .gpio_in(fp_gpio_in[9:8]) + ); + assign fp_gpio_in[7:0] = 8'h00; + `endif +`endif + + /////////////////////////////////////////////////////////////////////// + // GPIF2 + /////////////////////////////////////////////////////////////////////// + + gpif2_slave_fifo32 #(.DATA_RX_FIFO_SIZE(13), .DATA_TX_FIFO_SIZE(13)) slave_fifo32 + ( + .gpif_clk(gpif_clk), .gpif_rst(gpif_rst), .gpif_enb(1'b1), + .gpif_ctl({GPIF_CTL8, GPIF_CTL6, GPIF_CTL5, GPIF_CTL4}), .fifoadr({GPIF_CTL11,GPIF_CTL12}), + .slwr(GPIF_CTL1), .sloe(GPIF_CTL2), .slcs(GPIF_CTL0), .slrd(GPIF_CTL3), .pktend(GPIF_CTL7), + .gpif_d(GPIF_D), + + .fifo_clk(bus_clk), .fifo_rst(bus_rst), + .tx_tdata(tx_tdata), .tx_tlast(tx_tlast), .tx_tvalid(tx_tvalid), .tx_tready(tx_tready), + .rx_tdata(rx_tdata), .rx_tlast(rx_tlast), .rx_tvalid(rx_tvalid), .rx_tready(rx_tready), + .ctrl_tdata(ctrl_tdata), .ctrl_tlast(ctrl_tlast), .ctrl_tvalid(ctrl_tvalid), .ctrl_tready(ctrl_tready), + .resp_tdata(resp_tdata), .resp_tlast(resp_tlast), .resp_tvalid(resp_tvalid), .resp_tready(resp_tready), + + .debug() + ); + + /////////////////////////////////////////////////////////////////////// + // Debug port + /////////////////////////////////////////////////////////////////////// + assign debug = 0; + +endmodule // B200 |