00001 // Build a two-stage low noise amplifier, and optimize the component values. 00002 00003 #include "supermix.h" 00004 00005 int main() 00006 { 00007 device::T = 4.2 * Kelvin; 00008 device::Z0 = 50. * Ohm; 00009 00010 // ========================================================================== 00011 // Building the circuit: 00012 00013 fhx13x t1, t2; // Field-effect transistors made by Fujitsu. 00014 t1.Ls.L = 0.05 * nHenry; // adjusting the source inductance values a bit... 00015 t2.Ls.L = 0.05 * nHenry; 00016 inductor lg1, lg2; // Gate tuning inductors. 00017 00018 resistor rd1, rd2; // Drain bias resistors. 00019 lg1.series(); 00020 lg1.series(); 00021 rd1.parallel(); 00022 rd2.parallel(); 00023 // The inductance and resistance values will be found by the optimizer 00024 00025 circuit amp; 00026 int input = amp.add_port(lg1, 1); 00027 amp.connect(lg1, 2, t1, 1); 00028 amp.connect(t1, 2, rd1, 1); 00029 amp.connect(rd1, 2, lg2, 1); 00030 amp.connect(lg2, 2, t2, 1); 00031 amp.connect(t2, 2, rd2, 1); 00032 int output = amp.add_port(rd2, 2); 00033 00034 // ========================================================================== 00035 // Setting up the error function for the optimization: 00036 00037 error_func ef; 00038 lg1.L = ef.vary( 1.0, 3.0, 20.0, nHenry ); 00039 lg2.L = ef.vary( 0.2, 1.0, 10.0, nHenry ); 00040 rd1.R = ef.vary( 30.0, 100.0, 500.0, Ohm ); 00041 rd2.R = ef.vary( 30.0, 100.0, 150.0, Ohm ); 00042 00043 sweeper gain_band, stability_band; 00044 00045 gain_band.sweep( device::f, 4.0*GHz, 8.0*GHz, 0.25*GHz ); 00046 stability_band.sweep( device::f, 0.1*GHz, 20.1*GHz, 0.50*GHz ); 00047 00048 // Optimize for stability. 00049 amp_k stb1_term(amp); 00050 amp_mag_delta stb2_term(amp); 00051 00052 // Keep the gain high. 00053 gain_dB gain_term(amp, input, output); 00054 gain_term.above(20.0); 00055 00056 // Optimize for flat gain. 00057 gain_dB flatness_term(amp, input, output); 00058 flatness_term.flat(); 00059 00060 // Optimize the output match. 00061 gain_dB out_match_term(amp, output, output); 00062 out_match_term.below(-15.0); 00063 00064 // Optimize the input match. 00065 gain_dB in_match_term(amp, input, input); 00066 in_match_term.below(-10.0); 00067 00068 // Optimize for low noise. 00069 input_tn noise_term(amp, input, output); 00070 noise_term.match(0.0); 00071 00072 ef.add_term( 10.0, stb1_term, stability_band ); 00073 ef.add_term( 10.0, stb2_term, stability_band ); 00074 ef.add_term( 1.5, gain_term, gain_band ); 00075 ef.add_term( 20.0, flatness_term, gain_band ); 00076 ef.add_term( 1.0, out_match_term, gain_band ); 00077 ef.add_term( 1.0, in_match_term, gain_band ); 00078 ef.add_term( 10.0, noise_term, gain_band ); 00079 00080 // ========================================================================== 00081 // Setting up the optimization algorithm: 00082 00083 powell opt(ef); 00084 opt.verbose(); 00085 opt.FTOL = 0.00001; 00086 00087 // ========================================================================== 00088 // Perform the optimization, displaying the resulting optimized values: 00089 00090 cout << endl << "2 stage cryogenic low-noise amplifier" << endl << endl; 00091 cout << "Starting optimization:" << endl << endl; 00092 00093 double error_val = opt.minimize(); 00094 00095 cout << endl << "Final error function value: " << error_val << endl ; 00096 cout << "Error function breakdown by term:" << endl; 00097 cout << ef.get_func_breakdown() << endl; 00098 00099 cout << "Final parameters are:" << endl; 00100 cout << "lg1(nH)" << " " << "lg2(nH)" << " " << "rd1(O) " << " " << "rd2(O)"; 00101 00102 ef.get_parms_user().show() ; 00103 00104 00105 // ========================================================================== 00106 // Now display the response of our amplifier using the optimized values: 00107 00108 cout << endl << "Response:" << endl << endl; 00109 cout << setw(8) << "Freq" << " " 00110 << setw(8) << "S21(dB)" << " " 00111 << setw(8) << "S22(dB)" << " " 00112 << setw(8) << "Tn(K)" << " " 00113 << setw(8) << "NF(dB)" << endl << endl; 00114 00115 ampdata response; 00116 00117 for(double freq = 1.0; freq <=12.0; freq += 0.5) 00118 { 00119 device::f = freq * GHz; 00120 response = amp.get_data(); 00121 00122 cout << fixed << setprecision(4) 00123 << setw(8) << freq << " " 00124 << setw(8) << response.SdB(output,input) << " " 00125 << setw(8) << response.SdB(output,output) << " " 00126 << setw(8) << response.tn(output,input)/Kelvin << " " 00127 << setw(8) << response.NF(output,input) << " "; 00128 00129 if(response.unconditionally_stable()) cout << "Unconditionally Stable"; 00130 00131 cout << endl; 00132 } 00133 00134 cout << endl; 00135 }
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7