################################################################################ # # Copyright 2013, Sinclair R.F., Inc. # ################################################################################ import re; from ssbccPeripheral import SSBCCperipheral from ssbccUtil import SSBCCException; class timer(SSBCCperipheral): """ Simple timer to facilitate polled-loops.\n The timer sets a flag when the timer expires and clears the flag when it is read.\n Usage: PERIPHERAL timer inport=I_name \\ ratemethod={clk/rate|count}\n Where: inport=I_name specifies the symbol used by the inport instruction to get the unexpired/expired status of the timer Note: The name must start with "I_" ratemethod specifies the method to generate the desired timer event rate: 1st method: clk/rate clk is the frequency of "i_clk" in Hz a number will be interpreted as the clock frequency in Hz a symbol will be interpreted as a parameter Note: this parameter must have been declared with a "PARAMETER" command rate is the desired baud rate this is specified as per "clk" 2nd method: specify the number of "i_clk" clock cycles between timer events Note: clk, rate, and count can be parameters or constants. For example, the following uses the parameter G_CLK_FREQ_HZ for the clock frequency and a hard-wired event rate of 1 kHz "baudmethod=G_CLK_FREQ_HZ/1000". Note: The numeric values can have Verilog-style '_' separators between the digits. For example, 100_000_000 represents 100 million.\n Example: Configure the timer for 1000 kHz events and monitor for these events in the micro controller code.\n PARAMETER G_CLK_FREQ_HZ 100_000_000 PERIPHERAL timer inport=I_TIMER ratemethod=G_CLK_FREQ_HZ/1000\n ; See if the timer has expired since the last time it was polled and ; conditionally call "timer_event" if it has. .inport(I_TIMER) .callc(timer_event) """ def __init__(self,peripheralFile,config,param_list,loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile; # Get the parameters. for param_tuple in param_list: param = param_tuple[0]; param_arg = param_tuple[1]; if param == 'inport': self.AddAttr(config,param,param_arg,'I_\w+$',loc); elif param == 'ratemethod': self.AddRateMethod(config,param,param_arg,loc); else: raise SSBCCException('Unrecognized parameter at %s: %s' % (loc,param,)); # Ensure the required parameters are provided. for paramname in ('inport','ratemethod',): if not hasattr(self,paramname): raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,)); # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. name = 's__%s__expired' % self.inport; config.AddSignal(name, 1, loc); config.AddSignal('s_SETRESET_%s' % name,1,loc); config.AddInport((self.inport, ('s__%s__expired' % self.inport, 1, 'set-reset'), ),loc); # Add the 'clog2' function to the processor (if required). config.functions['clog2'] = True; def GenVerilog(self,fp,config): body = self.LoadCore(self.peripheralFile,'.v'); for subs in ( (r'\bL__', 'L__@NAME@__',), (r'\bs__', 's__@NAME@__',), (r'@RATEMETHOD@', str(self.ratemethod),), (r'@NAME@', self.inport,), ): body = re.sub(subs[0],subs[1],body); body = self.GenVerilogFinal(config,body); fp.write(body);