[myhdl-list] initial blocks in Verilog
Brought to you by:
jandecaluwe
From: John S. <jo...@sa...> - 2012-03-23 10:21:48
|
I note this as an open task. It bit me trying to co-simulate code in Icarus. Essentially the presence of 'undefined' states at the beginning of a simulation can give incorrect results. For example an integrator may have its register initialised by a reset in the logic, but in simulation, if it receives an 'undefined' input, that will propagate into the register and never change thereafter! In real logic, depending on circumstance, it may not be necessary to reset everything and incur the logic overhead to do that. Undefined (or actually, defined by switch-on transients but unknown) states in a pipeline, for example, will flush out eventually. I've added a simple function to _toVerilog.py, modelled on _writeSigDecls, which initialises variables in the siglist to the stored value, and initialises RAM in memlist to zero with a for loop. Signals of enums are set to zero, as there is no obvious initial value for them. Code including initial blocks generated by this addition has compiled successfully in Altera's Quartus II web edition. The open task description talks about dealing with lists of signals and intbvs. I'm not sure what else is required to do that though, so this addition may need more work. Here is a patch on _toVerilog.py to add this functionality: --- myhdl/myhdl/conversion/_toVerilog.py 2012-03-23 09:42:06.000000000 +0000 +++ myhdl-0.8dev_jcs/myhdl/conversion/_toVerilog.py 2012-03-17 11:17:14.000000000 +0000 @@ -94,7 +94,8 @@ "radix", "header", "no_myhdl_header", - "no_testbench" + "no_testbench", + "initial" ) def __init__(self): @@ -106,6 +107,7 @@ self.header = '' self.no_myhdl_header = False self.no_testbench = False + self.initial = False def __call__(self, func, *args, **kwargs): global _converting @@ -148,6 +150,8 @@ _writeFileHeader(vfile, vpath, self.timescale) _writeModuleHeader(vfile, intf, doc) _writeSigDecls(vfile, intf, siglist, memlist) + if self.initial: + _writeSigInitial(vfile, intf, siglist, memlist) _convertGens(genlist, vfile) _writeModuleFooter(vfile) @@ -297,6 +301,29 @@ print >> f, s.toVerilog() print >> f +def _writeSigInitial(f, intf, siglist, memlist): + if len(memlist) > 0: + print >> f, "integer kk;" + print >> f, "initial begin" + for s in siglist: + if not s._used: + continue +# if s._name in intf.argnames: +# continue + if s._driven and s._driven == 'reg': + if isinstance(s._val, (bool,int,long,intbv)): + v = s._val + else: + v = 0 + print >> f, " %s = %d;" % (s._name, v) + for m in memlist: + if not m._used: + continue + if m._driven and m._driven == 'reg': + print >> f, " for (kk=0;kk<%d;kk=kk+1)" % (m.depth) + print >> f, " %s[kk] = 0;" % (m.name) + print >>f, "end" + def _writeModuleFooter(f): print >> f, "endmodule" |