The main changes included are: - Variant-dependent pin-out instantiation. - Update clocking scheme in top level file to include XO3 PLL - Add ability to shift outgoing data for the GPIO communication interface with the X410 FPGA. - Include project files required to build the XO3 variant of the ZBX CPLD. - Add build flow for Lattice Diamond designs. - Add ability to build XO3 variant of ZBX CPLD. Original-commit: 2c7813acb21383f302353a1b6cf57f0946fa0b6b
743 lines
27 KiB
Verilog
743 lines
27 KiB
Verilog
//
|
|
// Copyright 2021 Ettus Research, a National Instruments Brand
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
//
|
|
// Module: dsa_control
|
|
//
|
|
// Description:
|
|
// Implements control over Digital Step Attenuators via CtrlPort. Uses RAM to
|
|
// store multiple ATR configurations. Provides gain table to abstract from raw
|
|
// DSA values.
|
|
//
|
|
// IMPORTANT: The default values here must be synchronized with the default
|
|
// values in gen_defaults.py, they are not automatically kept in sync.
|
|
//
|
|
|
|
`default_nettype none
|
|
|
|
module dsa_control #(
|
|
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 = 2'b0,
|
|
output reg [31:0] s_ctrlport_resp_data = 32'b0,
|
|
|
|
// ATR switching
|
|
input wire [ 7:0] atr_config_rf0,
|
|
input wire [ 7:0] atr_config_rf1,
|
|
|
|
// The attenuation setting for TX paths is indexed from two,
|
|
// to match schematic naming. In this case, the two LSBs
|
|
// for parallel control going into the DSA chips are connected
|
|
// to ground(those bits control fractional attenuation).
|
|
|
|
//Tx0 DSA control (domain: ctrl_reg_clk)
|
|
output wire [6:2] tx0_dsa1,
|
|
output wire [6:2] tx0_dsa2,
|
|
|
|
//Tx1 DSA control (domain: ctrl_reg_clk)
|
|
output wire [6:2] tx1_dsa1,
|
|
output wire [6:2] tx1_dsa2,
|
|
|
|
// The attenuation setting for RX paths is indexed from one,
|
|
// to match schematic naming. In this case, the LSB controls
|
|
// the highest value, so re reverse the order of the vector.
|
|
// Note the these signals are active low.
|
|
|
|
//Rx0 DSA control (domain: ctrl_reg_clk)
|
|
output wire [1:4] rx0_dsa1_n,
|
|
output wire [1:4] rx0_dsa2_n,
|
|
output wire [1:4] rx0_dsa3_a_n,
|
|
output wire [1:4] rx0_dsa3_b_n,
|
|
|
|
//Rx1 DSA control (domain: ctrl_reg_clk)
|
|
output wire [1:4] rx1_dsa1_n,
|
|
output wire [1:4] rx1_dsa2_n,
|
|
output wire [1:4] rx1_dsa3_a_n,
|
|
output wire [1:4] rx1_dsa3_b_n
|
|
);
|
|
|
|
`include "../regmap/dsa_setup_regmap_utils.vh"
|
|
`include "../../../../../../lib/rfnoc/core/ctrlport.vh"
|
|
|
|
//---------------------------------------------------------------
|
|
// register bitfields
|
|
//---------------------------------------------------------------
|
|
reg [TX_DSA1_SIZE -1:0] tx0_dsa_1_reg = {TX_DSA1_SIZE{1'b1}};
|
|
reg [TX_DSA2_SIZE -1:0] tx0_dsa_2_reg = {TX_DSA2_SIZE{1'b1}};
|
|
|
|
reg [TX_DSA1_SIZE -1:0] tx1_dsa_1_reg = {TX_DSA1_SIZE{1'b1}};
|
|
reg [TX_DSA2_SIZE -1:0] tx1_dsa_2_reg = {TX_DSA2_SIZE{1'b1}};
|
|
|
|
reg [RX_DSA1_SIZE -1:0] rx0_dsa_1_reg = {RX_DSA1_SIZE{1'b1}};
|
|
reg [RX_DSA2_SIZE -1:0] rx0_dsa_2_reg = {RX_DSA2_SIZE{1'b1}};
|
|
reg [RX_DSA3_A_SIZE -1:0] rx0_dsa_3_a_reg = {RX_DSA3_A_SIZE{1'b1}};
|
|
reg [RX_DSA3_B_SIZE -1:0] rx0_dsa_3_b_reg = {RX_DSA3_B_SIZE{1'b1}};
|
|
|
|
reg [RX_DSA1_SIZE -1:0] rx1_dsa_1_reg = {RX_DSA1_SIZE{1'b1}};
|
|
reg [RX_DSA2_SIZE -1:0] rx1_dsa_2_reg = {RX_DSA2_SIZE{1'b1}};
|
|
reg [RX_DSA3_A_SIZE -1:0] rx1_dsa_3_a_reg = {RX_DSA3_A_SIZE{1'b1}};
|
|
reg [RX_DSA3_B_SIZE -1:0] rx1_dsa_3_b_reg = {RX_DSA3_B_SIZE{1'b1}};
|
|
|
|
//---------------------------------------------------------------
|
|
// ATR memory signals
|
|
//---------------------------------------------------------------
|
|
reg ram_tx0_wea = 1'b0;
|
|
wire [31:0] ram_tx0_doa;
|
|
wire [31:0] ram_tx0_dob;
|
|
reg ram_tx1_wea = 1'b0;
|
|
wire [31:0] ram_tx1_doa;
|
|
wire [31:0] ram_tx1_dob;
|
|
reg ram_rx0_wea = 1'b0;
|
|
wire [31:0] ram_rx0_doa;
|
|
wire [31:0] ram_rx0_dob;
|
|
reg ram_rx1_wea = 1'b0;
|
|
wire [31:0] ram_rx1_doa;
|
|
wire [31:0] ram_rx1_dob;
|
|
|
|
reg table_tx0_wea = 1'b0;
|
|
wire [31:0] table_tx0_doa;
|
|
reg table_tx1_wea = 1'b0;
|
|
wire [31:0] table_tx1_doa;
|
|
reg table_rx0_wea = 1'b0;
|
|
wire [31:0] table_rx0_doa;
|
|
reg table_rx1_wea = 1'b0;
|
|
wire [31:0] table_rx1_doa;
|
|
|
|
//---------------------------------------------------------------
|
|
// Handling of CtrlPort
|
|
//---------------------------------------------------------------
|
|
// Check of request address is targeted for this module.
|
|
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) && (s_ctrlport_req_addr < BASE_ADDRESS + SIZE_ADDRESS);
|
|
// Read request shift register to align memory read and response generation.
|
|
reg [ 1:0] read_req_shift_reg = 2'b0;
|
|
// Write request shift register to align gain table memory read and ATR memory
|
|
// write operation.
|
|
reg [ 1:0] write_req_shift_reg = 2'b0;
|
|
// Mask out 8 bits for ATR configurations to be able to compare all ATR
|
|
// configurations against the same base register address.
|
|
wire [31:0] register_base_address = {s_ctrlport_req_addr[19:10], 8'b0, s_ctrlport_req_addr[1:0]};
|
|
// Extract masked out bits from the address, which represent the register
|
|
// array index = ATR configuration index
|
|
wire [ 7:0] register_index = s_ctrlport_req_addr[9:2];
|
|
// switch between CtrlPort data and gain table data for ATR memories
|
|
reg select_gain_table = 1'b0;
|
|
|
|
always @(posedge ctrlport_clk) begin
|
|
// reset internal registers and responses
|
|
if (ctrlport_rst) begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
|
|
read_req_shift_reg <= 2'b0;
|
|
write_req_shift_reg <= 2'b0;
|
|
|
|
ram_tx0_wea <= 1'b0;
|
|
ram_tx1_wea <= 1'b0;
|
|
ram_rx0_wea <= 1'b0;
|
|
ram_rx1_wea <= 1'b0;
|
|
|
|
table_tx0_wea <= 1'b0;
|
|
table_tx1_wea <= 1'b0;
|
|
table_rx0_wea <= 1'b0;
|
|
table_rx1_wea <= 1'b0;
|
|
|
|
select_gain_table <= 1'b0;
|
|
|
|
end else begin
|
|
// default assignments
|
|
read_req_shift_reg <= { read_req_shift_reg[0], s_ctrlport_req_rd};
|
|
write_req_shift_reg <= {write_req_shift_reg[0], s_ctrlport_req_wr};
|
|
|
|
ram_tx0_wea <= 1'b0;
|
|
ram_tx1_wea <= 1'b0;
|
|
ram_rx0_wea <= 1'b0;
|
|
ram_rx1_wea <= 1'b0;
|
|
|
|
table_tx0_wea <= 1'b0;
|
|
table_tx1_wea <= 1'b0;
|
|
table_rx0_wea <= 1'b0;
|
|
table_rx1_wea <= 1'b0;
|
|
|
|
select_gain_table <= 1'b0;
|
|
|
|
// Answer write requests delayed by 2 clock cycles. This compensated for
|
|
// register ram_addr and the memory internal address register to make sure
|
|
// gain table output data is up to date when forwarding data to ATR memory
|
|
if (write_req_shift_reg[1]) 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 (register_base_address)
|
|
BASE_ADDRESS + TX0_DSA_ATR(0): begin
|
|
ram_tx0_wea <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + TX1_DSA_ATR(0): begin
|
|
ram_tx1_wea <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + RX0_DSA_ATR(0): begin
|
|
ram_rx0_wea <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + RX1_DSA_ATR(0): begin
|
|
ram_rx1_wea <= 1'b1;
|
|
end
|
|
|
|
BASE_ADDRESS + TX0_DSA_TABLE(0): begin
|
|
table_tx0_wea <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + TX1_DSA_TABLE(0): begin
|
|
table_tx1_wea <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + RX0_DSA_TABLE(0): begin
|
|
table_rx0_wea <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + RX1_DSA_TABLE(0): begin
|
|
table_rx1_wea <= 1'b1;
|
|
end
|
|
|
|
BASE_ADDRESS + TX0_DSA_TABLE_SELECT(0): begin
|
|
ram_tx0_wea <= 1'b1;
|
|
select_gain_table <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + TX1_DSA_TABLE_SELECT(0): begin
|
|
ram_tx1_wea <= 1'b1;
|
|
select_gain_table <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + RX0_DSA_TABLE_SELECT(0): begin
|
|
ram_rx0_wea <= 1'b1;
|
|
select_gain_table <= 1'b1;
|
|
end
|
|
BASE_ADDRESS + RX1_DSA_TABLE_SELECT(0): begin
|
|
ram_rx1_wea <= 1'b1;
|
|
select_gain_table <= 1'b1;
|
|
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
|
|
|
|
// Answer read requests delayed by 2 clock cycles. This compensated for
|
|
// register ram_addr and the memory internal address register to make sure
|
|
// ram_ch0_doa is up to date when generating the response.
|
|
end else if (read_req_shift_reg[1]) 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 (register_base_address)
|
|
BASE_ADDRESS + TX0_DSA_ATR(0): begin
|
|
s_ctrlport_resp_data <= ram_tx0_doa & TX_DSA_CONTROL_MASK;
|
|
end
|
|
BASE_ADDRESS + TX1_DSA_ATR(0): begin
|
|
s_ctrlport_resp_data <= ram_tx1_doa & TX_DSA_CONTROL_MASK;
|
|
end
|
|
BASE_ADDRESS + RX0_DSA_ATR(0): begin
|
|
s_ctrlport_resp_data <= ram_rx0_doa & RX_DSA_CONTROL_MASK;
|
|
end
|
|
BASE_ADDRESS + RX1_DSA_ATR(0): begin
|
|
s_ctrlport_resp_data <= ram_rx1_doa & RX_DSA_CONTROL_MASK;
|
|
end
|
|
BASE_ADDRESS + TX0_DSA_TABLE(0): begin
|
|
s_ctrlport_resp_data <= table_tx0_doa & TX_DSA_CONTROL_MASK;
|
|
end
|
|
BASE_ADDRESS + TX1_DSA_TABLE(0): begin
|
|
s_ctrlport_resp_data <= table_tx1_doa & TX_DSA_CONTROL_MASK;
|
|
end
|
|
BASE_ADDRESS + RX0_DSA_TABLE(0): begin
|
|
s_ctrlport_resp_data <= table_rx0_doa & RX_DSA_CONTROL_MASK;
|
|
end
|
|
BASE_ADDRESS + RX1_DSA_TABLE(0): begin
|
|
s_ctrlport_resp_data <= table_rx1_doa & RX_DSA_CONTROL_MASK;
|
|
end
|
|
|
|
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
|
|
|
|
// no request
|
|
end else begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
// register without reset
|
|
reg [ 7:0] ram_addr = 8'b0;
|
|
reg [ 7:0] gain_table_addr = 8'b0;
|
|
reg [31:0] ram_datain = 32'b0;
|
|
always @(posedge ctrlport_clk) begin
|
|
// Capture CtrlPort data and address on requests as only in this clock cycle
|
|
// the data is valid.
|
|
if (s_ctrlport_req_wr || s_ctrlport_req_rd) begin
|
|
ram_addr <= register_index;
|
|
ram_datain <= s_ctrlport_req_data;
|
|
|
|
case (register_base_address)
|
|
BASE_ADDRESS + TX0_DSA_TABLE_SELECT(0),
|
|
BASE_ADDRESS + TX1_DSA_TABLE_SELECT(0),
|
|
BASE_ADDRESS + RX0_DSA_TABLE_SELECT(0),
|
|
BASE_ADDRESS + RX1_DSA_TABLE_SELECT(0): begin
|
|
gain_table_addr <= s_ctrlport_req_data[TABLE_INDEX_MSB:TABLE_INDEX];
|
|
end
|
|
default: begin
|
|
gain_table_addr <= register_index;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
// outputs
|
|
tx0_dsa_1_reg <= ram_tx0_dob[ TX_DSA1_MSB : TX_DSA1];
|
|
tx0_dsa_2_reg <= ram_tx0_dob[ TX_DSA2_MSB : TX_DSA2];
|
|
|
|
tx1_dsa_1_reg <= ram_tx1_dob[ TX_DSA1_MSB : TX_DSA1];
|
|
tx1_dsa_2_reg <= ram_tx1_dob[ TX_DSA2_MSB : TX_DSA2];
|
|
|
|
rx0_dsa_1_reg <= ram_rx0_dob[ RX_DSA1_MSB : RX_DSA1];
|
|
rx0_dsa_2_reg <= ram_rx0_dob[ RX_DSA2_MSB : RX_DSA2];
|
|
rx0_dsa_3_a_reg <= ram_rx0_dob[RX_DSA3_A_MSB : RX_DSA3_A];
|
|
rx0_dsa_3_b_reg <= ram_rx0_dob[RX_DSA3_B_MSB : RX_DSA3_B];
|
|
|
|
rx1_dsa_1_reg <= ram_rx1_dob[ RX_DSA1_MSB : RX_DSA1];
|
|
rx1_dsa_2_reg <= ram_rx1_dob[ RX_DSA2_MSB : RX_DSA2];
|
|
rx1_dsa_3_a_reg <= ram_rx1_dob[RX_DSA3_A_MSB : RX_DSA3_A];
|
|
rx1_dsa_3_b_reg <= ram_rx1_dob[RX_DSA3_B_MSB : RX_DSA3_B];
|
|
end
|
|
|
|
assign tx0_dsa1[6:2] = tx0_dsa_1_reg;
|
|
assign tx0_dsa2[6:2] = tx0_dsa_2_reg;
|
|
|
|
assign tx1_dsa1[6:2] = tx1_dsa_1_reg;
|
|
assign tx1_dsa2[6:2] = tx1_dsa_2_reg;
|
|
|
|
//Rx DSAs behave differently from Tx DSAs
|
|
//Flip MSB/LSB, and invert
|
|
|
|
genvar vi;
|
|
// take care of inverting the active low logic and bit-reversing
|
|
// the DSA controls for RX paths.
|
|
generate
|
|
for (vi=1; vi<=4; vi=vi+1) begin : reverselogic
|
|
// [1:4] [3:0]
|
|
assign rx0_dsa1_n[vi] = !rx0_dsa_1_reg[4-vi];
|
|
assign rx0_dsa2_n[vi] = !rx0_dsa_2_reg[4-vi];
|
|
assign rx0_dsa3_a_n[vi] = !rx0_dsa_3_a_reg[4-vi];
|
|
assign rx0_dsa3_b_n[vi] = !rx0_dsa_3_b_reg[4-vi];
|
|
|
|
assign rx1_dsa1_n[vi] = !rx1_dsa_1_reg[4-vi];
|
|
assign rx1_dsa2_n[vi] = !rx1_dsa_2_reg[4-vi];
|
|
assign rx1_dsa3_a_n[vi] = !rx1_dsa_3_a_reg[4-vi];
|
|
assign rx1_dsa3_b_n[vi] = !rx1_dsa_3_b_reg[4-vi];
|
|
end
|
|
endgenerate
|
|
|
|
//---------------------------------------------------------------
|
|
// ATR memories
|
|
//---------------------------------------------------------------
|
|
// Choose data source for ATR configurations from CtrlPort or gain table.
|
|
wire [31:0] ram_rx0_dia = select_gain_table ? table_rx0_doa : ram_datain;
|
|
wire [31:0] ram_rx1_dia = select_gain_table ? table_rx1_doa : ram_datain;
|
|
wire [31:0] ram_tx0_dia = select_gain_table ? table_tx0_doa : ram_datain;
|
|
wire [31:0] ram_tx1_dia = select_gain_table ? table_tx1_doa : ram_datain;
|
|
|
|
`ifdef VARIANT_XO3
|
|
localparam RAM_RW_MODE = "B-READ-ONLY" ;
|
|
`else
|
|
localparam RAM_RW_MODE = "READ-FIRST" ;
|
|
`endif
|
|
|
|
ram_2port #(
|
|
.DWIDTH (32),
|
|
.AWIDTH (8),
|
|
.RW_MODE (RAM_RW_MODE),
|
|
.RAM_TYPE ("AUTOMATIC"),
|
|
.OUT_REG (0),
|
|
.INIT_FILE ("register_endpoints/memory_init_files/tx_dsa_defaults.hex")
|
|
) ram_tx0_i (
|
|
.clka (ctrlport_clk),
|
|
.ena (1'b1),
|
|
.wea (ram_tx0_wea),
|
|
.addra (ram_addr),
|
|
.dia (ram_tx0_dia),
|
|
.doa (ram_tx0_doa),
|
|
.clkb (ctrlport_clk),
|
|
.enb (1'b1),
|
|
.web (1'b0),
|
|
.addrb (atr_config_rf0),
|
|
.dib (0),
|
|
.dob (ram_tx0_dob)
|
|
);
|
|
|
|
ram_2port #(
|
|
.DWIDTH (32),
|
|
.AWIDTH (8),
|
|
.RW_MODE (RAM_RW_MODE),
|
|
.RAM_TYPE ("AUTOMATIC"),
|
|
.OUT_REG (0),
|
|
.INIT_FILE ("register_endpoints/memory_init_files/tx_dsa_defaults.hex")
|
|
) ram_tx1_i (
|
|
.clka (ctrlport_clk),
|
|
.ena (1'b1),
|
|
.wea (ram_tx1_wea),
|
|
.addra (ram_addr),
|
|
.dia (ram_tx1_dia),
|
|
.doa (ram_tx1_doa),
|
|
.clkb (ctrlport_clk),
|
|
.enb (1'b1),
|
|
.web (1'b0),
|
|
.addrb (atr_config_rf1),
|
|
.dib (0),
|
|
.dob (ram_tx1_dob)
|
|
);
|
|
|
|
ram_2port #(
|
|
.DWIDTH (32),
|
|
.AWIDTH (8),
|
|
.RW_MODE (RAM_RW_MODE),
|
|
.RAM_TYPE ("AUTOMATIC"),
|
|
.OUT_REG (0),
|
|
.INIT_FILE ("register_endpoints/memory_init_files/rx_dsa_defaults.hex")
|
|
) ram_rx0_i (
|
|
.clka (ctrlport_clk),
|
|
.ena (1'b1),
|
|
.wea (ram_rx0_wea),
|
|
.addra (ram_addr),
|
|
.dia (ram_rx0_dia),
|
|
.doa (ram_rx0_doa),
|
|
.clkb (ctrlport_clk),
|
|
.enb (1'b1),
|
|
.web (1'b0),
|
|
.addrb (atr_config_rf0),
|
|
.dib (0),
|
|
.dob (ram_rx0_dob)
|
|
);
|
|
|
|
ram_2port #(
|
|
.DWIDTH (32),
|
|
.AWIDTH (8),
|
|
.RW_MODE (RAM_RW_MODE),
|
|
.RAM_TYPE ("AUTOMATIC"),
|
|
.OUT_REG (0),
|
|
.INIT_FILE ("register_endpoints/memory_init_files/rx_dsa_defaults.hex")
|
|
) ram_rx1_i (
|
|
.clka (ctrlport_clk),
|
|
.ena (1'b1),
|
|
.wea (ram_rx1_wea),
|
|
.addra (ram_addr),
|
|
.dia (ram_rx1_dia),
|
|
.doa (ram_rx1_doa),
|
|
.clkb (ctrlport_clk),
|
|
.enb (1'b1),
|
|
.web (1'b0),
|
|
.addrb (atr_config_rf1),
|
|
.dib (0),
|
|
.dob (ram_rx1_dob)
|
|
);
|
|
|
|
//---------------------------------------------------------------
|
|
// Gain tables
|
|
//---------------------------------------------------------------
|
|
|
|
ram_2port #(
|
|
.DWIDTH (32),
|
|
.AWIDTH (8),
|
|
.RW_MODE (RAM_RW_MODE),
|
|
.RAM_TYPE ("AUTOMATIC"),
|
|
.OUT_REG (0),
|
|
.INIT_FILE ("register_endpoints/memory_init_files/tx_dsa_defaults.hex")
|
|
) table_tx0_i (
|
|
.clka (ctrlport_clk),
|
|
.ena (1'b1),
|
|
.wea (table_tx0_wea),
|
|
.addra (gain_table_addr),
|
|
.dia (ram_datain),
|
|
.doa (table_tx0_doa),
|
|
.clkb (ctrlport_clk),
|
|
.enb (1'b1),
|
|
.web (1'b0),
|
|
.addrb (8'b0),
|
|
.dib (32'b0),
|
|
.dob ()
|
|
);
|
|
|
|
ram_2port #(
|
|
.DWIDTH (32),
|
|
.AWIDTH (8),
|
|
.RW_MODE (RAM_RW_MODE),
|
|
.RAM_TYPE ("AUTOMATIC"),
|
|
.OUT_REG (0),
|
|
.INIT_FILE ("register_endpoints/memory_init_files/tx_dsa_defaults.hex")
|
|
) table_tx1_i (
|
|
.clka (ctrlport_clk),
|
|
.ena (1'b1),
|
|
.wea (table_tx1_wea),
|
|
.addra (gain_table_addr),
|
|
.dia (ram_datain),
|
|
.doa (table_tx1_doa),
|
|
.clkb (ctrlport_clk),
|
|
.enb (1'b1),
|
|
.web (1'b0),
|
|
.addrb (8'b0),
|
|
.dib (32'b0),
|
|
.dob ()
|
|
);
|
|
|
|
ram_2port #(
|
|
.DWIDTH (32),
|
|
.AWIDTH (8),
|
|
.RW_MODE (RAM_RW_MODE),
|
|
.RAM_TYPE ("AUTOMATIC"),
|
|
.OUT_REG (0),
|
|
.INIT_FILE ("register_endpoints/memory_init_files/rx_dsa_defaults.hex")
|
|
) table_rx0_i (
|
|
.clka (ctrlport_clk),
|
|
.ena (1'b1),
|
|
.wea (table_rx0_wea),
|
|
.addra (gain_table_addr),
|
|
.dia (ram_datain),
|
|
.doa (table_rx0_doa),
|
|
.clkb (ctrlport_clk),
|
|
.enb (1'b1),
|
|
.web (1'b0),
|
|
.addrb (8'b0),
|
|
.dib (32'b0),
|
|
.dob ()
|
|
);
|
|
|
|
ram_2port #(
|
|
.DWIDTH (32),
|
|
.AWIDTH (8),
|
|
.RW_MODE (RAM_RW_MODE),
|
|
.RAM_TYPE ("AUTOMATIC"),
|
|
.OUT_REG (0),
|
|
.INIT_FILE ("register_endpoints/memory_init_files/rx_dsa_defaults.hex")
|
|
) table_rx1_i (
|
|
.clka (ctrlport_clk),
|
|
.ena (1'b1),
|
|
.wea (table_rx1_wea),
|
|
.addra (gain_table_addr),
|
|
.dia (ram_datain),
|
|
.doa (table_rx1_doa),
|
|
.clkb (ctrlport_clk),
|
|
.enb (1'b1),
|
|
.web (1'b0),
|
|
.addrb (8'b0),
|
|
.dib (32'b0),
|
|
.dob ()
|
|
);
|
|
|
|
endmodule
|
|
|
|
`default_nettype wire
|
|
|
|
//XmlParse xml_on
|
|
//<regmap name="DSA_SETUP_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true" markdown="true">
|
|
// <group name="DSA_SETUP_REGISTERS">
|
|
// <info>
|
|
// The following registers control the digital step attenuators (DSA).
|
|
//
|
|
// There are two ways to set the DSA values, which are applied to the DB ICs.
|
|
//
|
|
// 1. The ...DSA_ATR registers can be used to access the raw
|
|
// values of each ATR configuration.
|
|
//
|
|
// 2. Gain tables can be used as intermediate step to abstract from the
|
|
// raw DB values. This gain table can be modified using the ...DSA_TABLE
|
|
// registers according to the content of the registers from the first
|
|
// option. Initially each gain table is empty (all zeros). Each gain
|
|
// table entry can be accessed at any time. Once the table is filled with
|
|
// values the ...DSA_TABLE_SELECT registers can be used to get one gain
|
|
// table entry with index TABLE_INDEX and write it to the appropriate ATR
|
|
// configuration given by the address (see _show extended info_ link below
|
|
// the register array headlines)
|
|
// </info>
|
|
// <regtype name="TX_DSA_CONTROL" size="32" attributes="Readable|Writable">
|
|
// <bitfield name="TX_DSA1" range="4..0" initialvalue="31">
|
|
// <info>
|
|
// Sets the attenuation level for Tx DSA1. The resolution attenuation is 1 dB, with an attenuation range from 1 to 31 dB. Write this field with the
|
|
// attenuation setting desired. Writing zero to this field results in no attenuation (different insertion loss expected for different frequency ranges).
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="TX_DSA2" range="12..8" initialvalue="31">
|
|
// <info>
|
|
// Sets the attenuation level for Tx DSA2. The resolution attenuation is 1 dB, with an attenuation range from 1 to 31 dB. Write this field with the
|
|
// attenuation setting desired. Writing zero to this field results in no attenuation (different insertion loss expected for different frequency ranges).
|
|
// </info>
|
|
// </bitfield>
|
|
// </regtype>
|
|
//
|
|
// <regtype name="RX_DSA_CONTROL" size="32" attributes="Readable|Writable">
|
|
// <bitfield name="RX_DSA1" range="3..0" initialvalue="15">
|
|
// <info>
|
|
// Sets the attenuation level for Rx DSA1. The resolution attenuation is 1 dB, with an attenuation range from 1 to 15 dB. Write this field with the
|
|
// attenuation setting desired. Writing zero to this field results in no attenuation (different insertion loss expected for different frequency ranges).
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="RX_DSA2" range="7..4" initialvalue="15">
|
|
// <info>
|
|
// Sets the attenuation level for Rx DSA2. The resolution attenuation is 1 dB, with an attenuation range from 1 to 15 dB. Write this field with the
|
|
// attenuation setting desired. Writing zero to this field results in no attenuation (different insertion loss expected for different frequency ranges).
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="RX_DSA3_A" range="11..8" initialvalue="15">
|
|
// <info>
|
|
// Sets the attenuation level for Rx DSA 3a and 3b. The resolution attenuation is 1 dB, with an attenuation range from 1 to 15 dB. Write this field with the
|
|
// attenuation setting desired. Writing zero to this field results in no attenuation (different insertion loss expected for different frequency ranges).
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="RX_DSA3_B" range="15..12" initialvalue="15">
|
|
// <info>
|
|
// Sets the attenuation level for Rx DSA 3b(to input of IF1 Amplifier 2). The resolution attenuation is 1 dB, with an attenuation range from 1 to 15 dB. Write this field with the
|
|
// attenuation setting desired. Writing zero to this field results in no attenuation (different insertion loss expected for different frequency ranges).. {BR/}
|
|
// </info>
|
|
// </bitfield>
|
|
// </regtype>
|
|
//
|
|
// <regtype name="DSA_TABLE_CONTROL" size="32" attributes="Writable">
|
|
// <bitfield name="TABLE_INDEX" range="7..0">
|
|
// <info>
|
|
// Gain table index to be used for getting the raw attenuation values.
|
|
// </info>
|
|
// </bitfield>
|
|
// </regtype>
|
|
//
|
|
// <register name="TX0_DSA_ATR" offset="0x000" count="256" step="4" typename="TX_DSA_CONTROL">
|
|
// <info>
|
|
// Controls the Tx0 DSAs by accessing the raw attenuation levels.
|
|
//
|
|
// This register array can hold settings for all ATR configurations.
|
|
// The register index equals the ATR configuration.
|
|
// The active configuration can be selected in @.ATR_REGMAP.
|
|
// Independently all configurations can be read/written at any time.
|
|
// </info>
|
|
// </register>
|
|
// <register name="TX1_DSA_ATR" offset="0x400" count="256" step="4" typename="TX_DSA_CONTROL">
|
|
// <info>
|
|
// Controls the Tx1 DSAs by accessing the raw attenuation levels.
|
|
//
|
|
// This register array can hold settings for all ATR configurations.
|
|
// The register index equals the ATR configuration.
|
|
// The active configuration can be selected in @.ATR_REGMAP.
|
|
// Independently all configurations can be read/written at any time.
|
|
// </info>
|
|
// </register>
|
|
//
|
|
// <register name="RX0_DSA_ATR" offset="0x800" count="256" step="4" typename="RX_DSA_CONTROL">
|
|
// <info>
|
|
// Controls the Rx0 DSAs by accessing the raw attenuation levels.
|
|
//
|
|
// This register array can hold settings for all ATR configurations.
|
|
// The register index equals the ATR configuration.
|
|
// The active configuration can be selected in @.ATR_REGMAP.
|
|
// Independently all configurations can be read/written at any time.
|
|
// </info>
|
|
// </register>
|
|
// <register name="RX1_DSA_ATR" offset="0xC00" count="256" step="4" typename="RX_DSA_CONTROL">
|
|
// <info>
|
|
// Controls the Rx1 DSAs by accessing the raw attenuation levels.
|
|
//
|
|
// This register array can hold settings for all ATR configurations.
|
|
// The register index equals the ATR configuration.
|
|
// The active configuration can be selected in @.ATR_REGMAP.
|
|
// Independently all configurations can be read/written at any time.
|
|
// </info>
|
|
// </register>
|
|
//
|
|
// <register name="TX0_DSA_TABLE_SELECT" offset="0x1000" count="256" step="4" typename="DSA_TABLE_CONTROL">
|
|
// <info>
|
|
// Controls the Tx0 DSAs by using the gain table to translate the table
|
|
// index to raw attenuation levels. The register offset (i) is targeting
|
|
// an ATR configuration to store the values from the gain table.
|
|
// </info>
|
|
// </register>
|
|
// <register name="TX1_DSA_TABLE_SELECT" offset="0x1400" count="256" step="4" typename="DSA_TABLE_CONTROL">
|
|
// <info>
|
|
// Controls the Tx1 DSAs by using the gain table to translate the table
|
|
// index to raw attenuation levels. The register offset (i) is targeting
|
|
// an ATR configuration to store the values from the gain table.
|
|
// </info>
|
|
// </register>
|
|
// <register name="RX0_DSA_TABLE_SELECT" offset="0x1800" count="256" step="4" typename="DSA_TABLE_CONTROL">
|
|
// <info>
|
|
// Controls the Rx0 DSAs by using the gain table to translate the table
|
|
// index to raw attenuation levels. The register offset (i) is targeting
|
|
// an ATR configuration to store the values from the gain table.
|
|
// </info>
|
|
// </register>
|
|
// <register name="RX1_DSA_TABLE_SELECT" offset="0x1C00" count="256" step="4" typename="DSA_TABLE_CONTROL">
|
|
// <info>
|
|
// Controls the Rx1 DSAs by using the gain table to translate the table
|
|
// index to raw attenuation levels. The register offset (i) is targeting
|
|
// an ATR configuration to store the values from the gain table.
|
|
// </info>
|
|
// </register>
|
|
//
|
|
// <register name="TX0_DSA_TABLE" offset="0x2000" count="256" step="4" typename="TX_DSA_CONTROL">
|
|
// <info>
|
|
// Provides access to the gain table for Tx0.
|
|
//
|
|
// Each entry i will be saved in the gain table without any implications
|
|
// on HW. Enables SW to use the table index in @.TX0_DSA_TABLE_SELECT to
|
|
// modify the ATR configurations.
|
|
// </info>
|
|
// </register>
|
|
// <register name="TX1_DSA_TABLE" offset="0x2400" count="256" step="4" typename="TX_DSA_CONTROL">
|
|
// <info>
|
|
// Provides access to the gain table for Tx1.
|
|
//
|
|
// Each entry i will be saved in the gain table without any implications
|
|
// on HW. Enables SW to use the table index in @.TX1_DSA_TABLE_SELECT to
|
|
// modify the ATR configurations.
|
|
// </info>
|
|
// </register>
|
|
// <register name="RX0_DSA_TABLE" offset="0x2800" count="256" step="4" typename="RX_DSA_CONTROL">
|
|
// <info>
|
|
// Provides access to the gain table for Rx0.
|
|
//
|
|
// Each entry i will be saved in the gain table without any implications
|
|
// on HW. Enables SW to use the table index in @.RX0_DSA_TABLE_SELECT to
|
|
// modify the ATR configurations.
|
|
// </info>
|
|
// </register>
|
|
// <register name="RX1_DSA_TABLE" offset="0x2C00" count="256" step="4" typename="RX_DSA_CONTROL">
|
|
// <info>
|
|
// Provides access to the gain table for Rx1.
|
|
//
|
|
// Each entry i will be saved in the gain table without any implications
|
|
// on HW. Enables SW to use the table index in @.RX1_DSA_TABLE_SELECT to
|
|
// modify the ATR configurations.
|
|
// </info>
|
|
// </register>
|
|
// </group>
|
|
//</regmap>
|
|
//XmlParse xml_off
|