1
0
mirror of https://github.com/myhdl/myhdl.git synced 2025-01-24 21:52:56 +08:00
This commit is contained in:
forumulator 2016-03-03 17:15:49 +05:30
commit 68302ecc6a
14 changed files with 124 additions and 44 deletions

View File

@ -9,13 +9,19 @@ python:
- "3.4"
- "3.5"
# binary install as per travis instructions
# used to install latest version of ghdl
before_script:
- ./scripts/install_ghdl.sh
- export PATH=$PATH:$PWD/ghdl-0.33/bin/
addons:
apt:
sources:
- pgavin-ghdl
# sources:
# - pgavin-ghdl
packages:
- iverilog
- ghdl
# - ghdl
install:
- pip install .

View File

@ -41,6 +41,14 @@ A :class:`Simulation` object has the following method:
Run the simulation forever (by default) or for a specified duration.
.. method:: Simulation.quit()
Quit the simulation after it has run for a specified duration. The method should
be called (the simulation instance must be quit) before another simulation
instance is created. The method is called by default when the simulation is run
forever.
.. _ref-simsupport:
Simulation support functions
@ -90,6 +98,11 @@ Waveform tracing
This attribute is used to set the directory to which VCD files are written. By
default, the current working directory is used.
.. attribute:: filename
This attribute is used to set the filename to which VCD files are written. By
default, the name attribbute is used.
.. attribute:: timescale
This attribute is used to set the timescale corresponding to unit steps,

View File

@ -33,6 +33,7 @@ def simulate(timesteps):
tb = traceSignals(test_dff)
sim = Simulation(tb)
sim.run(timesteps)
sim.quit()
simulate(2000)

View File

@ -44,6 +44,7 @@ def simulate(timesteps):
tb = traceSignals(test_dffa)
sim = Simulation(tb)
sim.run(timesteps)
sim.quit()
simulate(20000)

View File

@ -33,6 +33,7 @@ def simulate(timesteps):
tb = traceSignals(test_latch)
sim = Simulation(tb)
sim.run(timesteps)
sim.quit()
simulate(20000)

View File

@ -45,6 +45,7 @@ class _error:
_error.ArgType = "Inappriopriate argument type"
_error.MultipleCosim = "Only a single cosimulator argument allowed"
_error.DuplicatedArg = "Duplicated argument"
_error.MultipleSim = "Only a single Simulation instance is allowed"
class Simulation(object):
@ -54,6 +55,7 @@ class Simulation(object):
run -- run a simulation for some duration
"""
_no_of_instances = 0
def __init__(self, *args):
""" Construct a simulation object.
@ -65,13 +67,16 @@ class Simulation(object):
_simulator._time = 0
arglist = _flatten(*args)
self._waiters, self._cosim = _makeWaiters(arglist)
if Simulation._no_of_instances > 0:
raise SimulationError(_error.MultipleSim)
Simulation._no_of_instances += 1
if not self._cosim and _simulator._cosim:
warn("Cosimulation not registered as Simulation argument")
self._finished = False
del _futureEvents[:]
del _siglist[:]
def _finalize(self):
cosim = self._cosim
if cosim:
@ -85,9 +90,12 @@ class Simulation(object):
# clean up for potential new run with same signals
for s in _signals:
s._clear()
Simulation._no_of_instances = 0
self._finished = True
def quit(self):
self._finalize()
def runc(self, duration=0, quiet=0):
simrunc.run(sim=self, duration=duration, quiet=quiet)
@ -201,7 +209,7 @@ class Simulation(object):
self._finalize()
# now reraise the exepction
raise
def _makeWaiters(arglist):
waiters = []
@ -231,4 +239,4 @@ def _makeWaiters(arglist):
if hasattr(sig, '_waiter'):
waiters.append(sig._waiter)
return waiters, cosim

View File

@ -50,6 +50,7 @@ class _TraceSignalsClass(object):
__slot__ = ("name",
"directory",
"filename",
"timescale",
"tracelists"
)
@ -57,6 +58,7 @@ class _TraceSignalsClass(object):
def __init__(self):
self.name = None
self.directory = None
self.filename = None
self.timescale = "1ns"
self.tracelists = True
@ -89,8 +91,13 @@ class _TraceSignalsClass(object):
else:
directory = self.directory
if self.filename is None:
filename = name
else:
filename = str(self.filename)
h = _HierExtr(name, dut, *args, **kwargs)
vcdpath = os.path.join(directory, name + ".vcd")
vcdpath = os.path.join(directory, filename + ".vcd")
if path.exists(vcdpath):
backup = vcdpath + '.' + str(path.getmtime(vcdpath))
shutil.copyfile(vcdpath, backup)

View File

@ -578,10 +578,14 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
node.obj = int(0) # XXX
elif f is bool:
node.obj = bool()
elif f in _flatten(integer_types, ord):
elif f in _flatten(integer_types):
node.obj = int(-1)
## elif f in (posedge , negedge):
## node.obj = _EdgeDetector()
elif f is ord:
node.obj = int(-1)
if not (isinstance(node.args[0], ast.Str) and (len(node.args[0].s) == 1)):
self.raiseError(node, _error.NotSupported, "ord: expect string argument with length 1")
elif f is delay:
node.obj = delay(0)
### suprize: identity comparison on unbound methods doesn't work in python 2.5??
@ -915,6 +919,8 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
s = s[m.end():]
continue
self.raiseError(node, _error.UnsupportedFormatString, "%s" % s)
elif isinstance(n, ast.Str):
f.append(n.s)
else:
f.append(defaultConvSpec)
a.append(n)

View File

@ -602,9 +602,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
pre, suf = "", "(0)"
else:
pre, suf = "stdl(", ")"
elif isinstance(vhd, vhd_string):
if isinstance(ori, vhd_enum):
pre, suf = "%s'image(" % ori._type._name, ")"
# elif isinstance(vhd, vhd_string):
# if isinstance(ori, vhd_enum):
# pre, suf = "%s'image(" % ori._type._name, ")"
return pre, suf
@ -654,10 +654,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
self.shiftOp(node)
elif isinstance(node.op, (ast.BitAnd, ast.BitOr, ast.BitXor)):
self.BitOp(node)
elif isinstance(node.op, ast.Mod) and (self.context == _context.PRINT):
self.visit(node.left)
self.write(", ")
self.visit(node.right)
else:
self.BinOp(node)
@ -953,11 +949,10 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
return
elif f is ord:
opening, closing = '', ''
if isinstance(node.args[0], ast.Str):
if len(node.args[0].s) > 1:
self.raiseError(node, _error.UnsupportedType, "Strings with length > 1" )
else:
node.args[0].s = ord(node.args[0].s)
v = ord(node.args[0].s)
node.args[0].s = v
self.write(v)
return
elif f in integer_types:
opening, closing = '', ''
pre, suf = self.inferCast(node.vhd, node.vhdOri)
@ -1361,15 +1356,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
a.vhd = vhd_boolean()
elif isinstance(a.vhdOri, vhd_enum):
a.vhd = vhd_string()
self.write("write(L, ")
self.context = _context.PRINT
self.write("write(L, to_string(")
self.visit(a)
self.context = None
if s.justified == 'LEFT':
self.write(", justified=>LEFT")
if s.width:
self.write(", field=>%s" % s.width)
self.write(")")
self.write("))")
self.write(';')
self.writeline()
self.write("writeline(output, L);")

View File

@ -151,7 +151,7 @@ class _ToVerilogConvertor(object):
genlist = _analyzeGens(arglist, h.absnames)
siglist, memlist = _analyzeSigs(h.hierarchy)
_annotateTypes(genlist)
intf = _analyzeTopFunc(func, *args, **kwargs)
intf.name = name
doc = _makeDoc(inspect.getdoc(func))
@ -750,11 +750,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
return
elif f is ord:
opening, closing = '', ''
if isinstance(node.args[0], ast.Str):
if len(node.args[0].s) > 1:
self.raiseError(node, _error.UnsupportedType, "Strings with length > 1")
else:
node.args[0].s = str(ord(node.args[0].s))
node.args[0].s = str(ord(node.args[0].s))
elif f in integer_types:
opening, closing = '', ''
# convert number argument to integer

View File

@ -22,7 +22,7 @@ _simulators = {}
sim = namedtuple('sim', 'name hdl analyze elaborate simulate skiplines skipchars ignore')
def registerSimulator(name=None, hdl=None, analyze=None, elaborate=None, simulate=None,
def registerSimulator(name=None, hdl=None, analyze=None, elaborate=None, simulate=None,
skiplines=None, skipchars=None, ignore=None):
if not isinstance(name, str) or (name.strip() == ""):
raise ValueError("Invalid simulator name")
@ -41,8 +41,8 @@ def registerSimulator(name=None, hdl=None, analyze=None, elaborate=None, simulat
registerSimulator(
name="ghdl",
hdl="VHDL",
analyze="ghdl -a --workdir=work pck_myhdl_%(version)s.vhd %(topname)s.vhd",
elaborate="ghdl -e --workdir=work -o %(unitname)s %(topname)s",
analyze="ghdl -a --std=08 --workdir=work pck_myhdl_%(version)s.vhd %(topname)s.vhd",
elaborate="ghdl -e --std=08 --workdir=work %(unitname)s",
simulate="ghdl -r --workdir=work %(unitname)s"
)
@ -96,7 +96,7 @@ class _VerificationClass(object):
__slots__ = ("simulator", "_analyzeOnly")
def __init__(self, analyzeOnly=False):
self.simulator = None
self.simulator = None
self._analyzeOnly = analyzeOnly
@ -178,7 +178,7 @@ class _VerificationClass(object):
if ret != 0:
print("Elaboration failed", file=sys.stderr)
return ret
g = tempfile.TemporaryFile(mode='w+t')
#print(simulate)
ret = subprocess.call(simulate, stdout=g, shell=True)

View File

@ -0,0 +1,43 @@
from __future__ import print_function
import pytest
from myhdl import Simulation, delay, SimulationError, instance, now
from myhdl._Simulation import _error
from helpers import raises_kind
def test():
@instance
def tbstim():
yield delay(10)
print("{0:<8d} ".format(now()))
yield delay(1000)
print("{0:<8d} ".format(now()))
for _ in range(10):
yield delay(1000)
return tbstim
def issue_104_quit_method():
sim = Simulation(test())
sim.run(1000)
sim.run(500)
sim.quit()
return sim._finished
def issue_104_multiple_instance():
sim1 = Simulation(test())
sim1.run(1000)
# sim1 is "puased"
# try and create a second, third, forth simulation instance
for ii in range(4):
with raises_kind(SimulationError, _error.MultipleSim):
another_sim = Simulation(test())
# generating more sims should have failed
sim1.run(1000)
sim1.quit()
def test_issue_104():
assert issue_104_quit_method() == True
issue_104_multiple_instance()

View File

@ -155,12 +155,16 @@ class TestTraceSigs:
assert not path.exists(psub)
def testTristateTrace(self, vcd_dir):
Simulation(topTristate()).run(100, quiet=QUIET)
sim = Simulation(topTristate())
sim.run(100, quiet=QUIET)
sim.quit()
def testBackupOutputFile(self, vcd_dir):
p = "%s.vcd" % fun.__name__
dut = traceSignals(fun)
Simulation(dut).run(1000, quiet=QUIET)
sim = Simulation(dut)
sim.run(1000, quiet=QUIET)
sim.quit()
_simulator._tf.close()
_simulator._tracing = 0
size = path.getsize(p)

5
scripts/install_ghdl.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
set -evx
wget https://sourceforge.net/projects/ghdl-updates/files/Builds/ghdl-0.33/ghdl-0.33-x86_64-linux.tgz -O /tmp/ghdl.tar.gz
mkdir ghdl-0.33
tar -C ghdl-0.33 -xvf /tmp/ghdl.tar.gz