// // Copyright 2021 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // // Module: atr_controller // // Description: // Controller of the ATR state configuration for the other register endpoints. // `default_nettype none module atr_controller #( parameter [19:0] BASE_ADDRESS = 0, parameter [19:0] SIZE_ADDRESS = 0 ) ( // Clock and reset input wire ctrlport_clk, input wire ctrlport_rst, // Request input wire s_ctrlport_req_wr, input wire s_ctrlport_req_rd, input wire [19:0] s_ctrlport_req_addr, input wire [31:0] s_ctrlport_req_data, // Response output reg s_ctrlport_resp_ack, output reg [ 1:0] s_ctrlport_resp_status, output reg [31:0] s_ctrlport_resp_data, // ATR state of FPGA // Assumes the following assignment on the FPGA: // {tx_running[1], rx_running[1], tx_running[0], rx_running[0]} // where the array index indicates the RF chain. input wire [ 3:0] atr_fpga_state, // derived configuration output reg [ 7:0] atr_config_dsa_rf0 = 8'b0, output reg [ 7:0] atr_config_dsa_rf1 = 8'b0, output reg [ 7:0] atr_config_rf0 = 8'b0, output reg [ 7:0] atr_config_rf1 = 8'b0 ); `include "../regmap/atr_regmap_utils.vh" `include "../../../../../../lib/rfnoc/core/ctrlport.vh" //---------------------------------------------------------- // Internal registers //---------------------------------------------------------- reg [ RF0_OPTION_SIZE-1:0] option_rf0 = SW_DEFINED; reg [ RF1_OPTION_SIZE-1:0] option_rf1 = SW_DEFINED; reg [RF0_DSA_OPTION_SIZE-1:0] option_dsa_rf0 = SW_DEFINED; reg [RF1_DSA_OPTION_SIZE-1:0] option_dsa_rf1 = SW_DEFINED; reg [ SW_RF0_CONFIG_SIZE-1:0] sw_atr_config_rf0 = {SW_RF0_CONFIG_SIZE {1'b0}}; reg [ SW_RF1_CONFIG_SIZE-1:0] sw_atr_config_rf1 = {SW_RF1_CONFIG_SIZE {1'b0}}; reg [SW_RF0_DSA_CONFIG_SIZE-1:0] sw_atr_config_dsa_rf0 = {SW_RF0_DSA_CONFIG_SIZE {1'b0}}; reg [SW_RF1_DSA_CONFIG_SIZE-1:0] sw_atr_config_dsa_rf1 = {SW_RF1_DSA_CONFIG_SIZE {1'b0}}; //---------------------------------------------------------- // Handling of CtrlPort //---------------------------------------------------------- wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) && (s_ctrlport_req_addr < BASE_ADDRESS + SIZE_ADDRESS); always @(posedge ctrlport_clk) begin // reset internal registers and responses if (ctrlport_rst) begin option_rf0 <= SW_DEFINED; option_rf1 <= SW_DEFINED; option_dsa_rf0 <= SW_DEFINED; option_dsa_rf1 <= SW_DEFINED; sw_atr_config_rf0 <= {SW_RF0_CONFIG_SIZE {1'b0}}; sw_atr_config_rf1 <= {SW_RF1_CONFIG_SIZE {1'b0}}; sw_atr_config_dsa_rf0 <= {SW_RF0_DSA_CONFIG_SIZE {1'b0}}; sw_atr_config_dsa_rf1 <= {SW_RF1_DSA_CONFIG_SIZE {1'b0}}; s_ctrlport_resp_ack <= 1'b0; s_ctrlport_resp_data <= {32{1'bx}}; s_ctrlport_resp_status <= CTRL_STS_OKAY; end else begin // write requests if (s_ctrlport_req_wr) begin // always issue an ack and no data s_ctrlport_resp_ack <= 1'b1; s_ctrlport_resp_data <= {32{1'bx}}; s_ctrlport_resp_status <= CTRL_STS_OKAY; case (s_ctrlport_req_addr) BASE_ADDRESS + OPTION_REG: begin option_rf0 <= s_ctrlport_req_data[RF0_OPTION_MSB : RF0_OPTION]; option_rf1 <= s_ctrlport_req_data[RF1_OPTION_MSB : RF1_OPTION]; option_dsa_rf0 <= s_ctrlport_req_data[RF0_DSA_OPTION_MSB : RF0_DSA_OPTION]; option_dsa_rf1 <= s_ctrlport_req_data[RF1_DSA_OPTION_MSB : RF1_DSA_OPTION]; end BASE_ADDRESS + SW_CONFIG_REG: begin sw_atr_config_rf0 <= s_ctrlport_req_data[SW_RF0_CONFIG_MSB : SW_RF0_CONFIG]; sw_atr_config_rf1 <= s_ctrlport_req_data[SW_RF1_CONFIG_MSB : SW_RF1_CONFIG]; sw_atr_config_dsa_rf0 <= s_ctrlport_req_data[SW_RF0_DSA_CONFIG_MSB : SW_RF0_DSA_CONFIG]; sw_atr_config_dsa_rf1 <= s_ctrlport_req_data[SW_RF1_DSA_CONFIG_MSB : SW_RF1_DSA_CONFIG]; end // error on undefined address default: begin if (address_in_range) begin s_ctrlport_resp_status <= CTRL_STS_CMDERR; // no response if out of range end else begin s_ctrlport_resp_ack <= 1'b0; end end endcase // read requests end else if (s_ctrlport_req_rd) begin // default assumption: valid request s_ctrlport_resp_ack <= 1'b1; s_ctrlport_resp_status <= CTRL_STS_OKAY; s_ctrlport_resp_data <= {32{1'b0}}; case (s_ctrlport_req_addr) BASE_ADDRESS + CURRENT_CONFIG_REG: begin s_ctrlport_resp_data[CURRENT_RF0_CONFIG_MSB : CURRENT_RF0_CONFIG] <= atr_config_rf0; s_ctrlport_resp_data[CURRENT_RF1_CONFIG_MSB : CURRENT_RF1_CONFIG] <= atr_config_rf1; s_ctrlport_resp_data[CURRENT_RF0_DSA_CONFIG_MSB : CURRENT_RF0_DSA_CONFIG] <= atr_config_dsa_rf0; s_ctrlport_resp_data[CURRENT_RF1_DSA_CONFIG_MSB : CURRENT_RF1_DSA_CONFIG] <= atr_config_dsa_rf1; end BASE_ADDRESS + OPTION_REG: begin s_ctrlport_resp_data[RF0_OPTION_MSB : RF0_OPTION] <= option_rf0; s_ctrlport_resp_data[RF1_OPTION_MSB : RF1_OPTION] <= option_rf1; s_ctrlport_resp_data[RF0_DSA_OPTION_MSB : RF0_DSA_OPTION] <= option_dsa_rf0; s_ctrlport_resp_data[RF1_DSA_OPTION_MSB : RF1_DSA_OPTION] <= option_dsa_rf1; end BASE_ADDRESS + SW_CONFIG_REG: begin s_ctrlport_resp_data[SW_RF0_CONFIG_MSB : SW_RF0_CONFIG] <= sw_atr_config_rf0; s_ctrlport_resp_data[SW_RF1_CONFIG_MSB : SW_RF1_CONFIG] <= sw_atr_config_rf1; s_ctrlport_resp_data[SW_RF0_DSA_CONFIG_MSB : SW_RF0_DSA_CONFIG] <= sw_atr_config_dsa_rf0; s_ctrlport_resp_data[SW_RF1_DSA_CONFIG_MSB : SW_RF1_DSA_CONFIG] <= sw_atr_config_dsa_rf1; end // error on undefined address default: begin s_ctrlport_resp_data <= {32{1'b0}}; if (address_in_range) begin s_ctrlport_resp_status <= CTRL_STS_CMDERR; // no response if out of range end else begin s_ctrlport_resp_ack <= 1'b0; end end endcase // no request end else begin s_ctrlport_resp_ack <= 1'b0; end end end //---------------------------------------------------------- // derive configuration //---------------------------------------------------------- always @(posedge ctrlport_clk) begin case (option_rf0) SW_DEFINED: begin atr_config_rf0 <= sw_atr_config_rf0; end CLASSIC_ATR: begin atr_config_rf0 <= {6'b0, atr_fpga_state[1:0]}; end FPGA_STATE: begin atr_config_rf0 <= {4'b0, atr_fpga_state}; end endcase case (option_rf1) SW_DEFINED: begin atr_config_rf1 <= sw_atr_config_rf1; end CLASSIC_ATR: begin atr_config_rf1 <= {6'b0, atr_fpga_state[3:2]}; end FPGA_STATE: begin atr_config_rf1 <= {4'b0, atr_fpga_state}; end endcase case (option_dsa_rf0) SW_DEFINED: begin atr_config_dsa_rf0 <= sw_atr_config_dsa_rf0; end CLASSIC_ATR: begin atr_config_dsa_rf0 <= {6'b0, atr_fpga_state[1:0]}; end FPGA_STATE: begin atr_config_dsa_rf0 <= {4'b0, atr_fpga_state}; end endcase case (option_dsa_rf1) SW_DEFINED: begin atr_config_dsa_rf1 <= sw_atr_config_dsa_rf1; end CLASSIC_ATR: begin atr_config_dsa_rf1 <= {6'b0, atr_fpga_state[3:2]}; end FPGA_STATE: begin atr_config_dsa_rf1 <= {4'b0, atr_fpga_state}; end endcase end endmodule `default_nettype wire //XmlParse xml_on // // // // This regmap contains settings for the active configuration of RF 0 and 1. // There are two sets of configurations. One set comprises RF switches and // LEDs, the other set comprises the attenuators (DSA). // // // // // Contains the options available for RF 0 and RF 1. The chosen setting // affects how the active configuration of up to 8 bits is derived. // // // // Uses the respective value of @.SW_CONFIG_REG as configuration. // // // // // This option assumes the FPGA state to be assigned with: Bit 0 = RF 0 // RX running, Bit 1 = RF 0 TX running, Bit 2 = RF 1 RX running, Bit 3 // = RF 1 TX running. The configuration for each RF chain is built // up of the 2 bits for the RF chain (4 possible states: IDLE, RX only, // TX only, TX/RX). // 0 // // // // The 4 bit wide ATR FPGA state is used as configuration. This enables 16 states. // // // // // // // Contains the current active configuration. // // // // Current active configuration for switches and LEDs of RF 0. // // // // // Current active configuration for switches and LEDs of RF 1. // // // // // Current active configuration for DSAs of RF 0. // // // // // Current active configuration for DSAs of RF 1. // // // // // // // Set the option to be used for the RF chains. // // // // Option used for switches and LEDs of RF 0. // // // // // Option used for switches and LEDs of RF 1. // // // // // Option used for DSAs of RF 0. // // // // // Option used for DSAs of RF 1. // // // // // // // Contains the configuration to be applied in case SW_DEFINED option is // chosen. // // // // SW defined configuration for switches and LEDs of RF 0. // // // // // SW defined configuration for switches and LEDs of RF 1. // // // // // SW defined configuration for DSAs of RF 0. // // // // // SW defined configuration for DSAs of RF 1. // // // // // //XmlParse xml_off