Files
b210-k7-fpga/top/n3xx/dboards/rh/cpld/rhodium_top.v
T
+18 6b67702ad7 Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce
the size of the repository. However, over the last half-decade, the
split between the repositories has proven more burdensome than it has
been helpful. By merging the FPGA code back, it will be possible to
create atomic commits that touch both FPGA and UHD codebases. Continuous
integration testing is also simplified by merging the repositories,
because it was previously difficult to automatically derive the correct
UHD branch when testing a feature branch on the FPGA repository.

This commit also updates the license files and paths therein.

We are therefore merging the repositories again. Future development for
FPGA code will happen in the same repository as the UHD host code and
MPM code.

== Original Codebase and Rebasing ==

The original FPGA repository will be hosted for the foreseeable future
at its original local location: https://github.com/EttusResearch/fpga/

It can be used for bisecting, reference, and a more detailed history.

The final commit from said repository to be merged here is
05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as
v4.0.0.0-pre-uhd-merge.

If you have changes in the FPGA repository that you want to rebase onto
the UHD repository, simply run the following commands:

- Create a directory to store patches (this should be an empty
  directory):

    mkdir ~/patches

- Now make sure that your FPGA codebase is based on the same state as
  the code that was merged:

    cd src/fpga # Or wherever your FPGA code is stored
    git rebase v4.0.0.0-pre-uhd-merge

  Note: The rebase command may look slightly different depending on what
  exactly you're trying to rebase.

- Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge:

    git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches

  Note: Make sure that only patches are stored in your output directory.
  It should otherwise be empty. Make sure that you picked the correct
  range of commits, and only commits you wanted to rebase were exported
  as patch files.

- Go to the UHD repository and apply the patches:

    cd src/uhd # Or wherever your UHD repository is stored
    git am --directory fpga ~/patches/*
    rm -rf ~/patches # This is for cleanup

== Contributors ==

The following people have contributed mainly to these files (this list
is not complete):

Co-authored-by: Alex Williams <alex.williams@ni.com>
Co-authored-by: Andrej Rode <andrej.rode@ettus.com>
Co-authored-by: Ashish Chaudhari <ashish@ettus.com>
Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com>
Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Derek Kozel <derek.kozel@ettus.com>
Co-authored-by: EJ Kreinar <ej@he360.com>
Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com>
Co-authored-by: Ian Buckley <ian.buckley@gmail.com>
Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Jon Kiser <jon.kiser@ni.com>
Co-authored-by: Josh Blum <josh@joshknows.com>
Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com>
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Matt Ettus <matt@ettus.com>
Co-authored-by: Michael West <michael.west@ettus.com>
Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com>
Co-authored-by: Nick Foster <nick@ettus.com>
Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Paul David <paul.david@ettus.com>
Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com>
Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-authored-by: Sylvain Munaut <tnt@246tNt.com>
Co-authored-by: Trung Tran <trung.tran@ettus.com>
Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>


Original-commit: bafa9d95453387814ef25e6b6256ba8db2df612f
2020-01-28 09:35:36 -08:00

606 lines
17 KiB
Verilog

///////////////////////////////////////////////////////////////////
//
// Copyright 2018 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: rhodium_top
//////////////////////////////////////////////////////////////////////
`default_nettype none
module rhodium_top(
input [13:0] usrp_io, // bank 1A, 1B and 6
input ADC_A_Over_Range_18, input ADC_B_Over_Range_18, // bank 1A
// bank 6
input CPLD_PS_SPI_LE_25,
input CPLD_PS_SPI_CLK_25,
input CPLD_PS_ADDR0_25,
input CPLD_PS_ADDR1_25,
input CPLD_PS_SPI_SDI_25,
output reg CPLD_PS_SPI_SDO_25,
output PHDAC_SPI_CS_L,
output PHDAC_SPI_SCLK,
output PHDAC_SPI_SDI,
input LO_SYNC,
// bank 2
output reg CPLD_PL_SPI_SDO_18,
input CPLD_PL_SPI_LE_18,
input CPLD_PL_SPI_SCLK_18,
input CPLD_PL_SPI_SDI_18,
input CPLD_PL_SPI_ADDR0_18,
input CPLD_PL_SPI_ADDR1_18,
input CPLD_PL_SPI_ADDR2_18,
// NOTE: TxRx front-end switches are driven direct from the motherboard, so these ATR
// lines have no function at this time.
input CPLD_ATR_TX_18,
input CPLD_ATR_RX_18,
output ADC_SPI_CS_L_18,
output ADC_SPI_SCLK_18,
inout ADC_SPI_SDIO_18,
output DAC_SPI_CS_L_18,
output DAC_SPI_SCLK_18,
inout DAC_SPI_SDIO_18,
input DAC_Alarm_18, // TODO: drive to gpio?
// bank 3
output CLKDIST_SPI_CS_L,
output CLKDIST_SPI_SCLK,
inout CLKDIST_SPI_SDIO,
output Tx_DSA_C1,
output Tx_DSA_C2,
output Tx_DSA_C4,
output Tx_DSA_C8,
output Tx_DSA_C16,
output Tx_DSA1_LE,
output Tx_DSA2_LE,
output Tx_Sw1_Ctrl_1,
output Tx_Sw1_Ctrl_2,
output Tx_Sw2_Ctrl_1,
output Tx_Sw2_Ctrl_2,
output Tx_Sw3_Ctrl_1,
output Tx_Sw3_Ctrl_2,
output Tx_Sw3_Ctrl_3,
output Tx_Sw3_Ctrl_4,
output Rx_LO_Input_Select,
output Rx_LO_Filter_Sw_1,
output Rx_LO_Filter_Sw_2,
output Tx_LO_Input_Select,
output Tx_LO_Filter_Sw_1,
output Tx_LO_Filter_Sw_2,
input CLKDIST_Status_LD1,
input CLKDIST_Status_LD2,
input LOSYNTH_RX_MUXOUT,
input LOSYNTH_TX_MUXOUT,
// bank 8
output LO_SPI_SCLK, // fans out to both rx & tx synths
output LO_SPI_SDI,
output LO_TX_CS_L,
output LO_RX_CS_L,
output Rx_Sw1_Ctrl_1,
output Rx_Sw1_Ctrl_2,
output Rx_DSA_C1,
output Rx_DSA_C2,
output Rx_DSA_C4,
output Rx_DSA_C8,
output Rx_DSA_C16,
output Rx_DSA1_LE,
output Rx_DSA2_LE,
output Rx_Sw2_Ctrl,
output Rx_Sw3_Ctrl_1,
output Rx_Sw3_Ctrl_2,
output Rx_Sw4_Ctrl_1,
output Rx_Sw4_Ctrl_2,
output Rx_Sw4_Ctrl_3,
output Rx_Sw4_Ctrl_4,
output Rx_Demod_ADJ_1,
output Rx_Demod_ADJ_2,
// bank 5
output LO_DSA_C1,
output LO_DSA_C2,
output LO_DSA_C4,
output LO_DSA_C8,
output LO_DSA_C16,
output RxLO_DSA_LE,
output TxLO_DSA_LE,
output LODIST_Bd_SPI_CS_L,
output LODIST_Bd_SPI_SDI,
output LODIST_Bd_SPI_SCLK,
inout LODIST_Bd_IO1,
output Tx_Sw5_Ctrl_1,
output Tx_Sw5_Ctrl_2,
output Rx_Sw6_Ctrl_1,
output Rx_Sw6_Ctrl_2,
output Tx_HB_LB_Select,
output Rx_HB_LB_Select,
output Cal_iso_Sw_Ctrl
);
/* PS SPI */
localparam GIT_HASH = 36'h`GIT_HASH;
localparam PROD_SIGNATURE = 16'h0045; // Product signature (Rhodium atomic number in BCD)
localparam REVISION_MINOR = 16'h0002;
localparam REVISION_MAJOR = 16'h0004;
localparam CPLD_BUILD_LSB = GIT_HASH[15:0]; // Build code LSB
localparam CPLD_BUILD_MSB = GIT_HASH[31:16]; // Build code MSB
localparam PSADDR_SIGNATURE = 3'd0;
localparam PSADDR_REV_MINOR = 3'd1; // Minor version register
localparam PSADDR_REV_MAJOR = 3'd2; // Major version register
localparam PSADDR_BUILD_LSB = 3'd3;
localparam PSADDR_BUILD_MSB = 3'd4;
localparam PSADDR_SCRATCH = 3'd5; // scratchpad register
localparam PSADDR_GAIN_SEL = 3'd6; // band select for gain table loader
localparam PSADDR_DAC_ALARM = 3'd7; // DAC alarm pin register
// Sub-device selection for PS SPI
localparam PS_CPLD_REGS = 2'b00;
localparam GAIN_TABLE_RX = 2'b01;
localparam GAIN_TABLE_TX = 2'b10;
localparam GAIN_TABLE_LO = 2'b11;
// Setting to put TX SW1 in isolation mode
localparam [1:0] TX_SW1_TERM = 2'b11;
wire clkdis_cs_b = CPLD_PS_SPI_LE_25;
wire cpld_ps_cs_b = CPLD_PS_ADDR0_25;
wire phdac_cs_b = CPLD_PS_ADDR1_25;
wire adc_cs_b = usrp_io[12];
wire dac_cs_b = usrp_io[13];
// CPLD PS SPI format (left-most bit first):
// {table_sel[1:0], rsvd, reg_addr[3:0], rnw, data[15:0]}
wire [1:0] cpld_ps_table_sel;
wire [6:0] cpld_ps_spi_addr;
wire cpld_ps_spi_rnw;
reg [7:0] cpld_ps_spi_cmd;
reg [15:0] cpld_ps_spi_rdata;
reg [14:0] cpld_ps_spi_wdata;
reg cpld_ps_spi_sdo;
reg [4:0] cpld_ps_cnt;
assign {cpld_ps_spi_addr, cpld_ps_spi_rnw} = cpld_ps_spi_cmd;
// CPLD registers
reg [15:0] spad;
reg [15:0] gain_load_sel;
// Double sync. the DAC ALARM pin (async).
reg dac_alarm_ms, dac_alarm = 0;
always @(posedge CPLD_PS_SPI_CLK_25) begin
{dac_alarm, dac_alarm_ms} <= {dac_alarm_ms, DAC_Alarm_18};
end
wire rx_gain_load_tbl_sel;
wire rx_gain_load_miso;
wire rx_gain_ctrl_tbl_sel;
wire rx_gain_ctrl_miso;
wire tx_gain_load_tbl_sel;
wire tx_gain_load_miso;
wire tx_gain_ctrl_tbl_sel;
wire tx_gain_ctrl_miso;
wire lo_gain_ctrl_miso;
assign rx_gain_load_tbl_sel = gain_load_sel[0];
assign tx_gain_load_tbl_sel = gain_load_sel[8];
always @(posedge CPLD_PS_SPI_CLK_25 or posedge cpld_ps_cs_b)
begin
if (cpld_ps_cs_b) begin
cpld_ps_cnt <= 5'd0;
end else if (!cpld_ps_cs_b) begin
if (cpld_ps_cnt < 8) begin // Address / command
cpld_ps_spi_cmd <= {cpld_ps_spi_cmd[6:0], CPLD_PS_SPI_SDI_25};
cpld_ps_cnt <= cpld_ps_cnt + 5'd1;
end else if (cpld_ps_cnt < 23) begin // Shift in write data
cpld_ps_spi_wdata <= {cpld_ps_spi_wdata[13:0], CPLD_PS_SPI_SDI_25};
cpld_ps_cnt <= cpld_ps_cnt + 5'd1;
end else if (!cpld_ps_spi_rnw && cpld_ps_cnt == 23 && cpld_ps_spi_addr[6:5] == PS_CPLD_REGS) begin // Write
case (cpld_ps_spi_addr[2:0])
PSADDR_SIGNATURE: ;
PSADDR_REV_MINOR: ;
PSADDR_REV_MAJOR: ;
PSADDR_BUILD_LSB: ;
PSADDR_BUILD_MSB: ;
PSADDR_SCRATCH: spad <= {cpld_ps_spi_wdata, CPLD_PS_SPI_SDI_25};
PSADDR_GAIN_SEL: gain_load_sel <= {cpld_ps_spi_wdata, CPLD_PS_SPI_SDI_25};
endcase
end
if (cpld_ps_cnt == 7) begin // Set up read one cycle earlier
case (cpld_ps_spi_cmd[2:0])
PSADDR_SIGNATURE: cpld_ps_spi_rdata <= PROD_SIGNATURE;
PSADDR_REV_MINOR: cpld_ps_spi_rdata <= REVISION_MINOR;
PSADDR_REV_MAJOR: cpld_ps_spi_rdata <= REVISION_MAJOR;
PSADDR_BUILD_LSB: cpld_ps_spi_rdata <= CPLD_BUILD_LSB;
PSADDR_BUILD_MSB: cpld_ps_spi_rdata <= CPLD_BUILD_MSB;
PSADDR_SCRATCH: cpld_ps_spi_rdata <= spad;
PSADDR_GAIN_SEL: cpld_ps_spi_rdata <= gain_load_sel;
PSADDR_DAC_ALARM: cpld_ps_spi_rdata <= {15'b0, dac_alarm};
endcase
end else begin
cpld_ps_spi_rdata <= {cpld_ps_spi_rdata[14:0], 1'b1};
end
end
end
always @(negedge CPLD_PS_SPI_CLK_25)
begin
cpld_ps_spi_sdo <= cpld_ps_spi_rdata[15]; // Shift out on negative edge
end
// CLKDIST 3-wire to 4-wire
reg [4:0] clkdis_cnt;
reg clkdis_rd_pre, clkdis_rd, clkdis_sdio_t;
always @(posedge CPLD_PS_SPI_CLK_25 or posedge clkdis_cs_b)
begin
if (clkdis_cs_b) begin
clkdis_cnt <= 5'd0;
clkdis_rd <= 1'b0;
clkdis_rd_pre <= 1'b0;
end else if (!clkdis_cs_b) begin
if (clkdis_cnt < 23)
clkdis_cnt <= clkdis_cnt + 5'd1;
if (clkdis_cnt == 5'd0) // Check if read
clkdis_rd_pre <= CPLD_PS_SPI_SDI_25;
if (clkdis_cnt == 5'd15)
clkdis_rd <= clkdis_rd_pre;
end
end
always @(negedge CPLD_PS_SPI_CLK_25 or posedge clkdis_cs_b)
begin
if (clkdis_cs_b) begin
clkdis_sdio_t <= 1'b0;
end else begin
clkdis_sdio_t <= clkdis_rd;
end
end
// ADC 3-wire to 4-wire
reg [4:0] adc_cnt;
reg adc_rd_pre, adc_rd, adc_sdio_t;
always @(posedge CPLD_PS_SPI_CLK_25 or posedge adc_cs_b)
begin
if (adc_cs_b) begin
adc_cnt <= 5'd0;
adc_rd <= 1'b0;
adc_rd_pre <= 1'b0;
end else if (!adc_cs_b) begin
if (adc_cnt < 23)
adc_cnt <= adc_cnt + 5'd1;
if (adc_cnt == 5'd0) // Check if read
adc_rd_pre <= CPLD_PS_SPI_SDI_25;
if (adc_cnt == 5'd15)
adc_rd <= adc_rd_pre;
end
end
always @(negedge CPLD_PS_SPI_CLK_25 or posedge adc_cs_b)
begin
if (adc_cs_b) begin
adc_sdio_t <= 1'b0;
end else begin
adc_sdio_t <= adc_rd;
end
end
// DAC 3-wire to 4-wire
reg [4:0] dac_cnt;
reg dac_rd_pre, dac_rd, dac_sdio_t;
always @(posedge CPLD_PS_SPI_CLK_25 or posedge dac_cs_b)
begin
if (dac_cs_b) begin
dac_cnt <= 5'd0;
dac_rd <= 1'b0;
dac_rd_pre <= 1'b0;
end else if (!dac_cs_b) begin
if (dac_cnt < 23)
dac_cnt <= dac_cnt + 5'd1;
if (dac_cnt == 5'd0) // Check if read
dac_rd_pre <= CPLD_PS_SPI_SDI_25;
if (dac_cnt == 5'd7)
dac_rd <= dac_rd_pre;
end
end
always @(negedge CPLD_PS_SPI_CLK_25 or posedge dac_cs_b)
begin
if (dac_cs_b) begin
dac_sdio_t <= 1'b0;
end else begin
dac_sdio_t <= dac_rd;
end
end
// multiplexed slave device SPI ports
wire phdac_sck, phdac_sdi;
wire clkdis_sck, adc_sck, dac_sck;
assign clkdis_sck = (clkdis_cs_b == 1'b0) ? CPLD_PS_SPI_CLK_25 : 1'b0;
assign CLKDIST_SPI_CS_L = clkdis_cs_b;
assign CLKDIST_SPI_SCLK = clkdis_sck;
assign adc_sck = !adc_cs_b ? CPLD_PS_SPI_CLK_25 : 1'b0;
assign dac_sck = !dac_cs_b ? CPLD_PS_SPI_CLK_25 : 1'b0;
assign ADC_SPI_CS_L_18 = adc_cs_b;
assign ADC_SPI_SCLK_18 = adc_sck;
assign DAC_SPI_CS_L_18 = dac_cs_b;
assign DAC_SPI_SCLK_18 = dac_sck;
assign CLKDIST_SPI_SDIO = (!clkdis_sdio_t && !clkdis_cs_b) ? CPLD_PS_SPI_SDI_25 : 1'bz ;
assign ADC_SPI_SDIO_18 = (!adc_sdio_t && !adc_cs_b) ? CPLD_PS_SPI_SDI_25 : 1'bz ;
assign DAC_SPI_SDIO_18 = (!dac_sdio_t && !dac_cs_b) ? CPLD_PS_SPI_SDI_25 : 1'bz ;
always @(*)
begin
CPLD_PS_SPI_SDO_25 = 1'b1;
case ({cpld_ps_cs_b, clkdis_cs_b, adc_cs_b, dac_cs_b})
4'b0111: begin
case (cpld_ps_spi_addr[6:5])
PS_CPLD_REGS : CPLD_PS_SPI_SDO_25 = cpld_ps_spi_sdo;
GAIN_TABLE_RX: CPLD_PS_SPI_SDO_25 = rx_gain_load_miso;
GAIN_TABLE_TX: CPLD_PS_SPI_SDO_25 = tx_gain_load_miso;
GAIN_TABLE_LO: CPLD_PS_SPI_SDO_25 = 1'b1;
endcase
end
4'b1011: CPLD_PS_SPI_SDO_25 = CLKDIST_SPI_SDIO;
4'b1101: CPLD_PS_SPI_SDO_25 = ADC_SPI_SDIO_18;
4'b1110: CPLD_PS_SPI_SDO_25 = DAC_SPI_SDIO_18;
default: ;
endcase
end
// note: no readback from PHDAC
assign phdac_sck = (phdac_cs_b == 1'b0) ? CPLD_PS_SPI_CLK_25 : 1'b0;
assign phdac_sdi = (phdac_cs_b == 1'b0) ? CPLD_PS_SPI_SDI_25 : 1'b1;
assign PHDAC_SPI_SCLK = phdac_sck;
assign PHDAC_SPI_CS_L = phdac_cs_b;
assign PHDAC_SPI_SDI = phdac_sdi;
/* PL SPI */
// CPLD PL SPI format (left-most bit first):
// {table_sel[1:0], reg_addr[4:0], rnw, data[15:0]}
//TXLO, RXLO, LODIS, CPLD
localparam PLADDR_SCRATCH = 4'b0101; // scratchpad register
localparam PLADDR_RXBS = 4'b0110;
localparam PLADDR_TXBS = 4'b0111;
localparam PLADDR_RFCTRL = 4'b1000;
localparam PL_CPLD_REGS = 2'b00;
// CPLD PL registers
reg [15:0] rxbs = 'h0;
reg [15:0] txbs = 'h0;
reg [15:0] rfctrl = 'h0;
// register address on the falling edge of chip-select
wire txlo_cs_b = CPLD_PL_SPI_LE_18;
wire rxlo_cs_b = CPLD_PL_SPI_ADDR1_18;
wire lodis_cs_b = CPLD_PL_SPI_ADDR2_18;
wire cpld_pl_cs_b = CPLD_PL_SPI_ADDR0_18;
wire cpld_pl_spi_rnw;
wire [6:0] cpld_pl_spi_addr;
reg [7:0] cpld_pl_spi_cmd;
reg [15:0] cpld_pl_spi_rdata;
reg [14:0] cpld_pl_spi_wdata;
reg cpld_pl_spi_sdo;
reg [4:0] cpld_pl_cnt;
assign {cpld_pl_spi_addr, cpld_pl_spi_rnw} = cpld_pl_spi_cmd;
reg [15:0] pl_spad;
always @(posedge CPLD_PL_SPI_SCLK_18 or posedge cpld_pl_cs_b)
begin
if (cpld_pl_cs_b) begin
cpld_pl_cnt <= 5'd0;
end else if (!cpld_pl_cs_b) begin
if (cpld_pl_cnt < 8) begin // Address / command
cpld_pl_spi_cmd <= {cpld_pl_spi_cmd[6:0], CPLD_PL_SPI_SDI_18};
cpld_pl_cnt <= cpld_pl_cnt + 5'd1;
end else if (cpld_pl_cnt < 23) begin // Shift in write data
cpld_pl_spi_wdata <= {cpld_pl_spi_wdata[13:0], CPLD_PL_SPI_SDI_18};
cpld_pl_cnt <= cpld_pl_cnt + 5'd1;
end else if (!cpld_pl_spi_rnw && cpld_pl_cnt == 23 && cpld_pl_spi_addr[6:5] == PL_CPLD_REGS) begin // Write
case (cpld_pl_spi_addr[3:0])
PLADDR_SCRATCH: pl_spad <= {cpld_pl_spi_wdata, CPLD_PL_SPI_SDI_18};
PLADDR_RXBS: rxbs <= {cpld_pl_spi_wdata, CPLD_PL_SPI_SDI_18};
PLADDR_TXBS: txbs <= {cpld_pl_spi_wdata, CPLD_PL_SPI_SDI_18};
PLADDR_RFCTRL: rfctrl <= {cpld_pl_spi_wdata, CPLD_PL_SPI_SDI_18};
endcase
end
if (cpld_pl_cnt == 7) begin // Set up read one cycle earlier
case (cpld_pl_spi_cmd[3:0])
PLADDR_SCRATCH: cpld_pl_spi_rdata <= pl_spad;
PLADDR_RXBS: cpld_pl_spi_rdata <= rxbs;
PLADDR_TXBS: cpld_pl_spi_rdata <= txbs;
PLADDR_RFCTRL: cpld_pl_spi_rdata <= rfctrl;
endcase
end else begin
cpld_pl_spi_rdata <= {cpld_pl_spi_rdata[14:0], 1'b1};
end
end
end
always @(negedge CPLD_PL_SPI_SCLK_18)
begin
cpld_pl_spi_sdo <= cpld_pl_spi_rdata[15]; // Shift out on negative edge
end
// multiplexed slave device SPI ports, names aliased to protect the innocent
wire lo_sck, lodis_sck;
wire lo_sdi, lodis_sdi;
// Note: lo_sck and lo_sdi -> fan out to both rxlo and txlo synths
assign { LO_TX_CS_L, LO_RX_CS_L } = { txlo_cs_b, rxlo_cs_b};
assign LO_SPI_SCLK = lo_sck;
assign LO_SPI_SDI = lo_sdi;
assign LODIST_Bd_SPI_CS_L = lodis_cs_b;
assign LODIST_Bd_SPI_SDI = lodis_sdi;
assign LODIST_Bd_SPI_SCLK = lodis_sck;
assign lodis_sck = !lodis_cs_b ? CPLD_PL_SPI_SCLK_18 : 1'b0;
assign lodis_sdi = !lodis_cs_b ? CPLD_PL_SPI_SDI_18 : 1'b1;
assign { lo_sck, lo_sdi } = (!txlo_cs_b | !rxlo_cs_b) ? {CPLD_PL_SPI_SCLK_18,CPLD_PL_SPI_SDI_18} : 2'b01;
always @(*)
begin
CPLD_PL_SPI_SDO_18 = 1'bz;
case ({cpld_pl_cs_b, txlo_cs_b, rxlo_cs_b})
3'b110: CPLD_PL_SPI_SDO_18 = LOSYNTH_RX_MUXOUT;
3'b101: CPLD_PL_SPI_SDO_18 = LOSYNTH_TX_MUXOUT;
3'b011: begin
case (cpld_pl_spi_addr[6:5])
PL_CPLD_REGS : CPLD_PL_SPI_SDO_18 = cpld_pl_spi_sdo;
GAIN_TABLE_RX: CPLD_PL_SPI_SDO_18 = rx_gain_ctrl_miso;
GAIN_TABLE_TX: CPLD_PL_SPI_SDO_18 = tx_gain_ctrl_miso;
GAIN_TABLE_LO: CPLD_PL_SPI_SDO_18 = lo_gain_ctrl_miso;
endcase
end
default: ;
endcase
end
assign rx_gain_ctrl_tbl_sel = rxbs[12];
assign { Rx_Sw6_Ctrl_2,
Rx_Sw6_Ctrl_1,
Rx_Sw4_Ctrl_4,
Rx_Sw4_Ctrl_3,
Rx_Sw4_Ctrl_2,
Rx_Sw4_Ctrl_1,
Rx_Sw3_Ctrl_2,
Rx_Sw3_Ctrl_1,
Rx_Sw2_Ctrl,
Rx_Sw1_Ctrl_2,
Rx_Sw1_Ctrl_1 } = { rxbs[11:1] };
assign tx_gain_ctrl_tbl_sel = txbs[12];
assign { Tx_Sw5_Ctrl_2,
Tx_Sw5_Ctrl_1,
Tx_Sw3_Ctrl_4,
Tx_Sw3_Ctrl_3,
Tx_Sw3_Ctrl_2,
Tx_Sw3_Ctrl_1,
Tx_Sw2_Ctrl_2,
Tx_Sw2_Ctrl_1} = { txbs[11:4] };
// Terminate TX when idle
assign {Tx_Sw1_Ctrl_2, Tx_Sw1_Ctrl_1} = CPLD_ATR_TX_18 ? txbs[3:2] : TX_SW1_TERM;
assign { Rx_LO_Filter_Sw_2,
Rx_LO_Filter_Sw_1,
Tx_LO_Filter_Sw_2,
Tx_LO_Filter_Sw_1,
Rx_Demod_ADJ_1,
Rx_Demod_ADJ_2,
Rx_LO_Input_Select } = rfctrl[15:9];
assign { Rx_HB_LB_Select,
Tx_LO_Input_Select } = rfctrl[7:6];
assign { Tx_HB_LB_Select,
Cal_iso_Sw_Ctrl }
= { rfctrl[4:3] };
// RX Gain Table
wire [4:0] rx_dsa;
rhodium_gain_ctrl #(
.TABLE_NUM(GAIN_TABLE_RX)
) rx_gain_table (
.load_table_sel(rx_gain_load_tbl_sel),
.load_sck(CPLD_PS_SPI_CLK_25),
.load_csb(cpld_ps_cs_b),
.load_mosi(CPLD_PS_SPI_SDI_25),
.load_miso(rx_gain_load_miso),
.ctrl_table_sel(rx_gain_ctrl_tbl_sel),
.ctrl_sck(CPLD_PL_SPI_SCLK_18),
.ctrl_csb(cpld_pl_cs_b),
.ctrl_mosi(CPLD_PL_SPI_SDI_18),
.ctrl_miso(rx_gain_ctrl_miso),
.dsa(rx_dsa),
.dsa1_le(Rx_DSA1_LE),
.dsa2_le(Rx_DSA2_LE)
);
// TX Gain Table
wire [4:0] tx_dsa;
rhodium_gain_ctrl #(
.TABLE_NUM(GAIN_TABLE_TX)
) tx_gain_table (
.load_table_sel(tx_gain_load_tbl_sel),
.load_sck(CPLD_PS_SPI_CLK_25),
.load_csb(cpld_ps_cs_b),
.load_mosi(CPLD_PS_SPI_SDI_25),
.load_miso(tx_gain_load_miso),
.ctrl_table_sel(tx_gain_ctrl_tbl_sel),
.ctrl_sck(CPLD_PL_SPI_SCLK_18),
.ctrl_csb(cpld_pl_cs_b),
.ctrl_mosi(CPLD_PL_SPI_SDI_18),
.ctrl_miso(tx_gain_ctrl_miso),
.dsa(tx_dsa),
.dsa1_le(Tx_DSA1_LE),
.dsa2_le(Tx_DSA2_LE)
);
// LO Gain Table
wire [4:0] lo_dsa;
rhodium_lo_gain #(
.TABLE_NUM(GAIN_TABLE_LO)
) lo_gain_table (
.ctrl_sck(CPLD_PL_SPI_SCLK_18),
.ctrl_csb(cpld_pl_cs_b),
.ctrl_mosi(CPLD_PL_SPI_SDI_18),
.ctrl_miso(lo_gain_ctrl_miso),
.dsa(lo_dsa),
.dsa1_le(RxLO_DSA_LE),
.dsa2_le(TxLO_DSA_LE)
);
// Rx data shared by DSA1, DSA2
assign { Rx_DSA_C16, Rx_DSA_C8, Rx_DSA_C4, Rx_DSA_C2, Rx_DSA_C1 } = rx_dsa;
// Tx data shared by DSA1, DSA2
assign { Tx_DSA_C16, Tx_DSA_C8, Tx_DSA_C4, Tx_DSA_C2, Tx_DSA_C1 } = tx_dsa;
// data shared by both tx and rx lo DSAs
assign { LO_DSA_C16, LO_DSA_C8, LO_DSA_C4, LO_DSA_C2, LO_DSA_C1 } = lo_dsa;
endmodule
`default_nettype wire