diff --git a/README.md b/README.md index 5d441c0..232d0b9 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,15 @@ app.py ----服务器的主程序 ## 更新日志 +* 2021年3月24号,前端更新 + + * 新增:多种仿真模式下的数据显示,主要解决了在ac仿真模式下对数轴的问题和两个绘图框的问题 + * 新增:解决了simulator窗口和show_result窗口tab功能混淆的问题 + * dc仿真展示 + * ![avatar](./doc/schematic8.png) + * ac仿真展示 + * ![avatar](./doc/schematic9.png) + * * 2021年3月23号,前端更新 * 新增:多种仿真模式下的数据显示 @@ -72,6 +81,7 @@ app.py ----服务器的主程序 * 新增:仿真结果数据显示,成功将仿真得到的节点电压绘制出来。 * todo:绘制仿真结果时增加用户配置项目,可以进行选择性绘图。 + * transient仿真结果展示 * ![avatar](./doc/schematic7.png) * 2021年3月18号,后端更新 diff --git a/b3v3_1check.log b/b3v3_1check.log index 0b93d3a..2aaa01d 100644 --- a/b3v3_1check.log +++ b/b3v3_1check.log @@ -1,3 +1,3 @@ BSIM3V3.1 Parameter Check -Model = cmosp_180nm +Model = cmosn_180nm W = 2e-05, L = 1e-06 diff --git a/doc/schematic8.png b/doc/schematic8.png new file mode 100644 index 0000000..b746992 Binary files /dev/null and b/doc/schematic8.png differ diff --git a/doc/schematic9.png b/doc/schematic9.png new file mode 100644 index 0000000..3a9bd11 Binary files /dev/null and b/doc/schematic9.png differ diff --git a/handler/__pycache__/sim_data_container.cpython-36.pyc b/handler/__pycache__/sim_data_container.cpython-36.pyc index 7629dba..76289d8 100644 Binary files a/handler/__pycache__/sim_data_container.cpython-36.pyc and b/handler/__pycache__/sim_data_container.cpython-36.pyc differ diff --git a/handler/__pycache__/simulation.cpython-36.pyc b/handler/__pycache__/simulation.cpython-36.pyc index fbf2ad3..9664887 100644 Binary files a/handler/__pycache__/simulation.cpython-36.pyc and b/handler/__pycache__/simulation.cpython-36.pyc differ diff --git a/handler/__pycache__/spice.cpython-36.pyc b/handler/__pycache__/spice.cpython-36.pyc index aa64e2c..ae66e0c 100644 Binary files a/handler/__pycache__/spice.cpython-36.pyc and b/handler/__pycache__/spice.cpython-36.pyc differ diff --git a/handler/sim_data_container.py b/handler/sim_data_container.py index 57f2507..d4c4f98 100644 --- a/handler/sim_data_container.py +++ b/handler/sim_data_container.py @@ -1,4 +1,4 @@ - +import numpy as np class Sim_Data_Container : def __init__(self): @@ -15,7 +15,7 @@ class Sim_Data_Container : elif(simtype == 'dc'): self.parse_dc(analysis) elif(simtype == 'ac'): - pass + self.parse_ac(analysis) @@ -46,7 +46,7 @@ class Sim_Data_Container : result_dc = {} result_dc['sweep'] = [float(i) for i in analysis.sweep] result_dc['nodes_name'] = list(analysis.nodes.keys()) - nodes = {} + nodes = {} for i in result_dc['nodes_name'] : nodes[i] = [float(j) for j in analysis.nodes[i]] @@ -60,5 +60,40 @@ class Sim_Data_Container : self.result['dc'] = result_dc + + def parse_ac(self, analysis): + result_ac = {} + result_ac['frequency'] = [float(i) for i in analysis.frequency] + result_ac['nodes_name'] = list(analysis.nodes.keys()) + + nodes_gain = {} + nodes_phase = {} + for i in result_ac['nodes_name'] : + the_gain = 20*np.log10(np.absolute(analysis.nodes[i])) + the_phase = np.angle(analysis.nodes[i], deg=False) + # print(the_gain) + nodes_gain[i] = [float(j) for j in the_gain] + nodes_phase[i] = [float(j) for j in the_phase] + + result_ac['nodes_gain'] = nodes_gain + result_ac['nodes_phase'] = nodes_phase + # print(nodes_gain) + # print(nodes_phase) + + result_ac['branches_name'] = list(analysis.branches.keys()) + branches_gain = {} + branches_phase = {} + for i in result_ac['branches_name']: + the_gain = 20*np.log10(np.absolute(analysis.branches[i])) + the_phase = np.angle(analysis.branches[i], deg=False) + branches_gain[i] = [float(j) for j in the_gain] + branches_phase[i] = [float(j) for j in the_phase] + result_ac['branches_gain'] = branches_gain + result_ac['branches_phase'] = branches_phase + + + self.result['ac'] = result_ac + + def simulation_info_request(self, simtype): return self.result[simtype] diff --git a/handler/simulation.py b/handler/simulation.py index 410d4c6..d89ea54 100644 --- a/handler/simulation.py +++ b/handler/simulation.py @@ -51,12 +51,19 @@ class Simulator_CZ : exec("self.analysis = self.simulator.dc( {} )".format(the_args)) print("dc simulation finished !!!") - # print(self.analysis) - + return self.analysis elif(sim_type == 'ac' ): - pass + print("doing the ac simulation !!!") + self.analysis = self.simulator.ac( start_frequency = parameter['start_frequency'], + stop_frequency = parameter['stop_frequency'], + number_of_points = parameter['number_of_points'], + variation = parameter['variation']) + print("dc simulation finished !!!") + return self.analysis + + else: pass @@ -78,7 +85,10 @@ class Simulator_CZ : parameter["step"] = properties["step"] elif(sim_type == 'ac' ): - pass + parameter["start_frequency"] = self.unit_tran(properties["start_frequency"]) + parameter["stop_frequency"] = self.unit_tran(properties["stop_frequency"]) + parameter["number_of_points"] = int(properties["number_of_points"]) + parameter["variation"] = properties["variation"] return parameter @@ -112,19 +122,69 @@ class Simulator_CZ : elif the_unit in ['none','NONE','None']: return None + elif the_unit in ['ps','Ps','pS','PS']: + the_num = self.get_the_number(unit_num) + return u_ps(the_num) + + elif the_unit in ['ns','Ns','nS','NS']: + the_num = self.get_the_number(unit_num) + return u_ns(the_num) + elif the_unit in ['us','US','uS','Us']: - if(unit_num != []): - the_num = float(unit_num[0]) - else: - the_num = float(0) + the_num = self.get_the_number(unit_num) return u_us(the_num) - elif the_unit in ['ms','MS','mS','Ms']: - if(unit_num != []): - the_num = float(unit_num[0]) - else: - the_num = float(0) - return u_us(the_num) + elif the_unit in ['ms','mS']: + the_num = self.get_the_number(unit_num) + return u_ms(the_num) + + elif the_unit in ['s','S']: + the_num = self.get_the_number(unit_num) + return u_s(the_num) + + elif the_unit in ['ks','Ks','kS','KS']: + the_num = self.get_the_number(unit_num) + return u_ks(the_num) + + elif the_unit in ['Ms','MS']: + the_num = self.get_the_number(unit_num) + return u_Ms(the_num) + + + elif the_unit in ['hz','Hz','HZ']: + the_num = self.get_the_number(unit_num) + return u_Hz(the_num) + + elif the_unit in ['kHz','KHz','khz','Khz','kHZ','KHZ']: + the_num = self.get_the_number(unit_num) + return u_kHz(the_num) + + elif the_unit in ['MHz','Mhz','MHZ']: + the_num = self.get_the_number(unit_num) + return u_MHz(the_num) + + elif the_unit in ['gHz','GHz','ghz','Ghz','gHZ','GHZ']: + the_num = self.get_the_number(unit_num) + return u_GHz(the_num) + + elif the_unit in ['mHz','mhz','mHZ']: + the_num = self.get_the_number(unit_num) + return u_mHz(the_num) + + elif the_unit in ['uHz','UHz','uhz','Uhz','uHZ','UHZ']: + the_num = self.get_the_number(unit_num) + return u_uHz(the_num) + + elif the_unit in ['nHz','NHz','nhz','Nhz','nHZ','NHZ']: + the_num = self.get_the_number(unit_num) + return u_nHz(the_num) + + elif the_unit in ['pHz','PHz','phz','Phz','pHZ','PHZ']: + the_num = self.get_the_number(unit_num) + return u_pHz(the_num) + + + # 无单位时的情况 else: if(unit_num != []): @@ -134,4 +194,33 @@ class Simulator_CZ : return the_num + def get_the_number(self, the_unit_num): + if(the_unit_num != []): + the_num = float(the_unit_num[0]) + else: + the_num = float(0) + + return the_num + + +# 'u_A', 'u_Bq', 'u_C', 'u_Degree', 'u_F', 'u_GA', 'u_GBq', 'u_GC', 'u_GDegree', 'u_GF', 'u_GGy', 'u_GH', 'u_GHz', 'u_GJ', +# 'u_GK', 'u_GN', 'u_GOhm', 'u_GPa', 'u_GS', 'u_GSv', 'u_GV', 'u_GW', 'u_GWb', 'u_Gcd', 'u_Gkat', 'u_Glm', 'u_Glx', 'u_Gm', +# 'u_Gmol', 'u_Grad', 'u_Gs', 'u_Gsr', 'u_Gy', 'u_GΩ', 'u_H', 'u_Hz', 'u_J', 'u_K', 'u_MA', 'u_MBq', 'u_MC', 'u_MDegree', +# 'u_MF', 'u_MGy', 'u_MH', 'u_MHz', 'u_MJ', 'u_MK', 'u_MN', 'u_MOhm', 'u_MPa', 'u_MS', 'u_MSv', 'u_MV', 'u_MW', 'u_MWb', +# 'u_Mcd', 'u_Mkat', 'u_Mlm', 'u_Mlx', 'u_Mm', 'u_Mmol', 'u_Mrad', 'u_Ms', 'u_Msr', 'u_MΩ', 'u_N', 'u_Ohm', 'u_Pa', 'u_S', +# 'u_Sv', 'u_TA', 'u_TBq', 'u_TC', 'u_TDegree', 'u_TF', 'u_TGy', 'u_TH', 'u_THz', 'u_TJ', 'u_TK', 'u_TN', 'u_TOhm', 'u_TPa', +# 'u_TS', 'u_TSv', 'u_TV', 'u_TW', 'u_TWb', 'u_Tcd', 'u_Tkat', 'u_Tlm', 'u_Tlx', 'u_Tm', 'u_Tmol', 'u_Trad', 'u_Ts', 'u_Tsr', +# 'u_TΩ', 'u_V', 'u_W', 'u_Wb', 'u_cd', 'u_kA', 'u_kBq', 'u_kC', 'u_kDegree', 'u_kF', 'u_kGy', 'u_kH', 'u_kHz', 'u_kJ', 'u_kK', +# 'u_kN', 'u_kOhm', 'u_kPa', 'u_kS', 'u_kSv', 'u_kV', 'u_kW', 'u_kWb', 'u_kat', 'u_kcd', 'u_kkat', 'u_klm', 'u_klx', 'u_km', +# 'u_kmol', 'u_krad', 'u_ks', 'u_ksr', 'u_kΩ', 'u_lm', 'u_lx', 'u_m', 'u_mA', 'u_mBq', 'u_mC', 'u_mDegree', 'u_mF', 'u_mGy', +# 'u_mH', 'u_mHz', 'u_mJ', 'u_mK', 'u_mN', 'u_mOhm', 'u_mPa', 'u_mS', 'u_mSv', 'u_mV', 'u_mW', 'u_mWb', 'u_mcd', 'u_mkat', +# 'u_mlm', 'u_mlx', 'u_mm', 'u_mmol', 'u_mol', 'u_mrad', 'u_ms', 'u_msr', 'u_mΩ', 'u_nA', 'u_nBq', 'u_nC', 'u_nDegree', 'u_nF', +# 'u_nGy', 'u_nH', 'u_nHz', 'u_nJ', 'u_nK', 'u_nN', 'u_nOhm', 'u_nPa', 'u_nS', 'u_nSv', 'u_nV', 'u_nW', 'u_nWb', 'u_ncd', +# 'u_nkat', 'u_nlm', 'u_nlx', 'u_nm', 'u_nmol', 'u_nrad', 'u_ns', 'u_nsr', 'u_nΩ', 'u_pA', 'u_pBq', 'u_pC', 'u_pDegree', +# 'u_pF', 'u_pGy', 'u_pH', 'u_pHz', 'u_pJ', 'u_pK', 'u_pN', 'u_pOhm', 'u_pPa', 'u_pS', 'u_pSv', 'u_pV', 'u_pW', 'u_pWb', +# 'u_pcd', 'u_pkat', 'u_plm', 'u_plx', 'u_pm', 'u_pmol', 'u_prad', 'u_ps', 'u_psr', 'u_pΩ', 'u_rad', 'u_s', 'u_sr', 'u_uA', +# 'u_uBq', 'u_uC', 'u_uDegree', 'u_uF', 'u_uGy', 'u_uH', 'u_uHz', 'u_uJ', 'u_uK', 'u_uN', 'u_uOhm', 'u_uPa', 'u_uS', 'u_uSv', +# 'u_uV', 'u_uW', 'u_uWb', 'u_ucd', 'u_ukat', 'u_ulm', 'u_ulx', 'u_um', 'u_umol', 'u_urad', 'u_us', 'u_usr', 'u_Ω', 'u_μA', +# 'u_μBq', 'u_μC', 'u_μF', 'u_μGy', 'u_μH', 'u_μHz', 'u_μJ', 'u_μK', 'u_μN', 'u_μPa', 'u_μS', 'u_μSv', 'u_μV', 'u_μW', 'u_μWb', +# 'u_μcd', 'u_μkat', 'u_μlm', 'u_μlx', 'u_μm', 'u_μmol', 'u_μrad', 'u_μs', 'u_μsr', 'u_μΩ', \ No newline at end of file diff --git a/handler/spice.py b/handler/spice.py index 6876c79..7c4edbd 100644 --- a/handler/spice.py +++ b/handler/spice.py @@ -73,14 +73,14 @@ class SimulationInfoRequest_Handler(AuthBaseHandler): print(sim_type) sim_info = Container_SimResult.simulation_info_request(sim_type) - # sim_info = {'ab':1,'cd':2,'ef':'d2','hello':[1,2,3,4,5]} - print(sim_info) + + # print(sim_info) sim_info_json = json.dumps( sim_info ) - print('json transform ok !!') + # print('json transform ok !!') self.write( sim_info_json ) - print("send the simulation info request successfully!!!") + # print("send the simulation info request successfully!!!") # self.write(json_decode(sim_info)) # self.write("successful") diff --git a/static/spice/show_result2.js b/static/spice/show_result2.js index 17caed3..096352b 100644 --- a/static/spice/show_result2.js +++ b/static/spice/show_result2.js @@ -6,19 +6,17 @@ var SimResult = {} ; var Flag_Refresh = {"transient":false,"dc":false,"ac":false} ; var color_store = ["blue","brown","cyan","green","orange","pink","purple","red","whitesmoke","yellow"]; -// create a data source to hold data -// var the_source = new Bokeh.ColumnDataSource({ -// data: { x: [], y: [], color: [] } -// }); - -function openMode_Bokeh(evt, tabMode) { +function openMode(evt, tabMode, ducument_ID) { var i, tabcontent, tablinks; - tabcontent = document.getElementsByClassName("tabcontent"); + + var the_document = document.getElementById(ducument_ID); + + tabcontent = the_document.getElementsByClassName("tabcontent"); for (i = 0; i < tabcontent.length; i++) { tabcontent[i].style.display = "none"; } - tablinks = document.getElementsByClassName("tablinks"); + tablinks = the_document.getElementsByClassName("tablinks"); for (i = 0; i < tablinks.length; i++) { tablinks[i].className = tablinks[i].className.replace(" active", ""); } @@ -30,9 +28,9 @@ function plotPoint_tran() { if(Flag_Refresh['transient'] == true){ - the_source.data.x = []; - the_source.data.y = []; - the_source.data.color = []; + the_source['transient'].data.x = []; + the_source['transient'].data.y = []; + the_source['transient'].data.color = []; console.log("Flag_Refresh = true !"); @@ -41,11 +39,11 @@ function plotPoint_tran() { var the_x = SimResult['transient']["time"]; for(var i=0; i < the_nodes_name.length; i++){ var the_y = SimResult['transient']["nodes"][the_nodes_name[i]] ; - the_source.data.x.push(the_x); - the_source.data.y.push(the_y); - the_source.data.color.push(color_store[i%color_store.length]); + the_source['transient'].data.x.push(the_x); + the_source['transient'].data.y.push(the_y); + the_source['transient'].data.color.push(color_store[i%color_store.length]); } - the_source.change.emit(); + the_source['transient'].change.emit(); } else{ alert("The information has not been updated !!!"); @@ -55,9 +53,9 @@ function plotPoint_dc() { if(Flag_Refresh['dc'] == true){ - the_source.data.x = []; - the_source.data.y = []; - the_source.data.color = []; + the_source['dc'].data.x = []; + the_source['dc'].data.y = []; + the_source['dc'].data.color = []; console.log("Flag_Refresh = true !"); var the_nodes_name = SimResult['dc']["nodes_name"]; @@ -65,11 +63,11 @@ function plotPoint_dc() { var the_x = SimResult['dc']["sweep"]; for(var i=0; i < the_nodes_name.length; i++){ var the_y = SimResult['dc']["nodes"][the_nodes_name[i]] ; - the_source.data.x.push(the_x); - the_source.data.y.push(the_y); - the_source.data.color.push(color_store[i%color_store.length]); + the_source['dc'].data.x.push(the_x); + the_source['dc'].data.y.push(the_y); + the_source['dc'].data.color.push(color_store[i%color_store.length]); } - the_source.change.emit(); + the_source['dc'].change.emit(); } else{ alert("The information has not been updated !!!"); @@ -79,21 +77,30 @@ function plotPoint_ac() { if(Flag_Refresh['ac'] == true){ - the_source.data.x = []; - the_source.data.y = []; - the_source.data.color = []; + the_source['ac']["gain"].data.x = []; + the_source['ac']["gain"].data.y = []; + the_source['ac']["gain"].data.color = []; + + the_source['ac']["phase"].data.x = []; + the_source['ac']["phase"].data.y = []; + the_source['ac']["phase"].data.color = []; - console.log("Flag_Refresh = true !"); var the_nodes_name = SimResult['ac']["nodes_name"]; - var the_x = SimResult['ac']["fre"]; + var the_x = SimResult['ac']["frequency"]; for(var i=0; i < the_nodes_name.length; i++){ - var the_y = SimResult['ac']["nodes"][the_nodes_name[i]] ; - the_source.data.x.push(the_x); - the_source.data.y.push(the_y); - the_source.data.color.push(color_store[i%color_store.length]); + var the_gain = SimResult['ac']["nodes_gain"][the_nodes_name[i]] ; + var the_phase = SimResult['ac']["nodes_phase"][the_nodes_name[i]] ; + the_source['ac']["gain"].data.x.push(the_x); + the_source['ac']["gain"].data.y.push(the_gain); + the_source['ac']["gain"].data.color.push(color_store[i%color_store.length]); + + the_source['ac']["phase"].data.x.push(the_x); + the_source['ac']["phase"].data.y.push(the_phase); + the_source['ac']["phase"].data.color.push(color_store[i%color_store.length]); } - the_source.change.emit(); + the_source['ac']["gain"].change.emit(); + the_source['ac']["phase"].change.emit(); } else{ alert("The information has not been updated !!!"); @@ -117,8 +124,8 @@ function requestSimInfo(sim_type){ var sim_result ; data["sim_type"] = sim_type; - console.log(sim_type); - console.log(data); + // console.log(sim_type); + // console.log(data); $.ajax({ type: 'POST', @@ -133,7 +140,9 @@ function requestSimInfo(sim_type){ error: function(){ alert('ajax post failed !!!'); } - }); + }); + console.log(sim_result); + return sim_result ; }; @@ -146,7 +155,7 @@ function Callback_Refresh(sim_type){ // bokeh组件相关变量 -var bokeh_plot = [] ; +var bokeh_plot = {} ; var the_source = {} ; @@ -163,16 +172,28 @@ frame.append(div_node); for(var i=0; i