Files
b210-k7-fpga/top/x400/dboards/zbx/cpld/register_endpoints/atr_controller.v
T
a1d7c252c2 fpga: x400: zbx: Add support for ZBX CPLD
Co-authored-by: Cherwa Vang <cherwa.vang@ni.com>
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Max Köhler <max.koehler@ni.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>


Original-commit: 99b841c75aa91709090cbf4046bf51b7ffb4f612
2021-06-10 11:56:58 -05:00

342 lines
12 KiB
Verilog

//
// 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
//<regmap name="ATR_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <group name="ATR_REGISTERS">
// <info>
// 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).
// </info>
//
// <enumeratedtype name="ATR_OPTIONS">
// <info>
// 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.
// </info>
// <value name="SW_DEFINED" integer="0">
// <info>
// Uses the respective value of @.SW_CONFIG_REG as configuration.
// </info>
// </value>
// <value name="CLASSIC_ATR" integer="1">
// <info>
// 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).
// </info>0
// </value>
// <value name="FPGA_STATE" integer="2">
// <info>
// The 4 bit wide ATR FPGA state is used as configuration. This enables 16 states.
// </info>
// </value>
// </enumeratedtype>
//
// <register name="CURRENT_CONFIG_REG" size="32" offset="0x00" attributes="Readable">
// <info>
// Contains the current active configuration.
// </info>
// <bitfield name="CURRENT_RF0_CONFIG" range="7..0" type="integer">
// <info>
// Current active configuration for switches and LEDs of RF 0.
// </info>
// </bitfield>
// <bitfield name="CURRENT_RF1_CONFIG" range="15..8" type="integer">
// <info>
// Current active configuration for switches and LEDs of RF 1.
// </info>
// </bitfield>
// <bitfield name="CURRENT_RF0_DSA_CONFIG" range="23..16" type="integer">
// <info>
// Current active configuration for DSAs of RF 0.
// </info>
// </bitfield>
// <bitfield name="CURRENT_RF1_DSA_CONFIG" range="31..24" type="integer">
// <info>
// Current active configuration for DSAs of RF 1.
// </info>
// </bitfield>
// </register>
//
// <register name="OPTION_REG" size="32" offset="0x04" attributes="Readable|Writable">
// <info>
// Set the option to be used for the RF chains.
// </info>
// <bitfield name="RF0_OPTION" range="1..0" type="ATR_OPTIONS" initialvalue="SW_DEFINED">
// <info>
// Option used for switches and LEDs of RF 0.
// </info>
// </bitfield>
// <bitfield name="RF1_OPTION" range="9..8" type="ATR_OPTIONS" initialvalue="SW_DEFINED">
// <info>
// Option used for switches and LEDs of RF 1.
// </info>
// </bitfield>
// <bitfield name="RF0_DSA_OPTION" range="17..16" type="ATR_OPTIONS" initialvalue="SW_DEFINED">
// <info>
// Option used for DSAs of RF 0.
// </info>
// </bitfield>
// <bitfield name="RF1_DSA_OPTION" range="25..24" type="ATR_OPTIONS" initialvalue="SW_DEFINED">
// <info>
// Option used for DSAs of RF 1.
// </info>
// </bitfield>
// </register>
//
// <register name="SW_CONFIG_REG" size="32" offset="0x08" attributes="Readable|Writable">
// <info>
// Contains the configuration to be applied in case SW_DEFINED option is
// chosen.
// </info>
// <bitfield name="SW_RF0_CONFIG" range="7..0" type="integer" initialvalue="0">
// <info>
// SW defined configuration for switches and LEDs of RF 0.
// </info>
// </bitfield>
// <bitfield name="SW_RF1_CONFIG" range="15..8" type="integer" initialvalue="0">
// <info>
// SW defined configuration for switches and LEDs of RF 1.
// </info>
// </bitfield>
// <bitfield name="SW_RF0_DSA_CONFIG" range="23..16" type="integer" initialvalue="0">
// <info>
// SW defined configuration for DSAs of RF 0.
// </info>
// </bitfield>
// <bitfield name="SW_RF1_DSA_CONFIG" range="31..24" type="integer" initialvalue="0">
// <info>
// SW defined configuration for DSAs of RF 1.
// </info>
// </bitfield>
// </register>
// </group>
//</regmap>
//XmlParse xml_off