def __init__(self, tx_): try: df = tx_.vga_characteristics y = pd.unique(df.mag) x = pd.unique(df.gain_control) z = [] # Measurements were taken post_vga post_vga_gain = ut.db2lin(tx_.pa_driver_amp_gain_db + \ tx_.saw_filter_gain_db + \ tx_.pa_gain_db + \ tx_.bi_d_coupler_gain_db) for mag in y: f_y = [] f_xy = interp1d( df[df.mag == mag]['gain_control'].get_values(), df[df.mag == mag]['output_voltage'].get_values(), fill_value='extrapolate') for gc in x: val = f_xy(gc) / post_vga_gain f_y.append(val) z.append(f_y) except: print("Error initializing VGA") x = [0] y = [0] z = [0] self.vga_function = interp2d(x, y, z)
def __init__(self, reflection_loss_db=-10.0, reflection_phase=0.0): # self.reflection_loss_db = reflection_loss_db = -10.0 # self.reflection_phase = reflection_phase = 0.0 print(reflection_phase) self.reflection_gain_ = ut.db2lin(reflection_loss_db) * cmath.exp( 1j * reflection_phase) self.in_ = [] self.out_ = []
def compute_thermal_noise_densities(self, temp): n0_incident = 10*np.log10((consts.Boltzmann * consts.convert_temperature(float(temp), 'C', 'K')) / 1e-3) print(n0_incident) n0_rf = n0_incident + self.rx_attrib_.nf_rf_path print(n0_rf) n0_rf_gain = n0_rf + 20*np.log10(self.pre_cc_return_path_gain_ * self.post_cc_rf_gain_) print(n0_rf_gain) n0_rf_lin = (10 ** (n0_rf_gain/10)) * 1e-3 print(n0_rf_lin) spectral_density_rf = np.sqrt(n0_rf_lin * self.common_attrib_.impedance_) * 1e9 print(spectral_density_rf) spectral_density_demod = spectral_density_rf * ut.db2lin(self.rx_attrib_.rf_demod_gain_db_) print(spectral_density_demod) spectral_density_filter1_input = np.sqrt((spectral_density_demod ** 2) + (self.rx_attrib_.filter1_psd_ ** 2)) spectral_density_preamp = self.rx_attrib_.preamp_psd_ * ut.db2lin(self.rx_attrib_.preamp_gain_db_) spectral_density_filter2 = np.sqrt((spectral_density_preamp ** 2) + (self.rx_attrib_.filter2_psd_ ** 2)) * \ ut.db2lin(self.rx_attrib_.filter2_gain_db_) spectral_density_driver = np.sqrt((spectral_density_filter2 ** 2) + (self.rx_attrib_.driver_psd_ ** 2)) * \ ut.db2lin(self.rx_attrib_.driver_gain_db_) spectral_density_rx_adc = np.sqrt((spectral_density_driver ** 2) + (self.rx_attrib_.adc_psd_ ** 2)) * \ ut.db2lin(self.rx_attrib_.adc_gain_db_) self.filter1_input_noise_spectral_density = spectral_density_filter1_input self.rx_adc_noise_spectral_density = spectral_density_rx_adc print('n0_incident: ' + str(n0_incident)) print('n0_rf: ' + str(n0_rf)) print('RF Gain: ' + str(20 * np.log10(self.pre_cc_return_path_gain_ * self.post_cc_rf_gain_))) print('n0_rf_gain: ' + str(n0_rf_gain)) print('Spectral Density at RF: ' + str(spectral_density_rf)) print('Spectral Density at Demod: ' + str(spectral_density_demod)) print('Spectral Density at Filter1 Input: ' + str(spectral_density_filter1_input)) print('Spectral Density at Preamp: ' + str(spectral_density_preamp)) print('Spectral Density at Filter2: ' + str(spectral_density_filter2)) print('Spectral Density at Driver: ' + str(spectral_density_driver)) print('Spectral Density at ADC: ' + str(spectral_density_rx_adc))
def compute_combined_gains(self): forward_path_gain_db_ = self.common_attrib_.coupler_il_gain_db_ + self.common_attrib_.rf_mux_gain_db_ self.forward_path_gain_ = ut.db2lin(forward_path_gain_db_) pre_cc_return_path_gain_db = self.common_attrib_.rf_mux_gain_db_ + self.common_attrib_.coupler_gain_db_ + \ self.rx_attrib_.pre_cc_pad_gain_db_ + self.rx_attrib_.pre_cc_spdt1_gain_db_ + \ self.rx_attrib_.rx_phase_shift_gain_db_ + self.rx_attrib_.pre_cc_spdt2_gain_db_ self.pre_cc_return_path_gain_ = ut.db2lin(pre_cc_return_path_gain_db) cc_path_gain_db = self.common_attrib_.coupler_gain_db_ + self.rx_attrib_.quadrature_hybrid1_gain_db_ + \ self.rx_attrib_.coarse_cc_attenuation_gain_db_ + \ self.rx_attrib_.fine_cc_attenuation_gain_db_ + \ self.rx_attrib_.quadrant_select_switch_gain_db_ + \ self.rx_attrib_.quadrature_hybrid2_gain_db_ self.cc_path_gain_ = ut.db2lin(cc_path_gain_db) self.cc_combiner_gain_ = ut.db2lin(self.rx_attrib_.cc_combiner_gain_db_) post_cc_rf_gain_db = self.rx_attrib_.post_cc_spdt1_gain_db_ + self.rx_attrib_.post_cc_spdt2_gain_db_ + \ self.rx_attrib_.pre_lna_hpf_gain_db_ + self.rx_attrib_.lna_gain_db_ + \ self.rx_attrib_.post_lna_pad_gain_db_ + self.rx_attrib_.rf_demod_gain_db_ if self.rx_attrib_.add_atten_pad_: post_cc_rf_gain_db += self.rx_attrib_.post_cc_pad_gain_db_ post_demod_aux_adc_gain_db = self.rx_attrib_.filter1_gain_db_ post_demod_rx_adc_gain_db = self.rx_attrib_.filter1_gain_db_ + self.rx_attrib_.preamp_gain_db_ + \ self.rx_attrib_.filter2_gain_db_ + self.rx_attrib_.driver_gain_db_ + \ self.rx_attrib_.adc_gain_db_ self.post_cc_rf_gain_ = ut.db2lin(post_cc_rf_gain_db) self.post_demod_aux_adc_gain_ = ut.db2lin(post_demod_aux_adc_gain_db) self.post_demod_rx_adc_gain_ = ut.db2lin(post_demod_rx_adc_gain_db) #Tx Path Gains post_modulator_gain_db = self.tx_attrib_.pa_driver_amp_gain_db + self.tx_attrib_.saw_filter_gain_db self.coupler_gain = ut.db2lin(self.tx_attrib_.bi_d_coupler_gain_db) self.tx_post_modulator_gain = ut.db2lin(post_modulator_gain_db) self.tx_pdet_path_gain = self.tx_attrib_.rf_pdet_out_gain self.tx_antenna_gain_dB = self.tx_attrib_.antenna_gain_db
def calculate_ideal(self, refl, cw): rx = refl * self.pre_cc_return_path_gain_ self.rx_.append(rx) db_prec = 0.0625 db_clip_max = 31.9375 solution_i = abs(rx.real) / (np.abs(self.cw_[-1]) * self.cc_path_gain_) solution_q = abs(rx.imag) / (np.abs(self.cw_[-1]) * self.cc_path_gain_) if np.sign(rx.real) == 0.0: sign_i = 1.0 else: sign_i = np.sign(rx.real) if np.sign(rx.imag) == 0.0: sign_q = 1.0 else: sign_q = np.sign(rx.imag) if solution_i <= 1e-15: solution_i_db = db_clip_max solution_q_db = np.clip(-1 * ut.lin2db(solution_q), db_prec, db_clip_max) ideal_i_db = np.round(solution_i_db / db_prec) * db_prec ideal_q_db = np.round(solution_q_db / db_prec) * db_prec atten_i_lin = sign_i * ut.db2lin(-ideal_i_db) atten_q_lin = sign_q * ut.db2lin(-ideal_q_db) elif solution_q <= 1e-15: solution_i_db = np.clip(-1 * ut.lin2db(solution_i), db_prec, db_clip_max) solution_q_db = db_clip_max ideal_i_db = np.round(solution_i_db / db_prec) * db_prec ideal_q_db = np.round(solution_q_db / db_prec) * db_prec atten_i_lin = sign_i * ut.db2lin(-ideal_i_db) atten_q_lin = sign_q * ut.db2lin(-ideal_q_db) else: solution_i_db = np.clip(-1 * ut.lin2db(solution_i), db_prec, db_clip_max) solution_q_db = np.clip(-1 * ut.lin2db(solution_q), db_prec, db_clip_max) ideal_i_db = np.round(solution_i_db / db_prec) * db_prec ideal_q_db = np.round(solution_q_db / db_prec) * db_prec atten_i_lin = sign_i * ut.db2lin(-ideal_i_db) atten_q_lin = sign_q * ut.db2lin(-ideal_q_db) cc = ((np.abs(cw) * atten_i_lin) + (1j * (np.abs(cw) * atten_q_lin))) * self.cc_path_gain_ combined = (cc - rx) * self.cc_combiner_gain_ out = combined return sign_i * ideal_i_db, sign_q * ideal_q_db, out
def __init__(self, attrib=ReaderAttributes(), impairments=ReaderImpairments()): # Save off incoming attribute list self.sim_ctrl_ = attrib.sim_ctrl_ self.common_attrib_ = attrib.common_ self.rx_attrib_ = attrib.rx_ self.tx_attrib_ = attrib.tx_ # instantiate sub-modules #TODO: SETS UP CARRIER PHASOR, LO self.carrier_phasor = np.complex(1.0, 0.0) self.lo = LocalOscillator(self.common_attrib_.randomize_lo_initial_phase, self.rx_attrib_.phase_noise_freq_hz, self.rx_attrib_.phase_noise_dbc, self.rx_attrib_.fs_) self.tx_modulator_ = Modulator(1.0) rf_demod_gain = ut.db2lin(self.rx_attrib_.rf_demod_gain_db_) self.rx_demodulator_ = Modulator(rf_demod_gain) self.filter1_input_thermal_noise = Awgn() self.rx_adc_thermal_noise = Awgn() self.filter1 = AnalogFilter(self.rx_attrib_.filter1_order, self.rx_attrib_.filter1_passband_ripple, self.rx_attrib_.fs_, self.rx_attrib_.filter1_bw) # Set Tx amplitude self.tx_amp_ = ut.dbm2amp(attrib.tx_.tx_pwr_dbm_) * math.sqrt(attrib.common_.impedance_) # Compute combined path gains self.forward_path_gain_ = 1.0 self.pre_cc_return_path_gain_ = 1.0 self.cc_path_gain_ = 1.0 self.cc_combiner_gain_ = 1.0 self.post_cc_rf_gain_ = 1.0 self.post_demod_aux_adc_gain_ = 1.0 self.post_demod_rx_adc_gain_ = 1.0 self.tx_post_modulator_gain = 1.0 self.tx_pdet_path_gain = 1.0 self.tx_coupler_gain = 1.0 self.compute_combined_gains() self.filter1_input_noise_spectral_density = 0.0 self.rx_adc_noise_spectral_density = 0.0 self.compute_thermal_noise_densities(impairments.rx.temperature) self.filter1_input_thermal_noise.set_noise_spectral_density(self.filter1_input_noise_spectral_density, self.rx_attrib_.fs_) self.rx_adc_thermal_noise.set_noise_spectral_density(self.rx_adc_noise_spectral_density, self.rx_attrib_.fs_) # Carrier frequency self.fc_ = attrib.rx_.fc_/attrib.rx_.fs_ # time self.cw_sample_ = 0 self.time_step_ = 1/attrib.rx_.fs_ self.time_ = 0.0 # signals saved for debugging and analysis self.bb_tx_cw = [] self.cw_ = [] self.rx_ = [] self.cc_ = [] self.combined_ = [] self.demod_out_ = [] self.filter1_in_ = [] self.filter1_out_ = [] self.aux_adc_out_ = [] self.aux_adc_out_with_noise_ = [] self.rx_adc_out_ = [] self.rx_adc_out_with_noise_ = [] self.bb_ = [] self.tx_pwr = [] self.tx_pwr_sampled = [] self.pa_voltage_target = -1 #Tx Path Components self.tx_dac_i = Dac(bits=attrib.tx_.tx_dac_num_bits, fs_output_V=attrib.tx_.tx_dac_voltage_range) self.tx_dac_q = Dac(bits=attrib.tx_.tx_dac_num_bits, fs_output_V=attrib.tx_.tx_dac_voltage_range) self.vga = Vga(attrib.tx_) self.pa = PowerAmplifier() self.pdet = Pdet() self.tx_aux_dac_lo = Dac(bits=attrib.tx_.aux_dac_num_bits, fs_output_V=attrib.tx_.aux_dac_voltage_range) self.tx_aux_dac_hi = Dac(bits=attrib.tx_.aux_dac_num_bits, fs_output_V=attrib.tx_.aux_dac_voltage_range) self.pdet_out = 0 self.output_impedance = attrib.common_.impedance_ self.analog_settling = ReaderRfAnalogLoopSettling(tx_settling_time_us=attrib.tx_.tx_settling_time_us) self.tx_ts = 1.0/self.rx_attrib_.fs_ self.curr_step_time_s = 0
def __init__(self, gain_db=29): ''' Initialize PA with 29dB of default gain ''' self.pa_bias = 0 self.gain = ut.db2lin(gain_db)