def _construct_UI(self): """ Intitialize the UI with widgets for coefficient format and input and output quantization """ self.wdg_w_coeffs = UI_W_coeffs( self, label='Coefficient Format:', enabled=False, tip_WI='Number of integer bits - edit in the "b,a" tab', tip_WF='Number of fractional bits - edit in the "b,a" tab', WI=fb.fil[0]['fxqc']['QC']['WI'], WF=fb.fil[0]['fxqc']['QC']['WF']) self.wdg_q_coeffs = UI_Q_coeffs(self, enabled=False, cur_ov=fb.fil[0]['fxqc']['QC']['ovfl'], cur_q=fb.fil[0]['fxqc']['QC']['quant']) self.wdg_w_accu = UI_W( self, label='Accumulator Format <i>Q<sub>A </sub></i>:', WF=30) self.wdg_q_accu = UI_Q(self) #------------------------------------------------------------------------------ layVWdg = QVBoxLayout() layVWdg.setContentsMargins(0, 0, 0, 0) layVWdg.addWidget(self.wdg_w_coeffs) layVWdg.addWidget(self.wdg_q_coeffs) layVWdg.addWidget(self.wdg_w_accu) layVWdg.addWidget(self.wdg_q_accu) layVWdg.addStretch() self.setLayout(layVWdg)
def _construct_UI(self): """ Intitialize the UI with widgets for coefficient format and input and output quantization """ if not 'QA' in fb.fil[0]['fxqc']: fb.fil[0]['fxqc']['QA'] = {} set_dict_defaults(fb.fil[0]['fxqc']['QA'], {'WI':0, 'WF':30, 'W':32, 'ovfl':'wrap', 'quant':'floor'}) self.wdg_w_coeffs = UI_W(self, fb.fil[0]['fxqc']['QCB'], id='w_coeff', label='Coeff. Format <i>B<sub>I.F </sub></i>:', tip_WI='Number of integer bits - edit in the "b,a" tab', tip_WF='Number of fractional bits - edit in the "b,a" tab', WI = fb.fil[0]['fxqc']['QCB']['WI'], WF = fb.fil[0]['fxqc']['QCB']['WF']) # self.wdg_q_coeffs = UI_Q(self, fb.fil[0]['fxqc']['QCB'], # cur_ov=fb.fil[0]['fxqc']['QCB']['ovfl'], # cur_q=fb.fil[0]['fxqc']['QCB']['quant']) # self.wdg_q_coeffs.sig_tx.connect(self.update_q_coeff) self.wdg_w_accu = UI_W(self, fb.fil[0]['fxqc']['QA'], label='', id='w_accu', fractional=True, combo_visible=True) self.wdg_q_accu = UI_Q(self, fb.fil[0]['fxqc']['QA'], id='q_accu', label='Accu Format <i>Q<sub>A </sub></i>:') # initial setting for accumulator cmbW = qget_cmb_box(self.wdg_w_accu.cmbW, data=False) self.wdg_w_accu.ledWF.setEnabled(cmbW=='man') self.wdg_w_accu.ledWI.setEnabled(cmbW=='man') #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs & EVENTFILTERS #---------------------------------------------------------------------- self.wdg_w_coeffs.sig_tx.connect(self.update_q_coeff) self.wdg_w_accu.sig_tx.connect(self.process_sig_rx) self.wdg_q_accu.sig_tx.connect(self.process_sig_rx) #------------------------------------------------------------------------------ layVWdg = QVBoxLayout() layVWdg.setContentsMargins(0,0,0,0) layVWdg.addWidget(self.wdg_w_coeffs) # layVWdg.addWidget(self.wdg_q_coeffs) layVWdg.addWidget(self.wdg_q_accu) layVWdg.addWidget(self.wdg_w_accu) layVWdg.addStretch() self.setLayout(layVWdg)
def _construct_UI(self): """ Construct User Interface from all input subwidgets """ self.butLoadFilt = QPushButton("LOAD FILTER", self) self.butLoadFilt.setToolTip("Load filter from disk") self.butSaveFilt = QPushButton("SAVE FILTER", self) self.butSaveFilt.setToolTip("Save filter todisk") layHButtons1 = QHBoxLayout() layHButtons1.addWidget(self.butLoadFilt) # <Load Filter> button layHButtons1.addWidget(self.butSaveFilt) # <Save Filter> button layHButtons1.setContentsMargins(*params['wdg_margins_spc']) self.butDesignFilt = QPushButton("DESIGN FILTER", self) self.butDesignFilt.setToolTip("Design filter with chosen specs") self.butQuit = QPushButton("Quit", self) self.butQuit.setToolTip("Exit pyfda tool") layHButtons2 = QHBoxLayout() layHButtons2.addWidget(self.butDesignFilt) # <Design Filter> button layHButtons2.addWidget(self.butQuit) # <Quit> button layHButtons2.setContentsMargins(*params['wdg_margins']) # Subwidget for selecting filter with response type rt (LP, ...), # filter type ft (IIR, ...) and filter class fc (cheby1, ...) self.sel_fil = select_filter.SelectFilter(self) self.sel_fil.setObjectName("select_filter") self.sel_fil.sig_tx.connect(self.sig_rx_local) # Subwidget for selecting the frequency unit and range self.f_units = freq_units.FreqUnits(self) self.f_units.setObjectName("freq_units") self.f_units.sig_tx.connect(self.sig_rx_local) # Changing the frequency unit requires re-display of frequency specs # but it does not influence the actual specs (no specsChanged ) # Activating the "Sort" button emits 'view_changed'?specs_changed'?, requiring # sorting and storing the frequency entries # Changing filter parameters / specs requires reloading of parameters # in other hierarchy levels, e.g. in the plot tabs # Subwidget for Frequency Specs self.f_specs = freq_specs.FreqSpecs(self) self.f_specs.setObjectName("freq_specs") self.f_specs.sig_tx.connect(self.sig_rx_local) self.sig_tx.connect(self.f_specs.sig_rx) # Subwidget for Amplitude Specs self.a_specs = amplitude_specs.AmplitudeSpecs(self) self.a_specs.setObjectName("amplitude_specs") self.a_specs.sig_tx.connect(self.sig_rx_local) # Subwidget for Weight Specs self.w_specs = weight_specs.WeightSpecs(self) self.w_specs.setObjectName("weight_specs") self.w_specs.sig_tx.connect(self.sig_rx_local) # Subwidget for target specs (frequency and amplitude) self.t_specs = target_specs.TargetSpecs(self, title="Target Specifications") self.t_specs.setObjectName("target_specs") self.t_specs.sig_tx.connect(self.sig_rx_local) self.sig_tx.connect(self.t_specs.sig_rx) # Subwidget for displaying infos on the design method self.lblMsg = QLabel(self) self.lblMsg.setWordWrap(True) layVMsg = QVBoxLayout() layVMsg.addWidget(self.lblMsg) self.frmMsg = QFrame(self) self.frmMsg.setLayout(layVMsg) layVFrm = QVBoxLayout() layVFrm.addWidget(self.frmMsg) layVFrm.setContentsMargins(*params['wdg_margins']) # ---------------------------------------------------------------------- # LAYOUT for input specifications and buttons # ---------------------------------------------------------------------- layVMain = QVBoxLayout(self) layVMain.addLayout(layHButtons1) # <Load> & <Save> buttons layVMain.addWidget(self.sel_fil) # Design method (IIR - ellip, ...) layVMain.addLayout(layHButtons2) # <Design> & <Quit> buttons layVMain.addWidget(self.f_units) # Frequency units layVMain.addWidget(self.t_specs) # Target specs layVMain.addWidget(self.f_specs) # Freq. specifications layVMain.addWidget(self.a_specs) # Amplitude specs layVMain.addWidget(self.w_specs) # Weight specs layVMain.addLayout(layVFrm) # Text message layVMain.addStretch() layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) # main layout of widget # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx_local.connect(self.process_sig_rx_local) self.butLoadFilt.clicked.connect(lambda: load_filter(self)) self.butSaveFilt.clicked.connect(lambda: save_filter(self)) self.butDesignFilt.clicked.connect(self.start_design_filt) self.butQuit.clicked.connect(self.quit_program) # emit 'quit_program' # ---------------------------------------------------------------------- self.update_UI() # first time initialization self.start_design_filt() # design first filter using default values
def _construct_UI(self) -> None: """ Intitialize the main GUI, consisting of: - A combo box to select the filter topology and an image of the topology - The input quantizer - The UI of the fixpoint filter widget - Simulation and export buttons """ # ------------------------------------------------------------------------------ # Define frame and layout for the dynamically updated filter widget # The actual filter widget is instantiated in self.set_fixp_widget() later on self.layH_fx_wdg = QHBoxLayout() # self.layH_fx_wdg.setContentsMargins(*params['wdg_margins']) frmHDL_wdg = QFrame(self) frmHDL_wdg.setLayout(self.layH_fx_wdg) # frmHDL_wdg.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) # ------------------------------------------------------------------------------ # Initialize fixpoint filter combobox, title and description # ------------------------------------------------------------------------------ self.cmb_fx_wdg = QComboBox(self) self.cmb_fx_wdg.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.lblTitle = QLabel("not set", self) self.lblTitle.setWordWrap(True) self.lblTitle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) layHTitle = QHBoxLayout() layHTitle.addWidget(self.cmb_fx_wdg) layHTitle.addWidget(self.lblTitle) self.frmTitle = QFrame(self) self.frmTitle.setLayout(layHTitle) self.frmTitle.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------------------ # Input and Output Quantizer # ------------------------------------------------------------------------------ # - instantiate widgets for input and output quantizer # - pass the quantization (sub-?) dictionary to the constructor # ------------------------------------------------------------------------------ self.wdg_w_input = UI_W(self, q_dict=fb.fil[0]['fxqc']['QI'], wdg_name='w_input', label='', lock_visible=True) self.wdg_w_input.sig_tx.connect(self.process_sig_rx_local) cmb_q = ['round', 'floor', 'fix'] self.wdg_w_output = UI_W(self, q_dict=fb.fil[0]['fxqc']['QO'], wdg_name='w_output', label='') self.wdg_w_output.sig_tx.connect(self.process_sig_rx_local) self.wdg_q_output = UI_Q(self, q_dict=fb.fil[0]['fxqc']['QO'], wdg_name='q_output', label='Output Format <i>Q<sub>Y </sub></i>:', cmb_q=cmb_q, cmb_ov=['wrap', 'sat']) self.wdg_q_output.sig_tx.connect(self.sig_rx_local) if HAS_DS: cmb_q.append('dsm') self.wdg_q_input = UI_Q(self, q_dict=fb.fil[0]['fxqc']['QI'], wdg_name='q_input', label='Input Format <i>Q<sub>X </sub></i>:', cmb_q=cmb_q) self.wdg_q_input.sig_tx.connect(self.sig_rx_local) # Layout and frame for input quantization layVQiWdg = QVBoxLayout() layVQiWdg.addWidget(self.wdg_q_input) layVQiWdg.addWidget(self.wdg_w_input) frmQiWdg = QFrame(self) # frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmQiWdg.setLayout(layVQiWdg) frmQiWdg.setContentsMargins(*params['wdg_margins']) # Layout and frame for output quantization layVQoWdg = QVBoxLayout() layVQoWdg.addWidget(self.wdg_q_output) layVQoWdg.addWidget(self.wdg_w_output) frmQoWdg = QFrame(self) # frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmQoWdg.setLayout(layVQoWdg) frmQoWdg.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------------------ # Dynamically updated image of filter topology (label as placeholder) # ------------------------------------------------------------------------------ # allow setting background color # lbl_fixp_img_palette = QPalette() # lbl_fixp_img_palette.setColor(QPalette(window, Qt: white)) # lbl_fixp_img_palette.setBrush(self.backgroundRole(), QColor(150, 0, 0)) # lbl_fixp_img_palette.setColor(QPalette: WindowText, Qt: blue) self.lbl_fixp_img = QLabel("img not set", self) self.lbl_fixp_img.setAutoFillBackground(True) # self.lbl_fixp_img.setPalette(lbl_fixp_img_palette) # self.lbl_fixp_img.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.embed_fixp_img(self.no_fx_filter_img) layHImg = QHBoxLayout() layHImg.setContentsMargins(0, 0, 0, 0) layHImg.addWidget(self.lbl_fixp_img) # , Qt.AlignCenter) self.frmImg = QFrame(self) self.frmImg.setLayout(layHImg) self.frmImg.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------------------ # Simulation and export Buttons # ------------------------------------------------------------------------------ self.butExportHDL = QPushButton(self) self.butExportHDL.setToolTip( "Create Verilog or VHDL netlist for fixpoint filter.") self.butExportHDL.setText("Create HDL") self.butSimFx = QPushButton(self) self.butSimFx.setToolTip("Start fixpoint simulation.") self.butSimFx.setText("Sim. FX") self.layHHdlBtns = QHBoxLayout() self.layHHdlBtns.addWidget(self.butSimFx) self.layHHdlBtns.addWidget(self.butExportHDL) # This frame encompasses the HDL buttons sim and convert frmHdlBtns = QFrame(self) # frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmHdlBtns.setLayout(self.layHHdlBtns) frmHdlBtns.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------- # Top level layout # ------------------------------------------------------------------- splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(frmHDL_wdg) splitter.addWidget(frmQoWdg) splitter.addWidget(self.frmImg) # setSizes uses absolute pixel values, but can be "misused" by specifying values # that are way too large: in this case, the space is distributed according # to the _ratio_ of the values: splitter.setSizes([3000, 3000, 5000]) layVMain = QVBoxLayout() layVMain.addWidget(self.frmTitle) layVMain.addWidget(frmHdlBtns) layVMain.addWidget(frmQiWdg) layVMain.addWidget(splitter) layVMain.addStretch() layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) # ---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) self.sig_rx_local.connect(self.process_sig_rx_local) # dynamic connection in `self._update_fixp_widget()`: # ----- # if hasattr(self.fx_filt_ui, "sig_rx"): # self.sig_rx.connect(self.fx_filt_ui.sig_rx) # if hasattr(self.fx_filt_ui, "sig_tx"): # self.fx_filt_ui.sig_tx.connect(self.sig_rx_local) # ---- # ---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs # ---------------------------------------------------------------------- self.cmb_fx_wdg.currentIndexChanged.connect(self._update_fixp_widget) self.butExportHDL.clicked.connect(self.exportHDL) self.butSimFx.clicked.connect(lambda x: self.emit({'fx_sim': 'start'}))
def _construct_UI(self): """ Intitialize the main GUI, consisting of: - A combo box to select the filter topology and an image of the topology - The input quantizer - The UI of the fixpoint filter widget - Simulation and export buttons """ #------------------------------------------------------------------------------ # Define frame and layout for the dynamically updated filter widget # The actual filter widget is instantiated in self.set_fixp_widget() later on self.layH_fx_wdg = QHBoxLayout() #self.layH_fx_wdg.setContentsMargins(*params['wdg_margins']) frmHDL_wdg = QFrame(self) frmHDL_wdg.setLayout(self.layH_fx_wdg) #frmHDL_wdg.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) #------------------------------------------------------------------------------ # Initialize fixpoint filter combobox, title and description #------------------------------------------------------------------------------ self.cmb_wdg_fixp = QComboBox(self) self.cmb_wdg_fixp.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.lblTitle = QLabel("not set", self) self.lblTitle.setWordWrap(True) self.lblTitle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) layHTitle = QHBoxLayout() layHTitle.addWidget(self.cmb_wdg_fixp) layHTitle.addWidget(self.lblTitle) self.frmTitle = QFrame(self) self.frmTitle.setLayout(layHTitle) self.frmTitle.setContentsMargins(*params['wdg_margins']) #------------------------------------------------------------------------------ # Input and Output Quantizer #------------------------------------------------------------------------------ # - instantiate widgets for input and output quantizer # - pass the quantization (sub-?) dictionary to the constructor #------------------------------------------------------------------------------ self.wdg_w_input = UI_W(self, q_dict=fb.fil[0]['fxqc']['QI'], id='w_input', label='', lock_visible=True) self.wdg_w_input.sig_tx.connect(self.process_sig_rx) cmb_q = ['round', 'floor', 'fix'] self.wdg_w_output = UI_W(self, q_dict=fb.fil[0]['fxqc']['QO'], id='w_output', label='') self.wdg_w_output.sig_tx.connect(self.process_sig_rx) self.wdg_q_output = UI_Q( self, q_dict=fb.fil[0]['fxqc']['QO'], id='q_output', label='Output Format <i>Q<sub>Y </sub></i>:', cmb_q=cmb_q, cmb_ov=['wrap', 'sat']) self.wdg_q_output.sig_tx.connect(self.sig_rx) if HAS_DS: cmb_q.append('dsm') self.wdg_q_input = UI_Q( self, q_dict=fb.fil[0]['fxqc']['QI'], id='q_input', label='Input Format <i>Q<sub>X </sub></i>:', cmb_q=cmb_q) self.wdg_q_input.sig_tx.connect(self.sig_rx) # Layout and frame for input quantization layVQiWdg = QVBoxLayout() layVQiWdg.addWidget(self.wdg_q_input) layVQiWdg.addWidget(self.wdg_w_input) frmQiWdg = QFrame(self) #frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmQiWdg.setLayout(layVQiWdg) frmQiWdg.setContentsMargins(*params['wdg_margins']) # Layout and frame for output quantization layVQoWdg = QVBoxLayout() layVQoWdg.addWidget(self.wdg_q_output) layVQoWdg.addWidget(self.wdg_w_output) frmQoWdg = QFrame(self) #frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmQoWdg.setLayout(layVQoWdg) frmQoWdg.setContentsMargins(*params['wdg_margins']) #------------------------------------------------------------------------------ # Dynamically updated image of filter topology #------------------------------------------------------------------------------ # label is a placeholder for image self.lbl_fixp_img = QLabel("img not set", self) #self.lbl_fixp_img.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.embed_fixp_img(self.no_fx_filter_img) layHImg = QHBoxLayout() layHImg.setContentsMargins(0, 0, 0, 0) layHImg.addWidget(self.lbl_fixp_img) #, Qt.AlignCenter) self.frmImg = QFrame(self) self.frmImg.setLayout(layHImg) self.frmImg.setContentsMargins(*params['wdg_margins']) self.resize_img() #------------------------------------------------------------------------------ # Simulation and export Buttons #------------------------------------------------------------------------------ self.butExportHDL = QPushButton(self) self.butExportHDL.setToolTip( "Export fixpoint filter in Verilog format.") self.butExportHDL.setText("Create HDL") self.butSimHDL = QPushButton(self) self.butSimHDL.setToolTip("Start migen fixpoint simulation.") self.butSimHDL.setText("Sim. HDL") self.butSimFxPy = QPushButton(self) self.butSimFxPy.setToolTip("Simulate filter with fixpoint effects.") self.butSimFxPy.setText("Sim. FixPy") self.layHHdlBtns = QHBoxLayout() self.layHHdlBtns.addWidget(self.butSimFxPy) self.layHHdlBtns.addWidget(self.butSimHDL) self.layHHdlBtns.addWidget(self.butExportHDL) # This frame encompasses the HDL buttons sim and convert frmHdlBtns = QFrame(self) #frmBtns.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) frmHdlBtns.setLayout(self.layHHdlBtns) frmHdlBtns.setContentsMargins(*params['wdg_margins']) # ------------------------------------------------------------------- # Top level layout # ------------------------------------------------------------------- splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(frmHDL_wdg) splitter.addWidget(frmQoWdg) splitter.addWidget(self.frmImg) # setSizes uses absolute pixel values, but can be "misused" by specifying values # that are way too large: in this case, the space is distributed according # to the _ratio_ of the values: splitter.setSizes([3000, 3000, 5000]) layVMain = QVBoxLayout() layVMain.addWidget(self.frmTitle) layVMain.addWidget(frmHdlBtns) layVMain.addWidget(frmQiWdg) layVMain.addWidget(splitter) layVMain.addStretch() layVMain.setContentsMargins(*params['wdg_margins']) self.setLayout(layVMain) #---------------------------------------------------------------------- # GLOBAL SIGNALS & SLOTs #---------------------------------------------------------------------- self.sig_rx.connect(self.process_sig_rx) #---------------------------------------------------------------------- # LOCAL SIGNALS & SLOTs & EVENTFILTERS #---------------------------------------------------------------------- # monitor events and generate sig_resize event when resized self.lbl_fixp_img.installEventFilter(self) # ... then redraw image when resized self.sig_resize.connect(self.resize_img) self.cmb_wdg_fixp.currentIndexChanged.connect(self._update_fixp_widget) self.butExportHDL.clicked.connect(self.exportHDL) self.butSimHDL.clicked.connect(self.fx_sim_init) #---------------------------------------------------------------------- inst_wdg_list = self._update_filter_cmb() if len(inst_wdg_list) == 0: logger.warning("No fixpoint filters found!") else: logger.debug("Imported {0:d} fixpoint filters:\n{1}".format( len(inst_wdg_list.split("\n")) - 1, inst_wdg_list)) self._update_fixp_widget()