1// 2// Copyright 2013 Ettus Research LLC 3// Copyright 2017 Ettus Research, a National Instruments Company 4// 5// SPDX-License-Identifier: LGPL-3.0-or-later 6// 7 8 9/*********************************************************** 10 * B200 Module Declaration 11 **********************************************************/ 12module b200 ( 13 // SPI Interfaces 14 output cat_ce, 15 input cat_miso, 16 output cat_mosi, 17 output cat_sclk, 18 19 input fx3_ce, 20 output fx3_miso, 21 input fx3_mosi, 22 input fx3_sclk, 23 24 output pll_ce, 25 output pll_mosi, 26 output pll_sclk, 27 28 // UART 29 // By default these provide an FX3 UART console output. Under compile time control they can alternatively 30 // provide 2 (1.8V) GPIO pins which are logically bits [9:8] of the fp_gpio bus. 31 // Used as a UART RXD is an input and TXD an output electrically. 32 // input FPGA_RXD0, // These pins goto 3 pin 0.1" header on B2x0 and 33 // output FPGA_TXD0, // carry FX3 UART. 34 inout FPGA_RXD0, // These pins goto 3 pin 0.1" header J400 on B2x0 and 35 inout FPGA_TXD0, // carry FX3 UART. 36 37 // Catalina Controls 38 output codec_enable, 39 output codec_en_agc, 40 output codec_reset, 41 output codec_sync, 42 output codec_txrx, 43 output [3:0] codec_ctrl_in, // These should be outputs 44 input [7:0] codec_ctrl_out, // MUST BE INPUT 45 46 // Catalina Data 47 input codec_data_clk_p, // Clock from CAT (RX) 48 output codec_fb_clk_p, // Clock to CAT (TX) 49 input [11:0] rx_codec_d, 50 output [11:0] tx_codec_d, 51 input rx_frame_p, 52 output tx_frame_p, 53 54 input cat_clkout_fpga, 55 56 //always on 40MHz clock 57 input codec_main_clk_p, 58 input codec_main_clk_n, 59 60 // Debug Bus 61 output [31:0] debug, 62 output [1:0] debug_clk, 63 64 // GPIF, FX3 Slave FIFO 65 output IFCLK, // pclk 66 input FX3_EXTINT, 67 output GPIF_CTL0, // n_slcs 68 output GPIF_CTL1, // n_slwr 69 output GPIF_CTL2, // n_sloe 70 output GPIF_CTL3, // n_slrd 71 output GPIF_CTL7, // n_pktend 72 input GPIF_CTL4, // slfifo_flags[0] 73 input GPIF_CTL5, // slfifo_flags[1] 74 input GPIF_CTL6, // Serial settings bus from FX3. SDA 75 input GPIF_CTL8, // Serial settings bus from FX3. SCL 76 output GPIF_CTL11, // slfifo_addr[1] 77 output GPIF_CTL12, // slfifo_addr[0] 78 inout [31:0] GPIF_D, 79 input GPIF_CTL9, // global_reset 80 81 // GPS 82 input gps_lock, 83 output gps_rxd, 84 input gps_txd, // FPGA has pullup for unpopulated GPS 85 input gps_txd_nmea, // FPGA has pullup for unpopulated GPS 86 87 // LEDS 88 output LED_RX1, 89 output LED_RX2, 90 output LED_TXRX1_RX, 91 output LED_TXRX1_TX, 92 output LED_TXRX2_RX, 93 output LED_TXRX2_TX, 94 95 // GPIO Header J504 - 10 pin 0.1" 3.3V. 96 // Only present on Rev6 and later boards...these pins unused on Rev5 and earlier. 97 // NOTE: These pins are allocated from complimentry pairs and could potentially be used 98 // as differential style I/O. 99 `ifdef TARGET_B210 100 inout [7:0] fp_gpio, 101 `endif 102 // Misc Hardware Control 103 output ref_sel, 104 input pll_lock, 105 input FPGA_CFG_CS, // Driven by FX3 gpio. 106 input AUX_PWR_ON, // Driven by FX3 gpio. 107 108 // PPS 109 input PPS_IN_EXT, 110 input PPS_IN_INT, 111 112 // RF Hardware Control 113 output SFDX1_RX, 114 output SFDX1_TX, 115 output SFDX2_RX, 116 output SFDX2_TX, 117 output SRX1_RX, 118 output SRX1_TX, 119 output SRX2_RX, 120 output SRX2_TX, 121 output tx_bandsel_a, 122 output tx_bandsel_b, 123 output tx_enable1, 124 output tx_enable2, 125 output rx_bandsel_a, 126 output rx_bandsel_b, 127 output rx_bandsel_c 128 ); 129 130 wire reset_global = GPIF_CTL9; 131 132 /////////////////////////////////////////////////////////////////////// 133 // generate clocks from always on codec main clk 134 /////////////////////////////////////////////////////////////////////// 135 wire bus_clk, gpif_clk, radio_clk; 136 wire locked; 137 b200_clk_gen gen_clks 138 ( 139 .CLK_IN1_40_P(codec_main_clk_p), .CLK_IN1_40_N(codec_main_clk_n), 140 .CLK_OUT1_40_int(), .CLK_OUT2_100_gpif(gpif_clk), .CLK_OUT3_100_bus(), 141 .RESET(reset_global), .LOCKED(locked) 142 ); 143 144 // Bus Clock and GPIF Clock both same 100MHz clock. 145 assign bus_clk = gpif_clk; 146 147 148 //hold-off logic for clocks ready 149 reg [15:0] clocks_ready_count; 150 reg clocks_ready; 151 always @(posedge bus_clk or posedge reset_global or negedge locked) begin 152 if (reset_global | !locked) begin 153 clocks_ready_count <= 16'b0; 154 clocks_ready <= 1'b0; 155 end 156 else if (!clocks_ready) begin 157 clocks_ready_count <= clocks_ready_count + 1'b1; 158 clocks_ready <= (clocks_ready_count == 16'hffff); 159 end 160 end 161 162 /////////////////////////////////////////////////////////////////////// 163 // drive output clocks 164 /////////////////////////////////////////////////////////////////////// 165 wire [1:0] debug_clk_int; 166 //S6CLK2PIN S6CLK2PIN_dbg0 (.I(debug_clk_int[0]), .O(debug_clk[0])); 167 //S6CLK2PIN S6CLK2PIN_dbg1 (.I(debug_clk_int[1]), .O(debug_clk[1])); 168 assign debug_clk[1:0] = 2'b0; 169 S6CLK2PIN S6CLK2PIN_gpif (.I(gpif_clk), .O(IFCLK)); 170 171 /////////////////////////////////////////////////////////////////////// 172 // Create sync reset signals 173 /////////////////////////////////////////////////////////////////////// 174 wire gpif_rst, bus_rst, radio_rst; 175 reset_sync gpif_sync(.clk(gpif_clk), .reset_in(!clocks_ready), .reset_out(gpif_rst)); 176 reset_sync bus_sync(.clk(bus_clk), .reset_in(!clocks_ready), .reset_out(bus_rst)); 177 reset_sync radio_sync(.clk(radio_clk), .reset_in(!clocks_ready), .reset_out(radio_rst)); 178 179 /////////////////////////////////////////////////////////////////////// 180 // I/O 181 /////////////////////////////////////////////////////////////////////// 182 wire [31:0] rx_data0, rx_data1; 183 wire [31:0] tx_data0, tx_data1; 184 wire mimo; 185 186 b200_io b200_io_i0 187 ( 188 .reset(reset), 189 .mimo(mimo), 190 191 // Baseband sample interface 192 .radio_clk(radio_clk), 193 194 .rx_i0(rx_data0[31:20]), 195 .rx_q0(rx_data0[15:4]), 196 .rx_i1(rx_data1[31:20]), 197 .rx_q1(rx_data1[15:4]), 198 199 .tx_i0(tx_data0[31:20]), 200 .tx_q0(tx_data0[15:4]), 201 .tx_i1(tx_data1[31:20]), 202 .tx_q1(tx_data1[15:4]), 203 204 // Catalina interface 205 .rx_clk(codec_data_clk_p), 206 .rx_frame(rx_frame_p), 207 .rx_data(rx_codec_d), 208 209 .tx_clk(codec_fb_clk_p), 210 .tx_frame(tx_frame_p), 211 .tx_data(tx_codec_d) 212 ); 213 214 assign {rx_data0[19:16],rx_data0[3:0],rx_data1[19:16],rx_data1[3:0]} = 16'h0; 215 216 /////////////////////////////////////////////////////////////////////// 217 // SPI connections 218 /////////////////////////////////////////////////////////////////////// 219 wire mosi, miso, sclk; 220 wire [7:0] sen; 221 222 //AD9361 Slave 223 assign cat_ce = sen[0]; 224 assign cat_mosi = ~sen[0] & mosi; 225 assign cat_sclk = ~sen[0] & sclk; 226 assign miso = cat_miso; //PLL does not have a miso 227 228 //ADF4001 Slave 229 assign pll_ce = sen[1]; 230 assign pll_mosi = ~sen[1] & mosi; 231 assign pll_sclk = ~sen[1] & sclk; 232 233 //FX3 Master 234 //The following signals are routed to the FX3 and were used by an obsolete 235 //bit-banging SPI engine. 236 // fx3_ce, fx3_sclk, fx3_mosi <Unused> 237 assign fx3_miso = 1'bZ; //Safe state because we cannot guarantee the 238 //direction of this pin in the FX3 239 240 /////////////////////////////////////////////////////////////////////// 241 // bus signals 242 /////////////////////////////////////////////////////////////////////// 243 wire [63:0] ctrl_tdata, resp_tdata, rx_tdata, tx_tdata; 244 wire ctrl_tlast, resp_tlast, rx_tlast, tx_tlast; 245 wire ctrl_tvalid, resp_tvalid, rx_tvalid, tx_tvalid; 246 wire ctrl_tready, resp_tready, rx_tready, tx_tready; 247 248 249 /////////////////////////////////////////////////////////////////////// 250 // frontend assignments 251 // Most B2x0's have frontends swapped (radio0 to FE2), but some hardware revisions do not. 252 // The ATR pins are mapped from radio to frontend here based on the swap_atr_n bit. 253 /////////////////////////////////////////////////////////////////////// 254 wire swap_atr_n; 255 wire [7:0] radio0_gpio, radio1_gpio; 256 reg [7:0] fe0_gpio, fe1_gpio; 257 always @(posedge radio_clk) begin //Registers in the IOB 258 fe0_gpio <= swap_atr_n ? radio1_gpio : radio0_gpio; 259 fe1_gpio <= swap_atr_n ? radio0_gpio : radio1_gpio; 260 end 261 assign {tx_enable1, SFDX1_RX, SFDX1_TX, SRX1_RX, SRX1_TX, LED_RX1, LED_TXRX1_RX, LED_TXRX1_TX} = fe0_gpio; 262 assign {tx_enable2, SFDX2_RX, SFDX2_TX, SRX2_RX, SRX2_TX, LED_RX2, LED_TXRX2_RX, LED_TXRX2_TX} = fe1_gpio; 263 264 wire [31:0] misc_outs; reg [31:0] misc_outs_r; 265 266 always @(posedge bus_clk) misc_outs_r <= misc_outs; //register misc ios to ease routing to flop 267 268 wire codec_arst; 269 270 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]; 271 272 assign codec_ctrl_in = 4'b1; 273 assign codec_en_agc = 1'b1; 274 assign codec_txrx = 1'b1; 275 assign codec_enable = 1'b1; 276 assign codec_reset = ~codec_arst; // Codec Reset // RESETB // Operates active-low 277 assign codec_sync = 1'b0; 278 279 /////////////////////////////////////////////////////////////////////// 280 // b200 core 281 /////////////////////////////////////////////////////////////////////// 282 wire [9:0] fp_gpio_in, fp_gpio_out, fp_gpio_ddr; 283 284 b200_core #(.EXTRA_BUFF_SIZE(12)) b200_core 285 ( 286 .bus_clk(bus_clk), .bus_rst(bus_rst), 287 .tx_tdata(tx_tdata), .tx_tlast(tx_tlast), .tx_tvalid(tx_tvalid), .tx_tready(tx_tready), 288 .rx_tdata(rx_tdata), .rx_tlast(rx_tlast), .rx_tvalid(rx_tvalid), .rx_tready(rx_tready), 289 .ctrl_tdata(ctrl_tdata), .ctrl_tlast(ctrl_tlast), .ctrl_tvalid(ctrl_tvalid), .ctrl_tready(ctrl_tready), 290 .resp_tdata(resp_tdata), .resp_tlast(resp_tlast), .resp_tvalid(resp_tvalid), .resp_tready(resp_tready), 291 292 .radio_clk(radio_clk), .radio_rst(radio_rst), 293 .rx0(rx_data0), .rx1(rx_data1), 294 .tx0(tx_data0), .tx1(tx_data1), 295 .fe0_gpio_out(radio0_gpio), .fe1_gpio_out(radio1_gpio), 296 .fp_gpio_in(fp_gpio_in), .fp_gpio_out(fp_gpio_out), .fp_gpio_ddr(fp_gpio_ddr), 297 298 .pps_int(PPS_IN_INT), .pps_ext(PPS_IN_EXT), 299 300 .rxd(gps_txd), .txd(gps_rxd), 301 .sclk(sclk), .sen(sen), .mosi(mosi), .miso(miso), 302 .rb_misc({31'b0, pll_lock}), .misc_outs(misc_outs), 303 304 .debug_scl(GPIF_CTL8), .debug_sda(GPIF_CTL6), 305`ifdef DEBUG_UART 306 .debug_txd(FPGA_TXD0), .debug_rxd(FPGA_RXD0), 307`else 308 .debug_txd(), .debug_rxd(1'b0), 309`endif 310 311 .lock_signals(codec_ctrl_out[7:6]), 312 .debug() 313 ); 314 315`ifdef TARGET_B210 316 `ifdef DEBUG_UART 317 gpio_atr_io #(.WIDTH(8)) gpio_atr_io_inst ( // B210 with UART 318 .clk(radio_clk), .gpio_pins(fp_gpio), 319 .gpio_ddr(fp_gpio_ddr[7:0]), .gpio_out(fp_gpio_out[7:0]), .gpio_in(fp_gpio_in[7:0]) 320 ); 321 assign fp_gpio_in[9:8] = 2'b00; 322 `else 323 gpio_atr_io #(.WIDTH(10)) gpio_atr_io_inst ( // B210 no UART 324 .clk(radio_clk), .gpio_pins({FPGA_RXD0, FPGA_TXD0, fp_gpio}), 325 .gpio_ddr(fp_gpio_ddr), .gpio_out(fp_gpio_out), .gpio_in(fp_gpio_in) 326 ); 327 `endif 328`else 329 `ifdef DEBUG_UART 330 assign fp_gpio_in = 10'h000; // B200 with UART 331 `else 332 gpio_atr_io #(.WIDTH(2)) gpio_atr_io_inst ( // B200 no UART 333 .clk(radio_clk), .gpio_pins({FPGA_RXD0, FPGA_TXD0}), 334 .gpio_ddr(fp_gpio_ddr[9:8]), .gpio_out(fp_gpio_out[9:8]), .gpio_in(fp_gpio_in[9:8]) 335 ); 336 assign fp_gpio_in[7:0] = 8'h00; 337 `endif 338`endif 339 340 /////////////////////////////////////////////////////////////////////// 341 // GPIF2 342 /////////////////////////////////////////////////////////////////////// 343 344 gpif2_slave_fifo32 #(.DATA_RX_FIFO_SIZE(13), .DATA_TX_FIFO_SIZE(13)) slave_fifo32 345 ( 346 .gpif_clk(gpif_clk), .gpif_rst(gpif_rst), .gpif_enb(1'b1), 347 .gpif_ctl({GPIF_CTL8, GPIF_CTL6, GPIF_CTL5, GPIF_CTL4}), .fifoadr({GPIF_CTL11,GPIF_CTL12}), 348 .slwr(GPIF_CTL1), .sloe(GPIF_CTL2), .slcs(GPIF_CTL0), .slrd(GPIF_CTL3), .pktend(GPIF_CTL7), 349 .gpif_d(GPIF_D), 350 351 .fifo_clk(bus_clk), .fifo_rst(bus_rst), 352 .tx_tdata(tx_tdata), .tx_tlast(tx_tlast), .tx_tvalid(tx_tvalid), .tx_tready(tx_tready), 353 .rx_tdata(rx_tdata), .rx_tlast(rx_tlast), .rx_tvalid(rx_tvalid), .rx_tready(rx_tready), 354 .ctrl_tdata(ctrl_tdata), .ctrl_tlast(ctrl_tlast), .ctrl_tvalid(ctrl_tvalid), .ctrl_tready(ctrl_tready), 355 .resp_tdata(resp_tdata), .resp_tlast(resp_tlast), .resp_tvalid(resp_tvalid), .resp_tready(resp_tready), 356 357 .debug() 358 ); 359 360 /////////////////////////////////////////////////////////////////////// 361 // Debug port 362 /////////////////////////////////////////////////////////////////////// 363 assign debug = 0; 364 365endmodule // B200 366