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