diff options
-rw-r--r-- | fpga/usrp3/top/n3xx/dboards/mg/n3xx.v | 6 | ||||
-rw-r--r-- | fpga/usrp3/top/n3xx/dboards/rh/n3xx.v | 6 | ||||
-rw-r--r-- | fpga/usrp3/top/n3xx/n3xx_core.v | 490 |
3 files changed, 307 insertions, 195 deletions
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/n3xx.v b/fpga/usrp3/top/n3xx/dboards/mg/n3xx.v index e09e44741..d9104f412 100644 --- a/fpga/usrp3/top/n3xx/dboards/mg/n3xx.v +++ b/fpga/usrp3/top/n3xx/dboards/mg/n3xx.v @@ -904,8 +904,6 @@ module n3xx ( wire reg_rd_resp_npio, reg_rd_resp_npio0, reg_rd_resp_npio1; wire [REG_DWIDTH-1:0] reg_rd_data_npio, reg_rd_data_npio0, reg_rd_data_npio1; - localparam NPIO_REG_BASE = 14'h0200; - regport_resp_mux #( .WIDTH (REG_DWIDTH), .NUM_SLAVES (2) @@ -1360,7 +1358,7 @@ module n3xx ( n3xx_mgt_io_core #( .PROTOCOL ("Aurora"), - .REG_BASE (NPIO_REG_BASE + 14'h00), + .REG_BASE (14'h00), // Base offset removed by n3xx_core .REG_DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64) .REG_AWIDTH (REG_AWIDTH), // Width of the address bus .PORTNUM (8'd2), @@ -1417,7 +1415,7 @@ module n3xx ( n3xx_mgt_io_core #( .PROTOCOL ("Aurora"), - .REG_BASE (NPIO_REG_BASE + 14'h40), + .REG_BASE (14'h40), // Base offset removed by n3xx_core .REG_DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64) .REG_AWIDTH (REG_AWIDTH), // Width of the address bus .PORTNUM (8'd3), diff --git a/fpga/usrp3/top/n3xx/dboards/rh/n3xx.v b/fpga/usrp3/top/n3xx/dboards/rh/n3xx.v index 558e6734a..9eedd55b9 100644 --- a/fpga/usrp3/top/n3xx/dboards/rh/n3xx.v +++ b/fpga/usrp3/top/n3xx/dboards/rh/n3xx.v @@ -893,8 +893,6 @@ module n3xx ( wire reg_rd_resp_npio, reg_rd_resp_npio0, reg_rd_resp_npio1; wire [REG_DWIDTH-1:0] reg_rd_data_npio, reg_rd_data_npio0, reg_rd_data_npio1; - localparam NPIO_REG_BASE = 14'h0200; - regport_resp_mux #( .WIDTH (REG_DWIDTH), .NUM_SLAVES (2) @@ -1350,7 +1348,7 @@ module n3xx ( n3xx_mgt_io_core #( .PROTOCOL ("Aurora"), - .REG_BASE (NPIO_REG_BASE + 14'h00), + .REG_BASE (14'h00), // Base offset removed by n3xx_core .REG_DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64) .REG_AWIDTH (REG_AWIDTH), // Width of the address bus .PORTNUM (8'd2), @@ -1407,7 +1405,7 @@ module n3xx ( n3xx_mgt_io_core #( .PROTOCOL ("Aurora"), - .REG_BASE (NPIO_REG_BASE + 14'h40), + .REG_BASE (14'h40), // Base offset removed by n3xx_core .REG_DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64) .REG_AWIDTH (REG_AWIDTH), // Width of the address bus .PORTNUM (8'd3), diff --git a/fpga/usrp3/top/n3xx/n3xx_core.v b/fpga/usrp3/top/n3xx/n3xx_core.v index 5128d57f7..712aef998 100644 --- a/fpga/usrp3/top/n3xx/n3xx_core.v +++ b/fpga/usrp3/top/n3xx/n3xx_core.v @@ -197,6 +197,7 @@ module n3xx_core #( input [63:0] sfp_ports_info, output reg [15:0] device_id ); + `include "../../lib/rfnoc/core/ctrlport.vh" ///////////////////////////////////////////////////////////////////////////////// // @@ -218,8 +219,14 @@ module n3xx_core #( ///////////////////////////////////////////////////////////////////////////////// // Register base - localparam REG_BASE_MISC = 14'h0; - localparam REG_BASE_TIMEKEEPER = 14'h1000; + localparam [CTRLPORT_ADDR_W-1:0] REG_BASE_MISC = 20'h0; + localparam [CTRLPORT_ADDR_W-1:0] REG_BASE_NPIO = 20'h200; + localparam [CTRLPORT_ADDR_W-1:0] REG_BASE_TIMEKEEPER = 20'h1000; + + // Register region sizes. Give each register region a 256-byte window. + localparam REG_GLOB_ADDR_W = 8; + localparam REG_NPIO_ADDR_W = 8; + localparam REG_TIMEKEEPER_ADDR_W = 8; // Misc Motherboard Registers localparam REG_COMPAT_NUM = REG_BASE_MISC + 14'h00; @@ -238,7 +245,7 @@ module n3xx_core #( localparam REG_FP_GPIO_RADIO_SRC = REG_BASE_MISC + 14'h34; localparam REG_NUM_TIMEKEEPERS = REG_BASE_MISC + 14'h48; - localparam NUM_TIMEKEEPERS = 16'd1; + localparam NUM_TIMEKEEPERS = 1; wire m_ctrlport_req_wr_radio0; wire m_ctrlport_req_rd_radio0; @@ -275,140 +282,243 @@ module n3xx_core #( bus_counter <= bus_counter + 32'd1; end - // Regport - wire reg_wr_req; - wire [REG_AWIDTH-1:0] reg_wr_addr; - wire [REG_DWIDTH-1:0] reg_wr_data; - wire reg_rd_req; - wire [REG_AWIDTH-1:0] reg_rd_addr; - wire reg_rd_resp; - wire [REG_DWIDTH-1:0] reg_rd_data; - - reg reg_rd_resp_glob; - reg [REG_DWIDTH-1:0] reg_rd_data_glob; - wire reg_rd_resp_tk; - wire [REG_DWIDTH-1:0] reg_rd_data_tk; - - regport_resp_mux #( - .WIDTH(REG_DWIDTH), - .NUM_SLAVES(3) - ) inst_mboard_regport_resp_mux ( - .clk(bus_clk), - .reset(bus_rst), - .sla_rd_resp({reg_rd_resp_npio, reg_rd_resp_glob, reg_rd_resp_tk}), - .sla_rd_data({reg_rd_data_npio, reg_rd_data_glob, reg_rd_data_tk}), - .mst_rd_resp(reg_rd_resp), - .mst_rd_data(reg_rd_data) + + ///////////////////////////////////////////////////////////////////////////// + // + // Bus Bridge + // + ///////////////////////////////////////////////////////////////////////////// + + // Specify timeout for CtrlPort transactions that don't complete. + localparam CTRLPORT_TIMEOUT = 20; + + wire cp_req_wr_aclk; + wire cp_req_rd_aclk; + wire [CTRLPORT_ADDR_W-1:0] cp_req_addr_aclk; + wire [CTRLPORT_DATA_W-1:0] cp_req_data_aclk; + wire cp_resp_ack_aclk; + wire [ CTRLPORT_STS_W-1:0] cp_resp_status_aclk; + wire [CTRLPORT_DATA_W-1:0] cp_resp_data_aclk; + + // Convert the AXI4-Lite transactions to CtrlPort + axil_ctrlport_master #( + .TIMEOUT (CTRLPORT_TIMEOUT), + .AXI_AWIDTH (REG_AWIDTH), + .CTRLPORT_AWIDTH (CTRLPORT_ADDR_W) + ) axil_ctrlport_master_i ( + .s_axi_aclk (s_axi_aclk), + .s_axi_aresetn (s_axi_aresetn), + .s_axi_awaddr (s_axi_awaddr), + .s_axi_awvalid (s_axi_awvalid), + .s_axi_awready (s_axi_awready), + .s_axi_wdata (s_axi_wdata), + .s_axi_wstrb (s_axi_wstrb), + .s_axi_wvalid (s_axi_wvalid), + .s_axi_wready (s_axi_wready), + .s_axi_bresp (s_axi_bresp), + .s_axi_bvalid (s_axi_bvalid), + .s_axi_bready (s_axi_bready), + .s_axi_araddr (s_axi_araddr), + .s_axi_arvalid (s_axi_arvalid), + .s_axi_arready (s_axi_arready), + .s_axi_rdata (s_axi_rdata), + .s_axi_rresp (s_axi_rresp), + .s_axi_rvalid (s_axi_rvalid), + .s_axi_rready (s_axi_rready), + .m_ctrlport_req_wr (cp_req_wr_aclk), + .m_ctrlport_req_rd (cp_req_rd_aclk), + .m_ctrlport_req_addr (cp_req_addr_aclk), + .m_ctrlport_req_portid (), + .m_ctrlport_req_rem_epid (), + .m_ctrlport_req_rem_portid (), + .m_ctrlport_req_data (cp_req_data_aclk), + .m_ctrlport_req_byte_en (), + .m_ctrlport_req_has_time (), + .m_ctrlport_req_time (), + .m_ctrlport_resp_ack (cp_resp_ack_aclk), + .m_ctrlport_resp_status (cp_resp_status_aclk), + .m_ctrlport_resp_data (cp_resp_data_aclk) ); - // Regport Master to convert AXI4-Lite to regport - axil_regport_master #( - .DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64) - .AWIDTH (REG_AWIDTH), // Width of the address bus - .WRBASE (0), // Write address base - .RDBASE (0), // Read address base - .TIMEOUT (10) // log2(timeout). Read will timeout after (2^TIMEOUT - 1) cycles - ) mboard_regport_master_i ( - // Clock and reset - .s_axi_aclk (s_axi_aclk), - .s_axi_aresetn (s_axi_aresetn), - // AXI4-Lite: Write address port (domain: s_axi_aclk) - .s_axi_awaddr (s_axi_awaddr), - .s_axi_awvalid (s_axi_awvalid), - .s_axi_awready (s_axi_awready), - // AXI4-Lite: Write data port (domain: s_axi_aclk) - .s_axi_wdata (s_axi_wdata), - .s_axi_wstrb (s_axi_wstrb), - .s_axi_wvalid (s_axi_wvalid), - .s_axi_wready (s_axi_wready), - // AXI4-Lite: Write response port (domain: s_axi_aclk) - .s_axi_bresp (s_axi_bresp), - .s_axi_bvalid (s_axi_bvalid), - .s_axi_bready (s_axi_bready), - // AXI4-Lite: Read address port (domain: s_axi_aclk) - .s_axi_araddr (s_axi_araddr), - .s_axi_arvalid (s_axi_arvalid), - .s_axi_arready (s_axi_arready), - // AXI4-Lite: Read data port (domain: s_axi_aclk) - .s_axi_rdata (s_axi_rdata), - .s_axi_rresp (s_axi_rresp), - .s_axi_rvalid (s_axi_rvalid), - .s_axi_rready (s_axi_rready), - // Register port: Write port (domain: reg_clk) - .reg_clk (bus_clk), - .reg_wr_req (reg_wr_req), - .reg_wr_addr (reg_wr_addr), - .reg_wr_data (reg_wr_data), - .reg_wr_keep (/*unused*/), - // Register port: Read port (domain: reg_clk) - .reg_rd_req (reg_rd_req), - .reg_rd_addr (reg_rd_addr), - .reg_rd_resp (reg_rd_resp), - .reg_rd_data (reg_rd_data) + wire cp_req_wr; + wire cp_req_rd; + wire [CTRLPORT_ADDR_W-1:0] cp_req_addr; + wire [CTRLPORT_DATA_W-1:0] cp_req_data; + wire cp_resp_ack; + wire [ CTRLPORT_STS_W-1:0] cp_resp_status; + wire [CTRLPORT_DATA_W-1:0] cp_resp_data; + + // Cross transactions from s_axi_clk to bus_clk domain + ctrlport_clk_cross ctrlport_clk_cross_i ( + .rst (~s_axi_aresetn), + .s_ctrlport_clk (s_axi_aclk), + .s_ctrlport_req_wr (cp_req_wr_aclk), + .s_ctrlport_req_rd (cp_req_rd_aclk), + .s_ctrlport_req_addr (cp_req_addr_aclk), + .s_ctrlport_req_portid ({CTRLPORT_PORTID_W{1'b0}}), + .s_ctrlport_req_rem_epid ({CTRLPORT_REM_EPID_W{1'b0}}), + .s_ctrlport_req_rem_portid ({CTRLPORT_PORTID_W{1'b0}}), + .s_ctrlport_req_data (cp_req_data_aclk), + .s_ctrlport_req_byte_en ({CTRLPORT_BYTE_EN_W{1'b1}}), + .s_ctrlport_req_has_time (1'b0), + .s_ctrlport_req_time ({CTRLPORT_TIME_W{1'b0}}), + .s_ctrlport_resp_ack (cp_resp_ack_aclk), + .s_ctrlport_resp_status (cp_resp_status_aclk), + .s_ctrlport_resp_data (cp_resp_data_aclk), + .m_ctrlport_clk (bus_clk), + .m_ctrlport_req_wr (cp_req_wr), + .m_ctrlport_req_rd (cp_req_rd), + .m_ctrlport_req_addr (cp_req_addr), + .m_ctrlport_req_portid (), + .m_ctrlport_req_rem_epid (), + .m_ctrlport_req_rem_portid (), + .m_ctrlport_req_data (cp_req_data), + .m_ctrlport_req_byte_en (), + .m_ctrlport_req_has_time (), + .m_ctrlport_req_time (), + .m_ctrlport_resp_ack (cp_resp_ack), + .m_ctrlport_resp_status (cp_resp_status), + .m_ctrlport_resp_data (cp_resp_data) ); - assign reg_wr_req_npio = reg_wr_req; - assign reg_wr_addr_npio = reg_wr_addr; - assign reg_wr_data_npio = reg_wr_data; - assign reg_rd_req_npio = reg_rd_req; - assign reg_rd_addr_npio = reg_rd_addr; + wire cp_glob_req_wr; + wire cp_glob_req_rd; + wire [CTRLPORT_ADDR_W-1:0] cp_glob_req_addr; + wire [CTRLPORT_DATA_W-1:0] cp_glob_req_data; + reg cp_glob_resp_ack = 1'b0; + reg [CTRLPORT_DATA_W-1:0] cp_glob_resp_data = 1'bX; + + wire cp_npio_req_wr; + wire cp_npio_req_rd; + wire [CTRLPORT_ADDR_W-1:0] cp_npio_req_addr; + wire [CTRLPORT_DATA_W-1:0] cp_npio_req_data; + wire cp_npio_resp_ack; + wire [CTRLPORT_DATA_W-1:0] cp_npio_resp_data; + + wire cp_tk_req_wr; + wire cp_tk_req_rd; + wire [CTRLPORT_ADDR_W-1:0] cp_tk_req_addr; + wire [CTRLPORT_DATA_W-1:0] cp_tk_req_data; + wire cp_tk_resp_ack; + wire [CTRLPORT_DATA_W-1:0] cp_tk_resp_data; + + // Split the CtrlPort for the global registers and the timekeeper registers + ctrlport_decoder_param #( + .NUM_SLAVES (3), + .PORT_BASE ({ REG_BASE_TIMEKEEPER, REG_BASE_NPIO, REG_BASE_MISC }), + .PORT_ADDR_W ({ REG_TIMEKEEPER_ADDR_W, REG_NPIO_ADDR_W, REG_GLOB_ADDR_W }) + ) ctrlport_decoder_param_i ( + .ctrlport_clk (bus_clk), + .ctrlport_rst (bus_rst), + .s_ctrlport_req_wr (cp_req_wr), + .s_ctrlport_req_rd (cp_req_rd), + .s_ctrlport_req_addr (cp_req_addr), + .s_ctrlport_req_data (cp_req_data), + .s_ctrlport_req_byte_en ({CTRLPORT_BYTE_EN_W{1'b1}}), + .s_ctrlport_req_has_time (1'b0), + .s_ctrlport_req_time ({CTRLPORT_TIME_W{1'b0}}), + .s_ctrlport_resp_ack (cp_resp_ack), + .s_ctrlport_resp_status (cp_resp_status), + .s_ctrlport_resp_data (cp_resp_data), + .m_ctrlport_req_wr ({ cp_tk_req_wr, cp_npio_req_wr, cp_glob_req_wr }), + .m_ctrlport_req_rd ({ cp_tk_req_rd, cp_npio_req_rd, cp_glob_req_rd }), + .m_ctrlport_req_addr ({ cp_tk_req_addr, cp_npio_req_addr, cp_glob_req_addr }), + .m_ctrlport_req_data ({ cp_tk_req_data, cp_npio_req_data, cp_glob_req_data }), + .m_ctrlport_req_byte_en (), + .m_ctrlport_req_has_time (), + .m_ctrlport_req_time (), + .m_ctrlport_resp_ack ({ cp_tk_resp_ack, cp_npio_resp_ack, cp_glob_resp_ack }), + .m_ctrlport_resp_status ({2{CTRL_STS_OKAY}}), + .m_ctrlport_resp_data ({ cp_tk_resp_data, cp_npio_resp_data, cp_glob_resp_data }) + ); + + // Convert NPIO from CtrlPort to RegPort + ctrlport_to_regport #( + .REG_AWIDTH (REG_AWIDTH), + .REG_DWIDTH (REG_DWIDTH) + ) ctrlport_to_regport_i ( + .clk (bus_clk), + .rst (bus_rst), + .s_ctrlport_req_wr (cp_npio_req_wr), + .s_ctrlport_req_rd (cp_npio_req_rd), + .s_ctrlport_req_addr (cp_npio_req_addr), + .s_ctrlport_req_data (cp_npio_req_data), + .s_ctrlport_resp_ack (cp_npio_resp_ack), + .s_ctrlport_resp_data (cp_npio_resp_data), + .reg_wr_req (reg_wr_req_npio), + .reg_wr_addr (reg_wr_addr_npio), + .reg_wr_data (reg_wr_data_npio), + .reg_rd_req (reg_rd_req_npio), + .reg_rd_addr (reg_rd_addr_npio), + .reg_rd_resp (reg_rd_resp_npio), + .reg_rd_data (reg_rd_data_npio) + ); + + + ///////////////////////////////////////////////////////////////////////////// + // + // Global Registers + // + ///////////////////////////////////////////////////////////////////////////// reg b_ref_clk_locked_ms; reg b_ref_clk_locked; reg b_meas_clk_locked_ms; reg b_meas_clk_locked; - // Write Registers always @ (posedge bus_clk) begin if (bus_rst) begin - scratch_reg <= 32'h0; - fp_gpio_master_reg <= 32'h0; - fp_gpio_src_reg <= 32'h0; - pps_select <= 4'h1; - pps_select_sfp <= 2'h0; - pps_out_enb <= 1'b0; - ref_clk_reset <= 1'b0; - meas_clk_reset <= 1'b0; + cp_glob_resp_ack <= 1'b0; + cp_glob_resp_data <= 'bX; + scratch_reg <= 32'h0; + fp_gpio_master_reg <= 32'h0; + fp_gpio_src_reg <= 32'h0; + pps_select <= 4'h1; + pps_select_sfp <= 2'h0; + pps_out_enb <= 1'b0; + ref_clk_reset <= 1'b0; + meas_clk_reset <= 1'b0; enable_ref_clk_async <= 1'b1; - device_id <= 16'h0; - end else if (reg_wr_req) begin - case (reg_wr_addr) - REG_DEVICE_ID: begin - device_id <= reg_wr_data[15:0]; - end - REG_FP_GPIO_MASTER: begin - fp_gpio_master_reg <= reg_wr_data; - end - REG_FP_GPIO_RADIO_SRC: begin - fp_gpio_src_reg <= reg_wr_data; - end - REG_SCRATCH: begin - scratch_reg <= reg_wr_data; - end - REG_CLOCK_CTRL: begin - pps_select <= reg_wr_data[3:0]; - pps_out_enb <= reg_wr_data[4]; - pps_select_sfp <= reg_wr_data[6:5]; - ref_clk_reset <= reg_wr_data[8]; - meas_clk_reset <= reg_wr_data[12]; - // This bit is defined as "to disable, write '1' to bit 16" for backwards - // compatibility. - enable_ref_clk_async <= ~reg_wr_data[16]; - end - endcase - end - end - - // Read Registers - always @ (posedge bus_clk) begin - if (bus_rst) begin - reg_rd_resp_glob <= 1'b0; + device_id <= 16'h0; b_ref_clk_locked_ms <= 1'b0; b_ref_clk_locked <= 1'b0; b_meas_clk_locked_ms <= 1'b0; b_meas_clk_locked <= 1'b0; - end - else begin + end else begin + cp_glob_resp_ack <= 1'b0; + + if (cp_glob_req_wr) begin + cp_glob_resp_ack <= 1'b1; + + case (cp_glob_req_addr[REG_GLOB_ADDR_W-1:0]) + REG_DEVICE_ID: + device_id <= cp_glob_req_data[15:0]; + + REG_FP_GPIO_MASTER: + fp_gpio_master_reg <= cp_glob_req_data; + + REG_FP_GPIO_RADIO_SRC: + fp_gpio_src_reg <= cp_glob_req_data; + + REG_SCRATCH: + scratch_reg <= cp_glob_req_data; + + REG_CLOCK_CTRL: begin + pps_select <= cp_glob_req_data[3:0]; + pps_out_enb <= cp_glob_req_data[4]; + pps_select_sfp <= cp_glob_req_data[6:5]; + ref_clk_reset <= cp_glob_req_data[8]; + meas_clk_reset <= cp_glob_req_data[12]; + // This bit is defined as "to disable, write '1' to bit 16" for backwards + // compatibility. + enable_ref_clk_async <= ~cp_glob_req_data[16]; + end + default: begin + // Don't acknowledge if the address doesn't match + cp_glob_resp_ack <= 1'b0; + end + endcase + end // double-sync the locked bits into the bus_clk domain before using them b_ref_clk_locked_ms <= ref_clk_locked; @@ -416,74 +526,74 @@ module n3xx_core #( b_meas_clk_locked_ms <= meas_clk_locked; b_meas_clk_locked <= b_meas_clk_locked_ms; - if (reg_rd_req) begin - reg_rd_resp_glob <= 1'b1; + if (cp_glob_req_rd) begin + cp_glob_resp_data <= 0; // Unused bits will read 0 + cp_glob_resp_ack <= 1'b1; - case (reg_rd_addr) - REG_DEVICE_ID: - reg_rd_data_glob <= device_id; + case (cp_glob_req_addr[REG_GLOB_ADDR_W-1:0]) + REG_DEVICE_ID: + cp_glob_resp_data <= {16'd0, device_id}; - REG_RFNOC_INFO: - reg_rd_data_glob <= {CHDR_WIDTH[15:0], RFNOC_PROTOVER[15:0]}; + REG_RFNOC_INFO: + cp_glob_resp_data <= {CHDR_WIDTH[15:0], RFNOC_PROTOVER[15:0]}; - REG_COMPAT_NUM: - reg_rd_data_glob <= {COMPAT_MAJOR, COMPAT_MINOR}; + REG_COMPAT_NUM: + cp_glob_resp_data <= {COMPAT_MAJOR, COMPAT_MINOR}; - REG_DATESTAMP: - reg_rd_data_glob <= build_datestamp; + REG_DATESTAMP: + cp_glob_resp_data <= build_datestamp; - REG_GIT_HASH: - `ifndef GIT_HASH - `define GIT_HASH 32'h0BADC0DE - `endif - reg_rd_data_glob <= `GIT_HASH; + REG_GIT_HASH: + `ifndef GIT_HASH + `define GIT_HASH 32'h0BADC0DE + `endif + cp_glob_resp_data <= `GIT_HASH; - REG_FP_GPIO_MASTER: - reg_rd_data_glob <= fp_gpio_master_reg; + REG_FP_GPIO_MASTER: + cp_glob_resp_data <= fp_gpio_master_reg; - REG_FP_GPIO_RADIO_SRC: - reg_rd_data_glob <= fp_gpio_src_reg; + REG_FP_GPIO_RADIO_SRC: + cp_glob_resp_data <= fp_gpio_src_reg; - REG_SCRATCH: - reg_rd_data_glob <= scratch_reg; + REG_SCRATCH: + cp_glob_resp_data <= scratch_reg; - REG_CLOCK_CTRL: begin - reg_rd_data_glob <= 32'b0; - reg_rd_data_glob[3:0] <= pps_select; - reg_rd_data_glob[4] <= pps_out_enb; - reg_rd_data_glob[6:5] <= pps_select_sfp; - reg_rd_data_glob[8] <= ref_clk_reset; - reg_rd_data_glob[9] <= b_ref_clk_locked; - reg_rd_data_glob[12] <= meas_clk_reset; - reg_rd_data_glob[13] <= b_meas_clk_locked; - reg_rd_data_glob[16] <= ~enable_ref_clk_async; - end + REG_CLOCK_CTRL: begin + cp_glob_resp_data <= 32'b0; + cp_glob_resp_data[3:0] <= pps_select; + cp_glob_resp_data[4] <= pps_out_enb; + cp_glob_resp_data[6:5] <= pps_select_sfp; + cp_glob_resp_data[8] <= ref_clk_reset; + cp_glob_resp_data[9] <= b_ref_clk_locked; + cp_glob_resp_data[12] <= meas_clk_reset; + cp_glob_resp_data[13] <= b_meas_clk_locked; + cp_glob_resp_data[16] <= ~enable_ref_clk_async; + end - REG_XADC_READBACK: - reg_rd_data_glob <= xadc_readback; + REG_XADC_READBACK: + cp_glob_resp_data <= xadc_readback; - REG_BUS_CLK_RATE: - reg_rd_data_glob <= BUS_CLK_RATE; + REG_BUS_CLK_RATE: + cp_glob_resp_data <= BUS_CLK_RATE; - REG_BUS_CLK_COUNT: - reg_rd_data_glob <= bus_counter; + REG_BUS_CLK_COUNT: + cp_glob_resp_data <= bus_counter; - REG_SFP_PORT0_INFO: - reg_rd_data_glob <= sfp_ports_info[31:0]; + REG_SFP_PORT0_INFO: + cp_glob_resp_data <= sfp_ports_info[31:0]; - REG_SFP_PORT1_INFO: - reg_rd_data_glob <= sfp_ports_info[63:32]; + REG_SFP_PORT1_INFO: + cp_glob_resp_data <= sfp_ports_info[63:32]; - REG_NUM_TIMEKEEPERS: - reg_rd_data_glob <= NUM_TIMEKEEPERS; + REG_NUM_TIMEKEEPERS: + cp_glob_resp_data <= NUM_TIMEKEEPERS; - default: - reg_rd_resp_glob <= 1'b0; + default: begin + // Don't acknowledge if the address doesn't match + cp_glob_resp_ack <= 1'b0; + end endcase end - else if (reg_rd_resp_glob) begin - reg_rd_resp_glob <= 1'b0; - end end end @@ -964,27 +1074,33 @@ module n3xx_core #( end endgenerate + + ///////////////////////////////////////////////////////////////////////////// + // // Timekeeper + // + ///////////////////////////////////////////////////////////////////////////// + wire [63:0] radio_time; timekeeper #( - .BASE_ADDR (REG_BASE_TIMEKEEPER), - .TIME_INCREMENT (1'b1) + .BASE_ADDR (0), // ctrlport_decoder removes the base offset + .TIME_INCREMENT (1'b1) ) timekeeper_i ( - .tb_clk (radio_clk), - .tb_rst (radio_rst), - .s_ctrlport_clk (bus_clk), - .s_ctrlport_req_wr (reg_wr_req), - .s_ctrlport_req_rd (reg_rd_req), - .s_ctrlport_req_addr (reg_wr_req ? reg_wr_addr: reg_rd_addr), - .s_ctrlport_req_data (reg_wr_data), - .s_ctrlport_resp_ack (reg_rd_resp_tk), - .s_ctrlport_resp_data (reg_rd_data_tk), - .sample_rx_stb (rx_stb[0]), - .pps (pps), - .tb_timestamp (radio_time), - .tb_timestamp_last_pps (), - .tb_period_ns_q32 () + .tb_clk (radio_clk), + .tb_rst (radio_rst), + .s_ctrlport_clk (bus_clk), + .s_ctrlport_req_wr (cp_tk_req_wr), + .s_ctrlport_req_rd (cp_tk_req_rd), + .s_ctrlport_req_addr (cp_tk_req_addr), + .s_ctrlport_req_data (cp_tk_req_data), + .s_ctrlport_resp_ack (cp_tk_resp_ack), + .s_ctrlport_resp_data (cp_tk_resp_data), + .sample_rx_stb (rx_stb[0]), + .pps (pps), + .tb_timestamp (radio_time), + .tb_timestamp_last_pps (), + .tb_period_ns_q32 () ); @@ -1138,7 +1254,7 @@ module n3xx_core #( //--------------------------------------------------------------------------- // Convert Control Port to Settings Bus //--------------------------------------------------------------------------- -`ifdef N320 +`ifdef N320 ctrlport_to_settings_bus # ( .NUM_PORTS (NUM_CHANNELS_PER_RADIO), .USE_TIME (1) |