diff options
Diffstat (limited to 'fpga/usrp3/top/n3xx/dboards/rh/cpld/rhodium_top.v')
-rw-r--r-- | fpga/usrp3/top/n3xx/dboards/rh/cpld/rhodium_top.v | 605 |
1 files changed, 605 insertions, 0 deletions
diff --git a/fpga/usrp3/top/n3xx/dboards/rh/cpld/rhodium_top.v b/fpga/usrp3/top/n3xx/dboards/rh/cpld/rhodium_top.v new file mode 100644 index 000000000..1d0d640da --- /dev/null +++ b/fpga/usrp3/top/n3xx/dboards/rh/cpld/rhodium_top.v @@ -0,0 +1,605 @@ +/////////////////////////////////////////////////////////////////// +// +// 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 + |