Exemple #1
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from sig_rx
        """

        if dict_sig['sender'] == __name__:
            logger.debug("Stopped infinite loop:\n{0}".format(
                pprint_log(dict_sig)))
            return
        else:
            logger.debug("SIG_RX - data_changed = {0}, vis = {1}\n{2}"\
                     .format(self.data_changed, self.isVisible(), pprint_log(dict_sig)))

        if 'ui_changed' in dict_sig and dict_sig['ui_changed'] == 'csv':
            self.ui._set_load_save_icons()
            #self.sig_tx.emit(dict_sig)

        elif self.isVisible():
            if 'data_changed' in dict_sig or self.data_changed:
                self.load_dict()
                self.data_changed = False
        else:
            # TODO: draw wouldn't be necessary for 'view_changed', only update view
            if 'data_changed' in dict_sig:
                self.data_changed = True
Exemple #2
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from sig_rx
        """
        logger.debug("process_sig_rx(): vis={0}\n{1}"\
                    .format(self.isVisible(), pprint_log(dict_sig)))

        if dict_sig['sender'] == __name__:
            logger.debug("Stopped infinite loop\n{0}".format(pprint_log(dict_sig)))
            return

        if  'ui_changed' in dict_sig and dict_sig['ui_changed'] == 'csv':
            self.ui._set_load_save_icons()

        elif self.isVisible():
            if self.data_changed or 'data_changed' in dict_sig:
                self.load_dict()
                self.data_changed = False
            if self.fx_specs_changed or ('fx_sim' in dict_sig and dict_sig['fx_sim'] == 'specs_changed'):
                self.qdict2ui()
                self.fx_specs_changed = False
        else:
            # TODO: draw wouldn't be necessary for 'view_changed', only update view 
            if 'data_changed' in dict_sig:
                self.data_changed = True
            elif 'fx_sim' in dict_sig and dict_sig['fx_sim'] == 'specs_changed':
                self.fx_specs_changed = True
Exemple #3
0
 def update_q_coeff(self, dict_sig):
     """
     Update coefficient quantization settings and coefficients.
     
     The new values are written to the fixpoint coefficient dict as
     `fb.fil[0]['fxqc']['QCB']` and
     `fb.fil[0]['fxqc']['b']`.
     """  
     logger.debug("update q_coeff - dict_sig:\n{0}".format(pprint_log(dict_sig)))
     #dict_sig.update({'ui':'C'+dict_sig['ui']})
     fb.fil[0]['fxqc'].update(self.ui2dict())
     logger.debug("b = {0}".format(pprint_log(fb.fil[0]['fxqc']['b'])))
     
     self.process_sig_rx(dict_sig)
Exemple #4
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from
        -
        -
        """

        logger.warning("PROCESS_SIG_RX - vis: {0}\n{1}".format(
            self.isVisible(), pprint_log(dict_sig)))

        if 'id' in dict_sig and dict_sig['id'] == id(self):
            logger.warning("Stopped infinite loop:\n{0}".format(
                pprint_log(dict_sig)))
            return
Exemple #5
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from the navigation toolbar and from sig_rx
        """
        logger.debug("Processing {0} | needs_calc = {1}, visible = {2}"\
                     .format(dict_sig, self.needs_calc, self.isVisible()))
        if dict_sig['sender'] == __name__:
            logger.debug("Stopped infinite loop\n{0}".format(
                pprint_log(dict_sig)))
            return

        if self.isVisible():
            if 'data_changed' in dict_sig or 'home' in dict_sig or self.needs_calc:
                self.draw()
                self.needs_calc = False
                self.needs_draw = False
            elif 'view_changed' in dict_sig or self.needs_draw:
                self.update_view()
                self.needs_draw = False
            # elif ('ui_changed' in dict_sig and dict_sig['ui_changed'] == 'resized')\
            #     or self.needs_redraw:
            #     self.redraw()
        else:
            if 'data_changed' in dict_sig:
                self.needs_calc = True
            elif 'view_changed' in dict_sig:
                self.needs_draw = True
Exemple #6
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process local signals from / for
        - FFT window widget
        - qfft_win_select
        """

        logger.debug("SIG_RX - vis: {0}\n{1}".format(self.isVisible(),
                                                     pprint_log(dict_sig)))

        if dict_sig['id'] == id(self):
            logger.warning(f"Stopped infinite loop:\n{pprint_log(dict_sig)}")

        # --- signals coming from the FFT window widget or the qfft_win_select
        if dict_sig['class'] in {'Plot_FFT_win', 'QFFTWinSelector'}:
            if 'closeEvent' in dict_sig:  # hide FFT window windget and return
                self.hide_fft_wdg()
                return
            else:
                if 'view_changed' in dict_sig and 'fft_win' in dict_sig[
                        'view_changed']:
                    # self._update_fft_window()  # TODO: needed?
                    # local connection to FFT window widget and qfft_win_select
                    self.emit(dict_sig, sig_name='sig_tx_local')
                    # global connection to upper hierachies
                    # send notification that filter design has changed
                    self.emit({'filt_changed': 'firwin'})
Exemple #7
0
    def process_sig_rx(self, dict_sig=None):
        logger.debug("sig_rx:\n{0}".format(pprint_log(dict_sig)))
        # check whether anything needs to be done locally
        # could also check here for 'quant', 'ovfl', 'WI', 'WF' (not needed at the moment)
        # if not, just pass the dict 
        if 'ui' in dict_sig:
            if dict_sig['id'] == 'w_coeff': # coefficient format updated
                """
                Update coefficient quantization settings and coefficients.
        
                The new values are written to the fixpoint coefficient dict as
                `fb.fil[0]['fxqc']['QCB']` and  `fb.fil[0]['fxqc']['b']`.
                """  

                fb.fil[0]['fxqc'].update(self.ui2dict())
                
            elif dict_sig['ui'] == 'cmbW':
                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')
                if cmbW in {'full', 'auto'}:
                    self.dict2ui()
                    self.sig_tx.emit({'sender':__name__, 'specs_changed':'cmbW'})
                else:
                    return

            dict_sig.update({'sender':__name__}) # currently only local

        self.sig_tx.emit(dict_sig)
Exemple #8
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from the navigation toolbar and from sig_rx:

        - `self.calc_N`
        - `self.update_view`:
        - `self.draw`: calculate window and FFT and draw both
        """
        # logger.debug("PROCESS_SIG_RX - vis={0}, needs_calc={1}\n{2}"
        #              .format(self.isVisible(), self.needs_calc, pprint_log(dict_sig)))

        if dict_sig['id'] == id(self):
            logger.warning("Stopped infinite loop:\n{0}".format(
                pprint_log(dict_sig)))
            return

        elif not self.isVisible():
            self.needs_calc = True

        elif 'view_changed' in dict_sig and 'fft_win' in dict_sig['view_changed']\
                or self.needs_calc:

            self.calc_win_draw()
            self.needs_calc = False

        elif 'home' in dict_sig:
            self.update_view()

        else:
            logger.error("Unknown content of dict_sig: {0}".format(dict_sig))
Exemple #9
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from
        - FFT window widget
        - qfft_win_select
        """

        # logger.debug("PROCESS_SIG_RX - vis: {0}\n{1}"
        #              .format(self.isVisible(), pprint_log(dict_sig)))

        if 'id' in dict_sig and dict_sig['id'] == id(self):
            logger.warning("Stopped infinite loop:\n{0}".format(
                pprint_log(dict_sig)))
            return

        # --- signals coming from the FFT window widget or the FFT window selector
        if dict_sig['class'] in {'Plot_FFT_win', 'QFFTWinSelector'}:
            if 'closeEvent' in dict_sig:  # hide FFT window widget and return
                self.hide_fft_wdg()
                return
            else:
                # check for value 'fft_win*':
                if 'view_changed' in dict_sig and 'fft_win' in dict_sig[
                        'view_changed']:
                    # local connection to FFT window widget and qfft_win_select
                    self.emit(dict_sig, sig_name='sig_tx_fft')
                    # global connection to e.g. plot_impz
                    self.emit(dict_sig)
Exemple #10
0
    def fx_sim_init(self):
        """
        Initialize fix-point simulation: 
            
        - Update the `fxqc_dict` containing all quantization information
        
        - Setup a filter instance for migen simulation
        
        - Request a stimulus signal
        """
        if not hasattr(self.fx_wdg_inst, 'construct_fixp_filter'):
            logger.error(
                'Fixpoint widget has no method "construct_fixp_filter", aborting.'
            )
            self.sig_tx.emit({'sender': __name__, 'fx_sim': 'error'})
            return

        try:
            logger.info("Fixpoint simulation started")
            self.t_start = time.process_time()
            self.update_fxqc_dict()
            self.fx_wdg_inst.construct_fixp_filter()  # setup filter instance

            dict_sig = {'sender': __name__, 'fx_sim': 'get_stimulus'}
            self.sig_tx.emit(dict_sig)

        except ValueError as e:  # exception
            logger.error(
                'Fixpoint stimulus generation failed during "init" for dict\n{0}'
                '\nwith "{1} "'.format(pprint_log(dict_sig), e))
        return
Exemple #11
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from
        - FFT window widget
        - qfft_win_select
        """

        logger.warning("PROCESS_SIG_RX - vis: {0}\n{1}".format(
            self.isVisible(), pprint_log(dict_sig)))

        if 'id' in dict_sig and dict_sig['id'] == id(self):
            logger.warning("Stopped infinite loop:\n{0}".format(
                pprint_log(dict_sig)))
            return
        elif 'view_changed' in dict_sig:
            if dict_sig['view_changed'] == 'f_S':
                self.recalc_freqs()
Exemple #12
0
 def log_rx(self, dict_sig=None):
     """
     Enable `self.sig_rx.connect(self.log_rx)` above for debugging.
     """
     if type(dict_sig) == dict:
         logger.warning("SIG_RX\n{0}".format(pprint_log(dict_sig)))
     else:
         logger.warning("empty dict")
Exemple #13
0
    def fx_sim_calc_response(self, dict_sig) -> None:
        """
        - Read fixpoint stimulus from `dict_sig` in integer format
        - Pass it to the fixpoint filter which calculates the fixpoint response
        - Store the result in `fb.fx_results` and return. In case of an error,
          `fb.fx_results == None`

        Returns
        -------
        None
        """
        try:
            # logger.info(
            #     'Simulate fixpoint frame with "{0}" stimulus:\n\t{1}'.format(
            #         dict_sig['class'],
            #         pprint_log(dict_sig['fx_stimulus'], tab=" "),
            #         ))

            # Run fixpoint simulation and store the results as integer values:
            fb.fx_results = self.fx_filt_ui.fxfilter(dict_sig['fx_stimulus'])

            if len(fb.fx_results) == 0:
                logger.error("Fixpoint simulation returned empty results!")
            # else:
            #     # logger.debug("fx_results: {0}"\
            #     #            .format(pprint_log(fb.fx_results, tab= " ")))
            #     logger.info(
            #         f'Fixpoint simulation successful for dict\n{pprint_log(dict_sig)}'
            #         f'\tStimuli: Shape {np.shape(dict_sig["fx_stimulus"])}'
            #         f' of type "{dict_sig["fx_stimulus"].dtype}"'
            #         f'\n\tResponse: Shape {np.shape(fb.fx_results)}'
            #         f' of type "{type(fb.fx_results).__name__} "'
            #         f' ("{type(fb.fx_results[0]).__name__}")'
            #     )

        except ValueError as e:
            logger.error("Simulator error {0}".format(e))
            fb.fx_results = None

        except AssertionError as e:
            logger.error('Fixpoint simulation failed for dict\n{0}'
                         '\twith msg. "{1}"\n\tStimuli: Shape {2} of type "{3}"'
                         '\n\tResponse: Shape {4} of type "{5}"'.format(
                            pprint_log(dict_sig), e,
                            np.shape(dict_sig['fx_stimulus']),
                            dict_sig['fx_stimulus'].dtype,
                            np.shape(fb.fx_results),
                            type(fb.fx_results)
                                ))
            fb.fx_results = None

        if fb.fx_results is None:
            qstyle_widget(self.butSimFx, "error")
        else:
            pass # everything ok, return 
            # logger.debug("Sending fixpoint results")
        return
Exemple #14
0
    def process_sig_rx(self, dict_sig=None) -> None:
        """
        Process signals coming from
        - the navigation toolbars (time and freq.)
        - local widgets (impz_ui) and
        - plot_tab_widgets() (global signals)
        """

        logger.warning("SIG_RX - vis: {0}\n{1}".format(self.isVisible(),
                                                       pprint_log(dict_sig)))
Exemple #15
0
 def update_fxqc_dict(self):
     """
     Update the fxqc dictionary before simulation / HDL generation starts.
     """
     if self.fx_wdg_found:
         # get a dict with the coefficients and fixpoint settings from fixpoint widget
         if hasattr(self.fx_filt_ui, "ui2dict"):
             fb.fil[0]['fxqc'].update(self.fx_filt_ui.ui2dict())
             logger.debug("update fxqc: \n{0}".format(pprint_log(fb.fil[0]['fxqc'])))
     else:
         logger.error("No fixpoint widget found!")
Exemple #16
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from the CSV pop-up window
        """

        logger.debug("PROCESS_SIG_RX\n{0}".format(pprint_log(dict_sig)))
        
        if 'closeEvent' in dict_sig:
            self._close_csv_win()
            self.sig_tx.emit({'sender':__name__, 'ui_changed': 'csv'})
            return # probably not needed
        elif 'ui_changed' in dict_sig:
            self._set_load_save_icons() # update icons file <-> clipboard
            # inform e.g. the p/z input widget about changes in CSV options 
            self.sig_tx.emit({'sender':__name__, 'ui_changed': 'csv'})
Exemple #17
0
    def process_sig_rx(self, dict_sig=None):
        logger.warning("sig_rx:\n{0}".format(pprint_log(dict_sig)))
        # check whether anything needs to be done locally
        # could also check here for 'quant', 'ovfl', 'WI', 'WF' (not needed at the moment)
        # if not, just emit the dict.
        if 'ui' in dict_sig:
            if dict_sig['wdg_name'] == 'w_coeff':  # coefficient format updated
                """
                Update coefficient quantization settings and coefficients.

                The new values are written to the fixpoint coefficient dict as
                `fb.fil[0]['fxqc']['QCB']` and  `fb.fil[0]['fxqc']['b']`.
                """

                fb.fil[0]['fxqc'].update(self.ui2dict())

            elif dict_sig['wdg_name'] == 'w_accu':  # accu format updated
                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')
                if cmbW in {'full', 'auto'}\
                        or ('ui' in dict_sig and dict_sig['ui'] in {'WF', 'WI'}):
                    pass

                elif cmbW == 'man':  # switched to manual, don't do anything
                    return

            # Accu quantization or overflow settings have been changed
            elif dict_sig['wdg_name'] == 'q_accu':
                pass

            else:
                logger.error(f"Unknown widget name '{dict_sig['wdg_name']}' "
                             f"in '{__name__}' !")
                return

            # - update fixpoint accu and coefficient quantization dict
            # - emit {'fx_sim': 'specs_changed'}
            fb.fil[0]['fxqc'].update(self.ui2dict())
            self.emit({'fx_sim': 'specs_changed'})

        else:
            logger.error(
                f"Unknown key '{dict_sig['wdg_name']}' (should be 'ui')"
                f"in '{__name__}' !")
Exemple #18
0
    def process_sig_rx(self, dict_sig=None, propagate=False):
        """
        Process signals coming in via subwidgets and sig_rx
        
        All signals terminate here unless the flag `propagate=True`.
        
        The sender name of signals coming in from local subwidgets is changed to
        its parent widget (`input_specs`) to prevent infinite loops.

        """
        logger.debug("Processing {0}: {1}".format(
            type(dict_sig).__name__, dict_sig))
        if dict_sig['sender'] == __name__:
            logger.debug("Stopped infinite loop:\n{0}\tpropagate={1}"\
                           .format(pprint_log(dict_sig),propagate))
            return
        elif 'view_changed' in dict_sig:
            self.f_specs.load_dict()
            self.t_specs.load_dict()
        elif 'specs_changed' in dict_sig:
            self.f_specs.sort_dict_freqs()
            self.t_specs.f_specs.sort_dict_freqs()
            self.color_design_button("changed")
        elif 'filt_changed' in dict_sig:
            # Changing the filter design requires updating UI because number or
            # kind of input fields changes -> call update_UI
            self.update_UI(dict_sig)
            self.color_design_button("changed")
        elif 'data_changed' in dict_sig:
            if dict_sig['data_changed'] == 'filter_loaded':
                """
                Called when a new filter has been LOADED:
                Pass new filter data from the global filter dict by
                specifically calling SelectFilter.load_dict()
                """
                self.sel_fil.load_dict()  # update select_filter widget
            # Pass new filter data from the global filter dict & set button = "ok"
            self.load_dict()

        if propagate:
            # local signals are propagated with the name of this widget,
            # global signals terminate here
            dict_sig.update({'sender': __name__})
            self.sig_tx.emit(dict_sig)
Exemple #19
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from the navigation toolbar and from sig_rx
        """
        logger.debug("SIG_RX - needs_calc = {0}, vis = {1}\n{2}"\
                     .format(self.needs_calc, self.isVisible(), pprint_log(dict_sig)))

        if self.isVisible():
            if 'data_changed' in dict_sig or 'specs_changed' in dict_sig\
                    or 'home' in dict_sig or self.needs_calc:
                self.draw()
                self.needs_calc = False
                self.needs_draw = False
            if 'view_changed' in dict_sig or self.needs_draw:
                self.update_view()
                self.needs_draw = False
        else:
            if 'data_changed' in dict_sig or 'specs_changed' in dict_sig:
                self.needs_calc = True
            if 'view_changed' in dict_sig:
                self.needs_draw = True
Exemple #20
0
    def __init__(self):
        p = fb.fil[0]['fxqc']

        # ------------- Define I/Os -------------------------------------------
        self.i = Signal((p['QI']['W'], True))  # input signal
        self.o = Signal((p['QO']['W'], True))  # output signal

        ###
        muls = []  # list for partial products b_i * x_i
        DW = int(np.ceil(np.log2(len(p['b']))))  # word growth
        # word format for sum of partial products b_i * x_i
        QP = {
            'WI': p['QI']['WI'] + p['QCB']['WI'] + DW,
            'WF': p['QI']['WF'] + p['QCB']['WF']
        }
        QP.update({'W': QP['WI'] + QP['WF'] + 1})

        src = self.i  # first register is connected to input signal

        for b in p['b']:
            sreg = Signal((p['QI']['W'], True))  # create chain of registers
            self.sync += sreg.eq(src)  # with input word length
            src = sreg
            muls.append(int(b) * sreg)

        logger.debug("b = {0}\nW(b) = {1}".format(pprint_log(p['b']),
                                                  p['QCB']['W']))

        # saturation logic doesn't make much sense with a FIR filter, this is
        # just for demonstration
        sum_full = Signal((QP['W'], True))
        self.sync += sum_full.eq(reduce(
            add, muls))  # sum of multiplication products

        # rescale from full product format to accumulator format
        sum_accu = Signal((p['QA']['W'], True))
        self.comb += sum_accu.eq(rescale(self, sum_full, QP, p['QA']))

        # rescale from accumulator format to output width
        self.comb += self.o.eq(rescale(self, sum_accu, p['QA'], p['QO']))
Exemple #21
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming from the navigation toolbar and from sig_rx
        """
        logger.debug("PROCESS_SIG_RX - vis: {0}\n{1}"\
                     .format(self.isVisible(), pprint_log(dict_sig)))
        if ('view_changed' in dict_sig and dict_sig['view_changed'] == 'win')\
            or ('filt_changed' in dict_sig and dict_sig['filt_changed'] == 'firwin')\
            or self.needs_calc:
            # logger.warning("Auto: {0} - WinLen: {1}".format(self.N_auto, self.win_dict['win_len']))
            self.N_auto = self.win_dict['win_len']
            self.calc_N()

            if self.isVisible():
                self.draw()
                self.needs_calc = False
            else:
                self.needs_calc = True

        elif 'home' in dict_sig:
            self.update_view()

        else:
            logger.error("Unknown content of dict_sig: {0}".format(dict_sig))
Exemple #22
0
    def fx_sim_set_stimulus(self, dict_sig):
        """
        - Get fixpoint stimulus from `dict_sig` in integer format
          
        - Pass it to the fixpoint filter and calculate the fixpoint response
        
        - Send the reponse to the plotting widget
        """
        try:
            logger.debug(
                'Starting fixpoint simulation with stimulus from "{0}":\n\tfx_stimulus:{1}'
                '\n\tStimuli: Shape {2} of type "{3}"'.format(
                    dict_sig['sender'],
                    pprint_log(dict_sig['fx_stimulus'], tab=" "),
                    np.shape(dict_sig['fx_stimulus']),
                    dict_sig['fx_stimulus'].dtype,
                ))
            self.t_stim = time.process_time()
            logger.info("Fixpoint simulation [{0:5.3g} ms]: Stimuli generated"\
                        .format((self.t_stim-self.t_start)*1000))

            # Run fixpoint simulation and return the results as integer values:
            self.fx_results = self.fx_wdg_inst.run_sim(
                dict_sig['fx_stimulus'])  # Run the simulation
            self.t_resp = time.process_time()

            if len(self.fx_results) == 0:
                logger.warning("Fixpoint simulation returned empty results!")
            else:
                #logger.debug("fx_results: {0}"\
                #            .format(pprint_log(self.fx_results, tab= " ")))
                logger.debug('Fixpoint simulation successful for dict\n{0}'
                         '\tStimuli: Shape {1} of type "{2}"'
                         '\n\tResponse: Shape {3} of type "{4}"'\
                           .format(pprint_log(dict_sig),
                                   np.shape(dict_sig['fx_stimulus']),
                                   dict_sig['fx_stimulus'].dtype,
                                   np.shape(self.fx_results),
                                   type(self.fx_results)
                                    ))
                logger.info('Fixpoint simulation [{0:5.3g} ms]: Response calculated'\
                            .format((self.t_resp - self.t_stim)*1000))

            #TODO: fixed point / integer to float conversion?
            #TODO: color push-button to show state of simulation
            #TODO: add QTimer single shot
#            self.timer_id = QtCore.QTimer()
#            self.timer_id.setSingleShot(True)
#            # kill simulation after some idle time, also add a button for this
#            self.timer_id.timeout.connect(self.kill_sim)

        except ValueError as e:
            logger.error("Simulator error {0}".format(e))
            self.fx_results = None
            qstyle_widget(self.butSimHDL, "error")
            self.sig_tx.emit({'sender': __name__, 'fx_sim': 'error'})
            return
        except AssertionError as e:
            logger.error('Fixpoint simulation failed for dict\n{0}'
                         '\twith msg. "{1}"\n\tStimuli: Shape {2} of type "{3}"'
                         '\n\tResponse: Shape {4} of type "{5}"'\
                           .format(pprint_log(dict_sig), e,
                                   np.shape(dict_sig['fx_stimulus']),
                                   dict_sig['fx_stimulus'].dtype,
                                   np.shape(self.fx_results),
                                   type(self.fx_results)
                                    ))

            self.fx_results = None
            qstyle_widget(self.butSimHDL, "error")
            self.sig_tx.emit({'sender': __name__, 'fx_sim': 'error'})
            return

        logger.debug("Sending fixpoint results")
        dict_sig = {
            'sender': __name__,
            'fx_sim': 'set_results',
            'fx_results': self.fx_results
        }
        self.sig_tx.emit(dict_sig)
        qstyle_widget(self.butSimHDL, "normal")
        return
Exemple #23
0
    def process_sig_rx(self, dict_sig=None):
        """
        Process signals coming in via subwidgets and sig_rx
		
		Play PingPong with a stimulus & plot widget:
        
		2. ``fx_sim_init()``: Request stimulus by sending 'fx_sim':'get_stimulus'
		
		3. ``fx_sim_set_stimulus()``: Receive stimulus from widget in 'fx_sim':'send_stimulus'
			and pass it to HDL object for simulation
		   
		4. Send back HDL response to widget via 'fx_sim':'set_response'

        """

        logger.debug("process_sig_rx(): vis={0}\n{1}"\
                    .format(self.isVisible(), pprint_log(dict_sig)))
        if dict_sig['sender'] == __name__:
            logger.debug("Stopped infinite loop\n{0}".format(
                pprint_log(dict_sig)))
            return
        elif 'data_changed' in dict_sig and dict_sig[
                'data_changed'] == "filter_designed":
            # New filter has been designed, update list of available filter topologies here
            self._update_filter_cmb()
            return
        elif 'data_changed' in dict_sig or\
            ('view_changed' in dict_sig and dict_sig['view_changed'] == 'q_coeff'):
            # update fields in the filter topology widget - wordlength may have
            # been changed. Also set RUN button to "changed" in wdg_dict2ui()
            self.wdg_dict2ui()
            #self.sig_tx.emit({'sender':__name__, 'fx_sim':'specs_changed'})
        elif 'fx_sim' in dict_sig:
            if dict_sig['fx_sim'] == 'init':
                if self.fx_wdg_found:
                    self.fx_sim_init()
                else:
                    logger.error("No fixpoint widget found!")
                    qstyle_widget(self.butSimHDL, "error")
                    self.sig_tx.emit({'sender': __name__, 'fx_sim': 'error'})

            elif dict_sig['fx_sim'] == 'send_stimulus':
                self.fx_sim_set_stimulus(dict_sig)
            elif dict_sig['fx_sim'] == 'specs_changed':
                # fixpoint specification have been changed somewhere, update ui
                # and set run button to "changed" in wdg_dict2ui()
                self.wdg_dict2ui()
            elif dict_sig['fx_sim'] == 'finish':
                qstyle_widget(self.butSimHDL, "normal")
                logger.info('Fixpoint simulation [{0:5.3g} ms]: Plotting finished'\
                            .format((time.process_time() - self.t_resp)*1000))
            else:
                logger.error('Unknown "fx_sim" command option "{0}"\n'
                             '\treceived from "{1}".'.format(
                                 dict_sig['fx_sim'], dict_sig['sender']))
        # ---- Process local widget signals
        elif 'ui' in dict_sig:
            if 'id' in dict_sig and dict_sig['id'] == 'w_input':
                """
                Input fixpoint format has been changed or butLock has been clicked.
                When I/O lock is active, copy input fixpoint word format to output 
                word format.
                """
                if dict_sig[
                        'ui'] == 'butLock' and not self.wdg_w_input.butLock.isChecked(
                        ):
                    # butLock was deactivitated, don't do anything
                    return
                elif self.wdg_w_input.butLock.isChecked():
                    # but lock was activated or wordlength setting have been changed
                    fb.fil[0]['fxqc']['QO']['WI'] = fb.fil[0]['fxqc']['QI'][
                        'WI']
                    fb.fil[0]['fxqc']['QO']['WF'] = fb.fil[0]['fxqc']['QI'][
                        'WF']
                    fb.fil[0]['fxqc']['QO']['W'] = fb.fil[0]['fxqc']['QI']['W']

            elif 'id' in dict_sig and dict_sig['id'] == 'w_output':
                """
                Output fixpoint format has been changed. When I/O lock is active, copy
                output fixpoint word format to input word format.
                """
                if self.wdg_w_input.butLock.isChecked():
                    fb.fil[0]['fxqc']['QI']['WI'] = fb.fil[0]['fxqc']['QO'][
                        'WI']
                    fb.fil[0]['fxqc']['QI']['WF'] = fb.fil[0]['fxqc']['QO'][
                        'WF']
                    fb.fil[0]['fxqc']['QI']['W'] = fb.fil[0]['fxqc']['QO']['W']

            elif 'id' in dict_sig and dict_sig['id'] in \
                {'w_coeff', 'q_input', 'q_output', 'w_accu', 'q_accu'}:
                pass  # nothing to do for now

            else:
                if not "id" in dict_sig:
                    logger.warning("No id in dict_sig:\n{0}".format(
                        pprint_log(dict_sig)))
                else:
                    logger.warning('Unknown id "{0}" in dict_sig:\n{1}'\
                                   .format(dict_sig['id'], pprint_log(dict_sig)))

            if not dict_sig['ui'] in {
                    'WI', 'WF', 'ovfl', 'quant', 'cmbW', 'butLock'
            }:
                logger.warning("Unknown value '{0}' for key 'ui'".format(
                    dict_sig['ui']))
            self.wdg_dict2ui(
            )  # update wordlengths in UI and set RUN button to 'changed'
            self.sig_tx.emit({'sender': __name__, 'fx_sim': 'specs_changed'})

            return
Exemple #24
0
    def process_sig_rx_local(self, dict_sig: dict = None) -> None:
        """
        Process signals coming in from input and output quantizer subwidget and the
        dynamically instantiated subwidget and emit {'fx_sim': 'specs_changed'} in
        the end.
        """
        if dict_sig['id'] == id(self):
            logger.warning(f'RX_LOCAL - Stopped infinite loop: "{first_item(dict_sig)}"')
            return

        elif 'fx_sim' in dict_sig and dict_sig['fx_sim'] == 'specs_changed':
            self.wdg_dict2ui()  # update wordlengths in UI and set RUN button to 'changed'
            dict_sig.update({'id': id(self)})  # propagate 'specs_changed' with self 'id'
            self.emit(dict_sig)
            return

        # ---- Process input and output quantizer settings ('ui' in dict_sig) --
        elif 'ui' in dict_sig:
            if 'wdg_name' not in dict_sig:
                logger.warning(f"No key 'wdg_name' in dict_sig:\n{pprint_log(dict_sig)}")
                return

            elif dict_sig['wdg_name'] == 'w_input':
                """
                Input fixpoint format has been changed or butLock has been clicked.
                When I/O lock is active, copy input fixpoint word format to output
                word format.
                """
                if dict_sig['ui'] == 'butLock'\
                        and not self.wdg_w_input.butLock.isChecked():
                    # butLock was deactivitated, don't do anything
                    return
                elif self.wdg_w_input.butLock.isChecked():
                    # but lock was activated or wordlength setting have been changed
                    fb.fil[0]['fxqc']['QO']['WI'] = fb.fil[0]['fxqc']['QI']['WI']
                    fb.fil[0]['fxqc']['QO']['WF'] = fb.fil[0]['fxqc']['QI']['WF']
                    fb.fil[0]['fxqc']['QO']['W'] = fb.fil[0]['fxqc']['QI']['W']

            elif dict_sig['wdg_name'] == 'w_output':
                """
                Output fixpoint format has been changed. When I/O lock is active, copy
                output fixpoint word format to input word format.
                """
                if self.wdg_w_input.butLock.isChecked():
                    fb.fil[0]['fxqc']['QI']['WI'] = fb.fil[0]['fxqc']['QO']['WI']
                    fb.fil[0]['fxqc']['QI']['WF'] = fb.fil[0]['fxqc']['QO']['WF']
                    fb.fil[0]['fxqc']['QI']['W'] = fb.fil[0]['fxqc']['QO']['W']

            elif dict_sig['wdg_name'] in {'q_output', 'q_input'}:
                pass
            else:
                logger.error("Unknown wdg_name '{0}' in dict_sig:\n{1}"
                             .format(dict_sig['wdg_name'], pprint_log(dict_sig)))
                return

            if dict_sig['ui'] not in {'WI', 'WF', 'ovfl', 'quant', 'cmbW', 'butLock'}:
                logger.warning("Unknown value '{0}' for key 'ui'".format(dict_sig['ui']))

            self.wdg_dict2ui()  # update wordlengths in UI and set RUN button to 'changed'
            self.emit({'fx_sim': 'specs_changed'})  # propagate 'specs_changed'

        else:
            logger.error(f"Unknown key/value in 'dict_sig':\n{pprint_log(dict_sig)}")