1/////////////////////////////////////////////////////////////////// 2// 3// Copyright 2018 Ettus Research, A National Instruments Company 4// 5// SPDX-License-Identifier: LGPL-3.0-or-later 6// 7// Module: rhodium_lo_gain 8// Description: 9// LO Gain controller for Rhodium 10// Implements a gain index register (not a table) 11// 12// Provides 1 SPI slave: 13// The "ctrl" slave takes in a gain index and drives the DSA with that 14// value. 15// The SPI formats are provided below. 16////////////////////////////////////////////////////////////////////// 17 18`default_nettype none 19 20/** 21* SPI DATA FORMAT (left-most bit is first) 22* CTRL 23* M {table_sel[1:0], rsvd, gain[4:0], rsvd[1:0], wr_dsa1, ------rsvd[5:0], wr_dsa2, ----rsvd[5:0] 24* S {-------------------------------, --------------rsvd[3:0], gain1[4:0], -rsvd[1:0], gain2[4:0]} 25*/ 26module rhodium_lo_gain #( 27 parameter TABLE_NUM = 2'b01 28) ( 29 input wire ctrl_sck, 30 input wire ctrl_csb, 31 input wire ctrl_mosi, 32 output reg ctrl_miso, 33 output wire [4:0] dsa, 34 output reg dsa1_le, 35 output reg dsa2_le 36); 37 38localparam CNT_GAIN1_DRIVE = 10, 39 CNT_DSA1_LE_RISE = 11, 40 CNT_DSA1_LE_FALL = 14, 41 CNT_GAIN1_RELEASE = 17; 42localparam CNT_GAIN2_DRIVE = 17, 43 CNT_DSA2_LE_RISE = 18, 44 CNT_DSA2_LE_FALL = 21, 45 CNT_GAIN2_RELEASE = 24; 46 47reg [4:0] ctrl_bit_cnt; 48reg [1:0] ctrl_tbl; 49reg [5:0] ctrl_index; 50reg [5:0] gain1, gain2; 51reg gain1_t; 52reg gain2_t; 53 54assign dsa = (!gain1_t | !gain2_t) ? ctrl_index[4:0] : 5'b11111; 55 56// Cycle counter for where we are in protocol and shift register for input 57// Also controls timing of DSAs' latch enable signals 58always @ (posedge ctrl_sck or posedge ctrl_csb) 59begin 60 if (ctrl_csb) begin 61 ctrl_bit_cnt <= 5'd0; 62 dsa1_le <= 1'b0; 63 dsa2_le <= 1'b0; 64 gain1_t <= 1'b1; 65 gain2_t <= 1'b1; 66 end else if (!ctrl_csb) begin 67 if (ctrl_bit_cnt < 23) begin 68 ctrl_bit_cnt <= ctrl_bit_cnt + 5'd1; 69 end 70 71 if (ctrl_bit_cnt < 8) begin 72 {ctrl_tbl, ctrl_index} <= {ctrl_tbl[0], ctrl_index, ctrl_mosi}; 73 end 74 75 if (ctrl_tbl == TABLE_NUM) begin 76 if ((ctrl_bit_cnt == CNT_GAIN1_DRIVE) && (ctrl_mosi)) begin 77 gain1 <= ctrl_index; 78 gain1_t <= 1'b0; 79 end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA1_LE_RISE)) begin 80 dsa1_le <= 1'b1; 81 end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA1_LE_FALL)) begin 82 dsa1_le <= 1'b0; 83 end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_GAIN1_RELEASE)) begin 84 gain1_t <= 1'b1; 85 end 86 87 if ((ctrl_bit_cnt == CNT_GAIN2_DRIVE) && (ctrl_mosi)) begin 88 gain2 <= ctrl_index; 89 gain2_t <= 1'b0; 90 end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA2_LE_RISE)) begin 91 dsa2_le <= 1'b1; 92 end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA2_LE_FALL)) begin 93 dsa2_le <= 1'b0; 94 end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_GAIN2_RELEASE)) begin 95 gain2_t <= 1'b1; 96 end 97 end 98 end 99end 100 101// SPI readback for ctrl bus, based on current bit count 102always @ (negedge ctrl_sck) 103begin 104 case (ctrl_bit_cnt) // Shift out on neg edge 105 11: ctrl_miso <= gain1[5]; 106 12: ctrl_miso <= gain1[4]; 107 13: ctrl_miso <= gain1[3]; 108 14: ctrl_miso <= gain1[2]; 109 15: ctrl_miso <= gain1[1]; 110 16: ctrl_miso <= gain1[0]; 111 18: ctrl_miso <= gain2[5]; 112 19: ctrl_miso <= gain2[4]; 113 20: ctrl_miso <= gain2[3]; 114 21: ctrl_miso <= gain2[2]; 115 22: ctrl_miso <= gain2[1]; 116 23: ctrl_miso <= gain2[0]; 117 default: ctrl_miso <= 1'b0; 118 endcase 119end 120 121 122endmodule // rhodium_lo_gain 123`default_nettype wire 124 125