// // Copyright 2013 Ettus Research LLC // Copyright 2017 Ettus Research, a National Instruments Company // Copyright 2019 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // module bus_int #( parameter NUM_RADIOS = 2, parameter NUM_CHANNELS_PER_RADIO = 2, parameter NUM_CHANNELS = 4 )( input clk, input clk_div2, input reset, input reset_div2, output sen, output sclk, output mosi, input miso, inout scl0, inout sda0, inout scl1, inout sda1, inout scl2, inout sda2, output gps_txd, input gps_rxd, output debug_txd, input debug_rxd, output [1:0] leds, output [3:0] sw_rst, // Timekeeper input pps, // Block connections input ce_clk, input ce_rst, // Radio Connections input radio_clk, input radio_rst, input [ NUM_CHANNELS-1:0] radio_rx_stb, input [32*NUM_CHANNELS-1:0] radio_rx_data, output [ NUM_CHANNELS-1:0] radio_rx_running, input [ NUM_CHANNELS-1:0] radio_tx_stb, output [32*NUM_CHANNELS-1:0] radio_tx_data, output [ NUM_CHANNELS-1:0] radio_tx_running, // Daughter Board Settings Buses output [ NUM_RADIOS-1:0] db_fe_set_stb, output [ 8*NUM_RADIOS-1:0] db_fe_set_addr, output [32*NUM_RADIOS-1:0] db_fe_set_data, input [ NUM_RADIOS-1:0] db_fe_rb_stb, output [ 8*NUM_RADIOS-1:0] db_fe_rb_addr, input [64*NUM_RADIOS-1:0] db_fe_rb_data, // SFP+ 0 input SFPP0_ModAbs, input SFPP0_TxFault, input SFPP0_RxLOS, inout SFPP0_RS0, inout SFPP0_RS1, // SFP+ 1 input SFPP1_ModAbs, input SFPP1_TxFault, input SFPP1_RxLOS, inout SFPP1_RS0, inout SFPP1_RS1, // Front-panel GPIO source output [23:0] fp_gpio_src, // Clock control and status input [7:0] clock_status, output [7:0] clock_control, output [31:0] ref_freq, output ref_freq_changed, // SFP+ 0 data stream output [63:0] sfp0_tx_tdata, output [3:0] sfp0_tx_tuser, output sfp0_tx_tlast, output sfp0_tx_tvalid, input sfp0_tx_tready, input [63:0] sfp0_rx_tdata, input [3:0] sfp0_rx_tuser, input sfp0_rx_tlast, input sfp0_rx_tvalid, output sfp0_rx_tready, // SFP+ 1 data stream output [63:0] sfp1_tx_tdata, output [3:0] sfp1_tx_tuser, output sfp1_tx_tlast, output sfp1_tx_tvalid, input sfp1_tx_tready, input [63:0] sfp1_rx_tdata, input [3:0] sfp1_rx_tuser, input sfp1_rx_tlast, input sfp1_rx_tvalid, output sfp1_rx_tready, // PCIe output [63:0] pcio_tdata, output [2:0] pcio_tuser, output pcio_tlast, output pcio_tvalid, input pcio_tready, input [63:0] pcii_tdata, input [2:0] pcii_tuser, input pcii_tlast, input pcii_tvalid, output pcii_tready, //iop2 message fifos output [63:0] o_iop2_msg_tdata, output o_iop2_msg_tvalid, output o_iop2_msg_tlast, input o_iop2_msg_tready, input [63:0] i_iop2_msg_tdata, input i_iop2_msg_tvalid, input i_iop2_msg_tlast, output i_iop2_msg_tready, //------------------------------------------------------------------ // Wishbone Slave Interface(s) //------------------------------------------------------------------ input [31:0] sfp0_wb_dat_i, output [31:0] sfp0_wb_dat_o, output [15:0] sfp0_wb_adr, output [3:0] sfp0_wb_sel, input sfp0_wb_ack, output sfp0_wb_stb, output sfp0_wb_cyc, output sfp0_wb_we, input sfp0_wb_int, // IJB. Nothing to connect this too!! No IRQ controller on x300. input [31:0] sfp1_wb_dat_i, output [31:0] sfp1_wb_dat_o, output [15:0] sfp1_wb_adr, output [3:0] sfp1_wb_sel, input sfp1_wb_ack, output sfp1_wb_stb, output sfp1_wb_cyc, output sfp1_wb_we, input sfp1_wb_int, // IJB. Nothing to connect this too!! No IRQ controller on x300. input [15:0] sfp0_phy_status, input [15:0] sfp1_phy_status, input [31:0] xadc_readback, // // AXI4 (128b@250MHz) interface to DDR3 controller // input ddr3_axi_clk_x2, input ddr3_axi_rst, // Write Address Ports output [1*2-1:0] ddr3_axi_awid, output [32*2-1:0] ddr3_axi_awaddr, output [8*2-1:0] ddr3_axi_awlen, output [3*2-1:0] ddr3_axi_awsize, output [2*2-1:0] ddr3_axi_awburst, output [1*2-1:0] ddr3_axi_awlock, output [4*2-1:0] ddr3_axi_awcache, output [3*2-1:0] ddr3_axi_awprot, output [4*2-1:0] ddr3_axi_awqos, output [1*2-1:0] ddr3_axi_awvalid, input [1*2-1:0] ddr3_axi_awready, // Write Data Ports output [64*2-1:0] ddr3_axi_wdata, output [8*2-1:0] ddr3_axi_wstrb, output [1*2-1:0] ddr3_axi_wlast, output [1*2-1:0] ddr3_axi_wvalid, input [1*2-1:0] ddr3_axi_wready, // Write Response Ports output [1*2-1:0] ddr3_axi_bready, input [1*2-1:0] ddr3_axi_bid, input [2*2-1:0] ddr3_axi_bresp, input [1*2-1:0] ddr3_axi_bvalid, // Read Address Ports output [1*2-1:0] ddr3_axi_arid, output [32*2-1:0] ddr3_axi_araddr, output [8*2-1:0] ddr3_axi_arlen, output [3*2-1:0] ddr3_axi_arsize, output [2*2-1:0] ddr3_axi_arburst, output [1*2-1:0] ddr3_axi_arlock, output [4*2-1:0] ddr3_axi_arcache, output [3*2-1:0] ddr3_axi_arprot, output [4*2-1:0] ddr3_axi_arqos, output [1*2-1:0] ddr3_axi_arvalid, input [1*2-1:0] ddr3_axi_arready, // Read Data Ports input [1*2-1:0] ddr3_axi_rid, input [64*2-1:0] ddr3_axi_rdata, input [2*2-1:0] ddr3_axi_rresp, input [1*2-1:0] ddr3_axi_rlast, input [1*2-1:0] ddr3_axi_rvalid, output [1*2-1:0] ddr3_axi_rready, // Debug output [31:0] debug0, output [31:0] debug1, output [127:0] debug2); localparam SR_AWIDTH = 8; localparam RB_AWIDTH = 8; localparam SR_LEDS = 8'd00; localparam SR_SW_RST = 8'd01; localparam SR_CLOCK_CTRL = 8'd02; localparam SR_DEVICE_ID = 8'd03; localparam SR_REF_FREQ = 8'd04; localparam SR_SFPP_CTRL0 = 8'd08; localparam SR_SFPP_CTRL1 = 8'd09; localparam SR_SPI = 8'd32; localparam SR_ETHINT0 = 8'd40; localparam SR_ETHINT1 = 8'd56; localparam SR_FP_GPIO_SRC = 8'd72; localparam SR_BASE_TIME = 8'd100; localparam RB_COUNTER = 8'd00; localparam RB_SPI_RDY = 8'd01; localparam RB_SPI_DATA = 8'd02; localparam RB_CLK_STATUS = 8'd03; localparam RB_ETH_TYPE0 = 8'd04; localparam RB_ETH_TYPE1 = 8'd05; localparam RB_COMPAT_NUM = 8'd06; localparam RB_RFNOC_INFO = 8'd07; localparam RB_SFPP_STATUS0 = 8'd08; localparam RB_SFPP_STATUS1 = 8'd09; localparam RB_GIT_HASH = 8'd10; localparam RB_XADC_VALS = 8'd11; localparam RB_NUM_TIMEKEEPERS = 8'd12; localparam RB_FP_GPIO_SRC = 8'd13; localparam COMPAT_MAJOR = 16'h0026; localparam COMPAT_MINOR = 16'h0000; localparam NUM_TIMEKEEPERS = 1; localparam [15:0] RFNOC_PROTOVER = {8'd1, 8'd0}; wire [31:0] set_data; wire [7:0] set_addr; reg [31:0] rb_data; wire [RB_AWIDTH-1:0] rb_addr; wire rb_rd_stb; wire set_stb; wire spi_ready; wire [31:0] rb_spi_data; wire [15:0] device_id; wire m_ctrlport_req_wr_radio0; wire m_ctrlport_req_rd_radio0; wire [19:0] m_ctrlport_req_addr_radio0; wire [31:0] m_ctrlport_req_data_radio0; wire [3:0] m_ctrlport_req_byte_en_radio0; wire m_ctrlport_req_has_time_radio0; wire [63:0] m_ctrlport_req_time_radio0; wire m_ctrlport_resp_ack_radio0; wire [1:0] m_ctrlport_resp_status_radio0; wire [31:0] m_ctrlport_resp_data_radio0; wire m_ctrlport_req_wr_radio1; wire m_ctrlport_req_rd_radio1; wire [19:0] m_ctrlport_req_addr_radio1; wire [31:0] m_ctrlport_req_data_radio1; wire [3:0] m_ctrlport_req_byte_en_radio1; wire m_ctrlport_req_has_time_radio1; wire [63:0] m_ctrlport_req_time_radio1; wire m_ctrlport_resp_ack_radio1; wire [1:0] m_ctrlport_resp_status_radio1; wire [31:0] m_ctrlport_resp_data_radio1; // ZPU in and ZPU out axi streams wire [63:0] zpui_tdata, zpuo_tdata; wire [3:0] zpui_tuser, zpuo_tuser; wire zpui_tlast, zpuo_tlast, zpui_tvalid, zpuo_tvalid, zpui_tready, zpuo_tready; wire [63:0] zpui0_tdata, zpuo0_tdata; wire [3:0] zpui0_tuser, zpuo0_tuser; wire zpui0_tlast, zpuo0_tlast, zpui0_tvalid, zpuo0_tvalid, zpui0_tready, zpuo0_tready; wire [63:0] zpui1_tdata, zpuo1_tdata; wire [3:0] zpui1_tuser, zpuo1_tuser; wire zpui1_tlast, zpuo1_tlast, zpui1_tvalid, zpuo1_tvalid, zpui1_tready, zpuo1_tready; // v2e (vita to ethernet) and e2v (eth to vita) wire [63:0] v2e0_tdata, v2e1_tdata, e2v0_tdata, e2v1_tdata; wire v2e0_tlast, v2e1_tlast, v2e0_tvalid, v2e1_tvalid, v2e0_tready, v2e1_tready; wire e2v0_tlast, e2v1_tlast, e2v0_tvalid, e2v1_tvalid, e2v0_tready, e2v1_tready; //settings bus for crossbar router wire [31:0] set_data_xb; wire [8:0] set_addr_xb; wire set_stb_xb; // SFP+ logic wire SFPP0_ModAbs_sync, SFPP0_TxFault_sync, SFPP0_RxLOS_sync; reg SFPP0_ModAbs_reg, SFPP0_TxFault_reg, SFPP0_RxLOS_reg; reg SFPP0_ModAbs_chgd, SFPP0_TxFault_chgd, SFPP0_RxLOS_chgd; wire SFPP1_ModAbs_sync, SFPP1_TxFault_sync, SFPP1_RxLOS_sync; reg SFPP1_ModAbs_reg, SFPP1_TxFault_reg, SFPP1_RxLOS_reg; reg SFPP1_ModAbs_chgd, SFPP1_TxFault_chgd, SFPP1_RxLOS_chgd; wire [15:0] sfp0_phy_status_sync, sfp1_phy_status_sync; //////////////////////////////////////////////////////////////////// // Soft CPU - drives network setup, soft reset, ICMP, ... //////////////////////////////////////////////////////////////////// soft_ctrl #(.SB_ADDRW(SR_AWIDTH), .RB_ADDRW(RB_AWIDTH)) sc ( .clk(clk), .rst(reset), .clk_div2(clk_div2), .rst_div2(reset_div2), //------------------------------------------------------------------ // I2C interfaces //------------------------------------------------------------------ .scl0(scl0), .sda0(sda0), .scl1(scl1), .sda1(sda1), .scl2(scl2), .sda2(sda2), //------------------------------------------------------------------ // UARTs for CPU comms //------------------------------------------------------------------ .gps_rxd(gps_rxd), .gps_txd(gps_txd), .debug_rxd(debug_rxd), .debug_txd(debug_txd), //------------------------------------------------------------------ // settings bus interface //------------------------------------------------------------------ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), //------------------------------------------------------------------ // settings bus interface for crossbar router //------------------------------------------------------------------ .set_stb_xb(set_stb_xb), .set_addr_xb(set_addr_xb), .set_data_xb(set_data_xb), //------------------------------------------------------------------ // readback bus interface //------------------------------------------------------------------ .rb_addr(rb_addr), .rb_data(rb_data), .rb_rd_stb(rb_rd_stb), //------------------------------------------------------------------ // packet interface in //------------------------------------------------------------------ .rx_tdata(zpui_tdata), .rx_tuser(zpui_tuser), .rx_tlast(zpui_tlast), .rx_tvalid(zpui_tvalid), .rx_tready(zpui_tready), //------------------------------------------------------------------ // packet interface out //------------------------------------------------------------------ .tx_tdata(zpuo_tdata), .tx_tuser(zpuo_tuser), .tx_tlast(zpuo_tlast), .tx_tvalid(zpuo_tvalid), .tx_tready(zpuo_tready), //------------------------------------------------------------------ // Wishbone Slave Interface(s) //------------------------------------------------------------------ .s4_dat_i(sfp0_wb_dat_i), .s4_dat_o(sfp0_wb_dat_o), .s4_adr(sfp0_wb_adr), .s4_sel(sfp0_wb_sel), .s4_ack(sfp0_wb_ack), .s4_stb(sfp0_wb_stb), .s4_cyc(sfp0_wb_cyc), .s4_we(sfp0_wb_we), .s4_int(sfp0_wb_int), //------------------------------------------------------------------ // IoPort2 Msg Interface //------------------------------------------------------------------ .o_iop2_msg_tdata(o_iop2_msg_tdata), .o_iop2_msg_tvalid(o_iop2_msg_tvalid), .o_iop2_msg_tlast(o_iop2_msg_tlast), .o_iop2_msg_tready(o_iop2_msg_tready), .i_iop2_msg_tdata(i_iop2_msg_tdata), .i_iop2_msg_tvalid(i_iop2_msg_tvalid), .i_iop2_msg_tlast(i_iop2_msg_tlast), .i_iop2_msg_tready(i_iop2_msg_tready), .s5_dat_i(sfp1_wb_dat_i), .s5_dat_o(sfp1_wb_dat_o), .s5_adr(sfp1_wb_adr), .s5_sel(sfp1_wb_sel), .s5_ack(sfp1_wb_ack), .s5_stb(sfp1_wb_stb), .s5_cyc(sfp1_wb_cyc), .s5_we(sfp1_wb_we), .s5_int(sfp1_wb_int), //------------------------------------------------------------------ // Debug //------------------------------------------------------------------ .debug0(debug2), .debug1() ); setting_reg #(.my_addr(SR_LEDS), .awidth(SR_AWIDTH), .width(2)) set_leds (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(leds)); // // SW_RST - Bit allocation: // [0] - PHY reset // [1] - Radio clk domain reset // [2] - Radio Clk PLL reset. // [3] - ADC IdelayCtrl reset // setting_reg #(.my_addr(SR_SW_RST), .awidth(SR_AWIDTH), .width(4)) set_sw_rst (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(sw_rst)); setting_reg #(.my_addr(SR_CLOCK_CTRL), .awidth(SR_AWIDTH), .width(8), .at_reset(7'b1000000) //bit 6 high means GPSDO on by default ) set_clk_ctrl (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(clock_control)); setting_reg #(.my_addr(SR_DEVICE_ID), .awidth(SR_AWIDTH), .width(16), .at_reset(32'd0) ) set_dev_id (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(device_id), .changed()); setting_reg #(.my_addr(SR_REF_FREQ), .awidth(SR_AWIDTH), .width(32), .at_reset(32'd10_000_000) //default to 10 MHz reference clock ) set_ref_freq (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(ref_freq), .changed(ref_freq_changed)); simple_spi_core #(.BASE(SR_SPI), .WIDTH(1), .CLK_IDLE(0), .SEN_IDLE(1'b1)) misc_spi (.clock(clk), .reset(reset), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .readback(rb_spi_data), .ready(spi_ready), .sen(sen), .sclk(sclk), .mosi(mosi), .miso(miso), .debug()); reg [31:0] counter; wire [31:0] rb_data_crossbar = 32'h0; wire [63:0] radio_time_tb; wire [63:0] radio_time_last_pps_tb; wire [63:0] period_ns_q32_tb; wire [63:0] radio_time; wire [63:0] radio_time_last_pps; reg [31:0] radio_time_hi; reg [31:0] radio_time_last_pps_hi; reg radio_time_hi_ld; reg radio_time_last_pps_hi_ld; always @(posedge clk) counter <= counter + 1; always @* begin radio_time_hi_ld = 1'b0; radio_time_last_pps_hi_ld = 1'b0; casex (rb_addr) RB_RFNOC_INFO: rb_data = {device_id, RFNOC_PROTOVER[15:0]}; RB_COMPAT_NUM: rb_data = {COMPAT_MAJOR[15:0], COMPAT_MINOR[15:0]}; RB_COUNTER: rb_data = counter; RB_SPI_RDY: rb_data = {31'b0, spi_ready}; RB_SPI_DATA: rb_data = rb_spi_data; RB_CLK_STATUS: rb_data = {24'b0, clock_status}; // SFPP Interface pins. RB_SFPP_STATUS0: rb_data = { sfp0_phy_status_sync, 10'b0, SFPP0_ModAbs_chgd, SFPP0_TxFault_chgd, SFPP0_RxLOS_chgd, SFPP0_ModAbs_sync, SFPP0_TxFault_sync, SFPP0_RxLOS_sync}; RB_SFPP_STATUS1: rb_data = { sfp1_phy_status_sync, 10'b0, SFPP1_ModAbs_chgd, SFPP1_TxFault_chgd, SFPP1_RxLOS_chgd, SFPP1_ModAbs_sync, SFPP1_TxFault_sync, SFPP1_RxLOS_sync}; RB_NUM_TIMEKEEPERS: rb_data = NUM_TIMEKEEPERS; // Allow readback of configured ethernet interfaces. `ifdef SFP0_AURORA RB_ETH_TYPE0: rb_data = {32'h2}; `else `ifdef SFP0_10GBE RB_ETH_TYPE0: rb_data = {32'h1}; `else RB_ETH_TYPE0: rb_data = {32'h0}; `endif `endif `ifdef SFP1_AURORA RB_ETH_TYPE1: rb_data = {32'h2}; `else `ifdef SFP1_10GBE RB_ETH_TYPE1: rb_data = {32'h1}; `else RB_ETH_TYPE1: rb_data = {32'h0}; `endif `endif RB_GIT_HASH: rb_data = `GIT_HASH; RB_XADC_VALS: rb_data = xadc_readback; RB_FP_GPIO_SRC: rb_data = fp_gpio_src; SR_BASE_TIME: begin rb_data = radio_time[31:0]; radio_time_hi_ld = 1'b1; end SR_BASE_TIME + 'h04: rb_data = radio_time_hi; SR_BASE_TIME + 'h14: begin rb_data = radio_time_last_pps[31:0]; radio_time_last_pps_hi_ld = 1'b1; end SR_BASE_TIME + 'h18: rb_data = radio_time_last_pps_hi; SR_BASE_TIME + 'h1C: rb_data = period_ns_q32_tb[31:0]; SR_BASE_TIME + 'h20: rb_data = period_ns_q32_tb[63:32]; default: begin rb_data = 32'h0; end endcase // case (rb_addr) end always @(posedge clk_div2) begin if (radio_time_hi_ld) radio_time_hi <= radio_time[63:32]; if (radio_time_last_pps_hi_ld) radio_time_last_pps_hi <= radio_time_last_pps[63:32]; end // Timekeeper axi_fifo_2clk #( .WIDTH (64), .SIZE (3) ) radio_time_clk_cross_fifo ( .reset (radio_rst), .i_aclk (radio_clk), .i_tdata (radio_time_tb), .i_tvalid (1'b1), .i_tready (), .o_aclk (clk_div2), .o_tdata (radio_time), .o_tready (1'b1), .o_tvalid () ); axi_fifo_2clk #( .WIDTH (64), .SIZE (3) ) radio_time_last_pps_clk_cross_fifo ( .reset (radio_rst), .i_aclk (radio_clk), .i_tdata (radio_time_last_pps_tb), .i_tvalid (1'b1), .i_tready (), .o_aclk (clk_div2), .o_tdata (radio_time_last_pps), .o_tready (1'b1), .o_tvalid () ); timekeeper #( .BASE_ADDR (SR_BASE_TIME), .TIME_INCREMENT (1'b1) ) timekeeper_i ( .tb_clk (radio_clk), .tb_rst (radio_rst), .s_ctrlport_clk (clk_div2), .s_ctrlport_req_wr (set_stb), .s_ctrlport_req_rd (), .s_ctrlport_req_addr (set_addr), .s_ctrlport_req_data (set_data), .s_ctrlport_resp_ack (), .s_ctrlport_resp_data (), .sample_rx_stb (radio_rx_stb[0]), .pps (pps), .tb_timestamp (radio_time_tb), .tb_timestamp_last_pps (radio_time_last_pps_tb), .tb_period_ns_q32 (period_ns_q32_tb) ); // Latch state changes to SFP0+ pins. synchronizer #(.INITIAL_VAL(1'b0)) sfpp0_modabs_sync ( .clk(clk), .rst(1'b0 /* no reset */), .in(SFPP0_ModAbs), .out(SFPP0_ModAbs_sync)); synchronizer #(.INITIAL_VAL(1'b0)) sfpp0_txfault_sync ( .clk(clk), .rst(1'b0 /* no reset */), .in(SFPP0_TxFault), .out(SFPP0_TxFault_sync)); synchronizer #(.INITIAL_VAL(1'b0)) sfpp0_rxlos_sync ( .clk(clk), .rst(1'b0 /* no reset */), .in(SFPP0_RxLOS), .out(SFPP0_RxLOS_sync)); always @(posedge clk) begin SFPP0_ModAbs_reg <= SFPP0_ModAbs_sync; SFPP0_TxFault_reg <= SFPP0_TxFault_sync; SFPP0_RxLOS_reg <= SFPP0_RxLOS_sync; end always @(posedge clk) begin if (reset || (rb_rd_stb && (rb_addr == RB_SFPP_STATUS0))) begin SFPP0_ModAbs_chgd <= 1'b0; SFPP0_TxFault_chgd <= 1'b0; SFPP0_RxLOS_chgd <= 1'b0; end else begin if (SFPP0_ModAbs_sync != SFPP0_ModAbs_reg) SFPP0_ModAbs_chgd <= 1'b1; if (SFPP0_TxFault_sync != SFPP0_TxFault_reg) SFPP0_TxFault_chgd <= 1'b1; if (SFPP0_RxLOS_sync != SFPP0_RxLOS_reg) SFPP0_RxLOS_chgd <= 1'b1; end end // Latch state changes to SFP1+ pins. synchronizer #(.INITIAL_VAL(1'b0)) sfpp1_modabs_sync ( .clk(clk), .rst(1'b0 /* no reset */), .in(SFPP1_ModAbs), .out(SFPP1_ModAbs_sync)); synchronizer #(.INITIAL_VAL(1'b0)) sfpp1_txfault_sync ( .clk(clk), .rst(1'b0 /* no reset */), .in(SFPP1_TxFault), .out(SFPP1_TxFault_sync)); synchronizer #(.INITIAL_VAL(1'b0)) sfpp1_rxlos_sync ( .clk(clk), .rst(1'b0 /* no reset */), .in(SFPP1_RxLOS), .out(SFPP1_RxLOS_sync)); always @(posedge clk) begin SFPP1_ModAbs_reg <= SFPP1_ModAbs_sync; SFPP1_TxFault_reg <= SFPP1_TxFault_sync; SFPP1_RxLOS_reg <= SFPP1_RxLOS_sync; end always @(posedge clk) begin if (reset || (rb_rd_stb && (rb_addr == RB_SFPP_STATUS1))) begin SFPP1_ModAbs_chgd <= 1'b0; SFPP1_TxFault_chgd <= 1'b0; SFPP1_RxLOS_chgd <= 1'b0; end else begin if (SFPP1_ModAbs_sync != SFPP1_ModAbs_reg) SFPP1_ModAbs_chgd <= 1'b1; if (SFPP1_TxFault_sync != SFPP1_TxFault_reg) SFPP1_TxFault_chgd <= 1'b1; if (SFPP1_RxLOS_sync != SFPP1_RxLOS_reg) SFPP1_RxLOS_chgd <= 1'b1; end end //Synchronize ethernet PHY status bits to bus_clk //All bits in the bus can be treated as asynchronous genvar i; generate for (i=0; i<16; i=i+1) begin: eth_status_synchronizer_gen synchronizer #(.INITIAL_VAL(1'b0)) sfp0_status ( .clk(clk), .rst(1'b0 /* no reset */), .in(sfp0_phy_status[i]), .out(sfp0_phy_status_sync[i])); synchronizer #(.INITIAL_VAL(1'b0)) sfp1_status ( .clk(clk), .rst(1'b0 /* no reset */), .in(sfp1_phy_status[i]), .out(sfp1_phy_status_sync[i])); end endgenerate wire [1:0] sfpp0_ctrl; // SFPP_RS0/1 pins are open drain. setting_reg #(.my_addr(SR_SFPP_CTRL0), .awidth(SR_AWIDTH), .width(2), .at_reset(2'b00)) set_sfpp0_ctrl (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(sfpp0_ctrl)); assign SFPP0_RS0 = sfpp0_ctrl[0] ? 1'b0 : 1'bz; assign SFPP0_RS1 = sfpp0_ctrl[1] ? 1'b0 : 1'bz; wire [1:0] sfpp1_ctrl; // SFPP1_RS0/1 pins are open drain. setting_reg #(.my_addr(SR_SFPP_CTRL1), .awidth(SR_AWIDTH), .width(2), .at_reset(2'b00)) set_sfpp1_ctrl (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(sfpp1_ctrl)); assign SFPP1_RS0 = sfpp1_ctrl[0] ? 1'b0 : 1'bz; assign SFPP1_RS1 = sfpp1_ctrl[1] ? 1'b0 : 1'bz; // Front-panel GPIO source - Each pin is allocated 2 bits setting_reg #(.my_addr(SR_FP_GPIO_SRC), .awidth(SR_AWIDTH), .width(24)) set_fp_gpio_src (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(fp_gpio_src)); // //////////////////////////////////////////////////////////////// // ETH interfaces `ifdef SFP0_AURORA // The packet format over Aurora is CHDR so we don't need any special framing/deframing assign {e2v0_tdata, e2v0_tlast, e2v0_tvalid, sfp0_rx_tready} = {sfp0_rx_tdata, sfp0_rx_tlast, sfp0_rx_tvalid, e2v0_tready}; assign {sfp0_tx_tdata, sfp0_tx_tlast, sfp0_tx_tvalid, v2e0_tready} = {v2e0_tdata, v2e0_tlast, v2e0_tvalid, sfp0_tx_tready}; assign {zpui0_tdata, zpui0_tlast, zpui0_tvalid, zpuo0_tready} = {64'h0, 1'b0, 1'b0, 1'b1}; `else x300_eth_interface #( .PROTOVER(RFNOC_PROTOVER), .MTU(10), .NODE_INST(0), .BASE(SR_ETHINT0) ) eth_interface0 ( .clk(clk), .reset(reset), .device_id(device_id), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .eth_tx_tdata(sfp0_tx_tdata), .eth_tx_tuser(sfp0_tx_tuser), .eth_tx_tlast(sfp0_tx_tlast), .eth_tx_tvalid(sfp0_tx_tvalid), .eth_tx_tready(sfp0_tx_tready), .eth_rx_tdata(sfp0_rx_tdata), .eth_rx_tuser(sfp0_rx_tuser), .eth_rx_tlast(sfp0_rx_tlast), .eth_rx_tvalid(sfp0_rx_tvalid), .eth_rx_tready(sfp0_rx_tready), .e2v_tdata(e2v0_tdata), .e2v_tlast(e2v0_tlast), .e2v_tvalid(e2v0_tvalid), .e2v_tready(e2v0_tready), .v2e_tdata(v2e0_tdata), .v2e_tlast(v2e0_tlast), .v2e_tvalid(v2e0_tvalid), .v2e_tready(v2e0_tready), .e2z_tdata(zpui0_tdata), .e2z_tuser(zpui0_tuser), .e2z_tlast(zpui0_tlast), .e2z_tvalid(zpui0_tvalid), .e2z_tready(zpui0_tready), .z2e_tdata(zpuo0_tdata), .z2e_tuser(zpuo0_tuser), .z2e_tlast(zpuo0_tlast), .z2e_tvalid(zpuo0_tvalid), .z2e_tready(zpuo0_tready) ); `endif `ifdef SFP1_AURORA // The packet format over Aurora is CHDR so we don't need any special framing/deframing assign {e2v1_tdata, e2v1_tlast, e2v1_tvalid, sfp1_rx_tready} = {sfp1_rx_tdata, sfp1_rx_tlast, sfp1_rx_tvalid, e2v1_tready}; assign {sfp1_tx_tdata, sfp1_tx_tlast, sfp1_tx_tvalid, v2e1_tready} = {v2e1_tdata, v2e1_tlast, v2e1_tvalid, sfp1_tx_tready}; assign {zpui1_tdata, zpui1_tlast, zpui1_tvalid, zpuo1_tready} = {64'h0, 1'b0, 1'b0, 1'b1}; `else x300_eth_interface #( .PROTOVER(RFNOC_PROTOVER), .MTU(10), .NODE_INST(1), .BASE(SR_ETHINT1) ) eth_interface1 ( .clk(clk), .reset(reset), .device_id(device_id), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), .eth_tx_tdata(sfp1_tx_tdata), .eth_tx_tuser(sfp1_tx_tuser), .eth_tx_tlast(sfp1_tx_tlast), .eth_tx_tvalid(sfp1_tx_tvalid), .eth_tx_tready(sfp1_tx_tready), .eth_rx_tdata(sfp1_rx_tdata), .eth_rx_tuser(sfp1_rx_tuser), .eth_rx_tlast(sfp1_rx_tlast), .eth_rx_tvalid(sfp1_rx_tvalid), .eth_rx_tready(sfp1_rx_tready), .e2v_tdata(e2v1_tdata), .e2v_tlast(e2v1_tlast), .e2v_tvalid(e2v1_tvalid), .e2v_tready(e2v1_tready), .v2e_tdata(v2e1_tdata), .v2e_tlast(v2e1_tlast), .v2e_tvalid(v2e1_tvalid), .v2e_tready(v2e1_tready), .e2z_tdata(zpui1_tdata), .e2z_tuser(zpui1_tuser), .e2z_tlast(zpui1_tlast), .e2z_tvalid(zpui1_tvalid), .e2z_tready(zpui1_tready), .z2e_tdata(zpuo1_tdata), .z2e_tuser(zpuo1_tuser), .z2e_tlast(zpuo1_tlast), .z2e_tvalid(zpuo1_tvalid), .z2e_tready(zpuo1_tready) ); `endif axi_mux4 #(.PRIO(0), .WIDTH(68)) zpui_mux (.clk(clk), .reset(reset), .clear(1'b0), .i0_tdata({zpui0_tuser,zpui0_tdata}), .i0_tlast(zpui0_tlast), .i0_tvalid(zpui0_tvalid), .i0_tready(zpui0_tready), .i1_tdata({zpui1_tuser,zpui1_tdata}), .i1_tlast(zpui1_tlast), .i1_tvalid(zpui1_tvalid), .i1_tready(zpui1_tready), .i2_tdata(68'h0), .i2_tlast(1'b0), .i2_tvalid(1'b0), .i2_tready(), .i3_tdata(68'h0), .i3_tlast(1'b0), .i3_tvalid(1'b0), .i3_tready(), .o_tdata({zpui_tuser,zpui_tdata}), .o_tlast(zpui_tlast), .o_tvalid(zpui_tvalid), .o_tready(zpui_tready)); // Demux ZPU to Eth output by the port number in top 8 bits of data on first line wire [67:0] zpuo_eth_header; wire [1:0] zpuo_eth_dest = (zpuo_eth_header[63:56] == 8'd0) ? 2'b00 : 2'b01; axi_demux4 #(.ACTIVE_CHAN(4'b0011), .WIDTH(68)) zpuo_demux (.clk(clk), .reset(reset), .clear(1'b0), .header(zpuo_eth_header), .dest(zpuo_eth_dest), .i_tdata({zpuo_tuser,zpuo_tdata}), .i_tlast(zpuo_tlast), .i_tvalid(zpuo_tvalid), .i_tready(zpuo_tready), .o0_tdata({zpuo0_tuser,zpuo0_tdata}), .o0_tlast(zpuo0_tlast), .o0_tvalid(zpuo0_tvalid), .o0_tready(zpuo0_tready), .o1_tdata({zpuo1_tuser,zpuo1_tdata}), .o1_tlast(zpuo1_tlast), .o1_tvalid(zpuo1_tvalid), .o1_tready(zpuo1_tready), .o2_tdata(), .o2_tlast(), .o2_tvalid(), .o2_tready(1'b1), .o3_tdata(), .o3_tlast(), .o3_tvalid(), .o3_tready(1'b1)); // // End ETH interfaces //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // PCIe Interface // localparam DMA_RX_DEST_WIDTH = 3; // PCIe to CHDR (p2c) and CHDR to PCIe (c2p) wire [63:0] p2c_tdata; wire p2c_tlast, p2c_tvalid, p2c_tready; wire [63:0] c2p_tdata; wire c2p_tlast, c2p_tvalid, c2p_tready; // Transport adapter with the management interface nirio_chdr64_adapter #( .PROTOVER(RFNOC_PROTOVER), .DMA_ID_WIDTH(DMA_RX_DEST_WIDTH) ) nirio_xport_adapter ( .clk(clk), .rst(reset), .device_id(device_id), // From x300_pcie_int .s_dma_tdata(pcii_tdata), .s_dma_tuser(pcii_tuser), .s_dma_tlast(pcii_tlast), .s_dma_tvalid(pcii_tvalid), .s_dma_tready(pcii_tready), // To x300_pcie_int .m_dma_tdata(pcio_tdata), .m_dma_tuser(pcio_tuser), .m_dma_tlast(pcio_tlast), .m_dma_tvalid(pcio_tvalid), .m_dma_tready(pcio_tready), // From xport adapter into the image core .m_chdr_tdata(p2c_tdata), .m_chdr_tlast(p2c_tlast), .m_chdr_tvalid(p2c_tvalid), .m_chdr_tready(p2c_tready), // From image core into the xport adapter .s_chdr_tdata(c2p_tdata), .s_chdr_tlast(c2p_tlast), .s_chdr_tvalid(c2p_tvalid), .s_chdr_tready(c2p_tready) ); // // End PCIe Interface /////////////////////////////////////////////////////////////////////////// rfnoc_image_core #( .PROTOVER(RFNOC_PROTOVER) ) rfnoc_sandbox_i ( .chdr_aclk (clk ), .ctrl_aclk (clk_div2 ), .core_arst (reset ), .device_id (device_id ), .radio_clk (radio_clk ), .ce_clk (ce_clk ), .dram_clk (ddr3_axi_clk_x2), .m_ctrlport_radio1_req_wr (m_ctrlport_req_wr_radio1 ), .m_ctrlport_radio1_req_rd (m_ctrlport_req_rd_radio1 ), .m_ctrlport_radio1_req_addr (m_ctrlport_req_addr_radio1 ), .m_ctrlport_radio1_req_data (m_ctrlport_req_data_radio1 ), .m_ctrlport_radio1_req_byte_en (m_ctrlport_req_byte_en_radio1 ), .m_ctrlport_radio1_req_has_time (m_ctrlport_req_has_time_radio1), .m_ctrlport_radio1_req_time (m_ctrlport_req_time_radio1 ), .m_ctrlport_radio1_resp_ack (m_ctrlport_resp_ack_radio1 ), .m_ctrlport_radio1_resp_status (m_ctrlport_resp_status_radio1 ), .m_ctrlport_radio1_resp_data (m_ctrlport_resp_data_radio1 ), .m_ctrlport_radio0_req_wr (m_ctrlport_req_wr_radio0 ), .m_ctrlport_radio0_req_rd (m_ctrlport_req_rd_radio0 ), .m_ctrlport_radio0_req_addr (m_ctrlport_req_addr_radio0 ), .m_ctrlport_radio0_req_data (m_ctrlport_req_data_radio0 ), .m_ctrlport_radio0_req_byte_en (m_ctrlport_req_byte_en_radio0 ), .m_ctrlport_radio0_req_has_time (m_ctrlport_req_has_time_radio0), .m_ctrlport_radio0_req_time (m_ctrlport_req_time_radio0 ), .m_ctrlport_radio0_resp_ack (m_ctrlport_resp_ack_radio0 ), .m_ctrlport_radio0_resp_status (m_ctrlport_resp_status_radio0 ), .m_ctrlport_radio0_resp_data (m_ctrlport_resp_data_radio0 ), .radio_time (radio_time_tb ), .radio_rx_stb_radio0 (radio_rx_stb[1:0] ), .radio_rx_data_radio0 (radio_rx_data[63:0] ), .radio_rx_running_radio0 (radio_rx_running[1:0] ), .radio_tx_stb_radio0 (radio_tx_stb[1:0] ), .radio_tx_data_radio0 (radio_tx_data[63:0] ), .radio_tx_running_radio0 (radio_tx_running[1:0] ), .radio_rx_stb_radio1 (radio_rx_stb[3:2] ), .radio_rx_data_radio1 (radio_rx_data[127:64] ), .radio_rx_running_radio1 (radio_rx_running[3:2] ), .radio_tx_stb_radio1 (radio_tx_stb[3:2] ), .radio_tx_data_radio1 (radio_tx_data[127:64] ), .radio_tx_running_radio1 (radio_tx_running[3:2] ), // DRAM interface .axi_rst (ddr3_axi_rst), // Slave Interface Write Address Ports .m_axi_awid (ddr3_axi_awid ), .m_axi_awaddr (ddr3_axi_awaddr ), .m_axi_awlen (ddr3_axi_awlen ), .m_axi_awsize (ddr3_axi_awsize ), .m_axi_awburst (ddr3_axi_awburst), .m_axi_awlock (ddr3_axi_awlock ), .m_axi_awcache (ddr3_axi_awcache), .m_axi_awprot (ddr3_axi_awprot ), .m_axi_awqos (ddr3_axi_awqos ), .m_axi_awregion (), .m_axi_awuser (), .m_axi_awvalid (ddr3_axi_awvalid), .m_axi_awready (ddr3_axi_awready), // Slave Interface Write Data Ports .m_axi_wdata (ddr3_axi_wdata ), .m_axi_wstrb (ddr3_axi_wstrb ), .m_axi_wlast (ddr3_axi_wlast ), .m_axi_wuser (), .m_axi_wvalid (ddr3_axi_wvalid), .m_axi_wready (ddr3_axi_wready), // Slave Interface Write Response Ports .m_axi_bid (ddr3_axi_bid ), .m_axi_bresp (ddr3_axi_bresp ), .m_axi_buser (), .m_axi_bvalid (ddr3_axi_bvalid), .m_axi_bready (ddr3_axi_bready), // Slave Interface Read Address Ports .m_axi_arid (ddr3_axi_arid ), .m_axi_araddr (ddr3_axi_araddr ), .m_axi_arlen (ddr3_axi_arlen ), .m_axi_arsize (ddr3_axi_arsize ), .m_axi_arburst (ddr3_axi_arburst), .m_axi_arlock (ddr3_axi_arlock ), .m_axi_arcache (ddr3_axi_arcache), .m_axi_arprot (ddr3_axi_arprot ), .m_axi_arqos (ddr3_axi_arqos ), .m_axi_arregion (), .m_axi_aruser (), .m_axi_arvalid (ddr3_axi_arvalid), .m_axi_arready (ddr3_axi_arready), // Slave Interface Read Data Ports .m_axi_rid (ddr3_axi_rid ), .m_axi_rdata (ddr3_axi_rdata ), .m_axi_rresp (ddr3_axi_rresp ), .m_axi_rlast (ddr3_axi_rlast ), .m_axi_ruser (), .m_axi_rvalid (ddr3_axi_rvalid), .m_axi_rready (ddr3_axi_rready), .s_eth0_tdata (e2v0_tdata ), .s_eth0_tlast (e2v0_tlast ), .s_eth0_tvalid (e2v0_tvalid), .s_eth0_tready (e2v0_tready), .m_eth0_tdata (v2e0_tdata ), .m_eth0_tlast (v2e0_tlast ), .m_eth0_tvalid (v2e0_tvalid), .m_eth0_tready (v2e0_tready), .s_eth1_tdata (e2v1_tdata ), .s_eth1_tlast (e2v1_tlast ), .s_eth1_tvalid (e2v1_tvalid), .s_eth1_tready (e2v1_tready), .m_eth1_tdata (v2e1_tdata ), .m_eth1_tlast (v2e1_tlast ), .m_eth1_tvalid (v2e1_tvalid), .m_eth1_tready (v2e1_tready), .s_pcie_tdata (p2c_tdata ), .s_pcie_tlast (p2c_tlast ), .s_pcie_tvalid (p2c_tvalid), .s_pcie_tready (p2c_tready), .m_pcie_tdata (c2p_tdata ), .m_pcie_tlast (c2p_tlast ), .m_pcie_tvalid (c2p_tvalid), .m_pcie_tready (c2p_tready) ); //--------------------------------------------------------------------------- // Convert Control Port to Settings Bus //--------------------------------------------------------------------------- localparam NUM_CTRLPORTS_PER_DBOARD = 1; ctrlport_to_settings_bus # ( .NUM_PORTS (NUM_CTRLPORTS_PER_DBOARD), .USE_TIME (1) ) ctrlport0_to_settings_bus_i ( .ctrlport_clk (radio_clk), .ctrlport_rst (radio_rst), .s_ctrlport_req_wr (m_ctrlport_req_wr_radio0), .s_ctrlport_req_rd (m_ctrlport_req_rd_radio0), .s_ctrlport_req_addr (m_ctrlport_req_addr_radio0), .s_ctrlport_req_data (m_ctrlport_req_data_radio0), .s_ctrlport_req_has_time (m_ctrlport_req_has_time_radio0), .s_ctrlport_req_time (m_ctrlport_req_time_radio0), .s_ctrlport_resp_ack (m_ctrlport_resp_ack_radio0), .s_ctrlport_resp_data (m_ctrlport_resp_data_radio0), .set_data (db_fe_set_data[31:0]), .set_addr (db_fe_set_addr[7:0]), .set_stb (db_fe_set_stb[0]), .set_time (), .set_has_time (), .rb_stb (db_fe_rb_stb[0]), .rb_addr (db_fe_rb_addr[7:0]), .rb_data (db_fe_rb_data[63:0]), .timestamp (radio_time_tb) ); ctrlport_to_settings_bus # ( .NUM_PORTS (NUM_CTRLPORTS_PER_DBOARD), .USE_TIME (1) ) ctrlport1_to_settings_bus_i ( .ctrlport_clk (radio_clk), .ctrlport_rst (radio_rst), .s_ctrlport_req_wr (m_ctrlport_req_wr_radio1), .s_ctrlport_req_rd (m_ctrlport_req_rd_radio1), .s_ctrlport_req_addr (m_ctrlport_req_addr_radio1), .s_ctrlport_req_data (m_ctrlport_req_data_radio1), .s_ctrlport_req_has_time (m_ctrlport_req_has_time_radio1), .s_ctrlport_req_time (m_ctrlport_req_time_radio1), .s_ctrlport_resp_ack (m_ctrlport_resp_ack_radio1), .s_ctrlport_resp_data (m_ctrlport_resp_data_radio1), .set_data (db_fe_set_data[63:32]), .set_addr (db_fe_set_addr[15:8]), .set_stb (db_fe_set_stb[1]), .set_time (), .set_has_time (), .rb_stb (db_fe_rb_stb[1]), .rb_addr (db_fe_rb_addr[15:8]), .rb_data (db_fe_rb_data[127:64]), .timestamp (radio_time_tb) ); endmodule // bus_int