mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
deleted
This commit is contained in:
parent
a700c121e9
commit
6651d335fb
@ -1,242 +0,0 @@
|
|||||||
# This file is part of the myhdl library, a Python package for using
|
|
||||||
# Python as a Hardware Description Language.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2003 Jan Decaluwe
|
|
||||||
#
|
|
||||||
# The myhdl library is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU Lesser General Public License as
|
|
||||||
# published by the Free Software Foundation; either version 2.1 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This library is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# Lesser General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public
|
|
||||||
# License along with this library; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
""" myhdl trace_sigs module.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
|
||||||
__revision__ = "$Revision$"
|
|
||||||
__date__ = "$Date$"
|
|
||||||
|
|
||||||
from __future__ import generators
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from inspect import currentframe, getframeinfo, getouterframes
|
|
||||||
import compiler
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
import time
|
|
||||||
from types import FunctionType
|
|
||||||
import os
|
|
||||||
path = os.path
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
from myhdl import _simulator, Signal, __version__
|
|
||||||
from myhdl._util import _isGenSeq, _isgeneratorfunction
|
|
||||||
|
|
||||||
_tracing = 0
|
|
||||||
|
|
||||||
class Error(Exception):
|
|
||||||
""" trace_sigs Error"""
|
|
||||||
def __init__(self, arg=""):
|
|
||||||
self.arg = arg
|
|
||||||
def __str__(self):
|
|
||||||
msg = self.__doc__
|
|
||||||
if self.arg:
|
|
||||||
msg = msg + ": " + str(self.arg)
|
|
||||||
return msg
|
|
||||||
|
|
||||||
class TopLevelNameError(Error):
|
|
||||||
"""result of trace_sigs call should be assigned to a top level name"""
|
|
||||||
|
|
||||||
class ArgTypeError(Error):
|
|
||||||
"""trace_sigs first argument should be a classic function"""
|
|
||||||
|
|
||||||
class NoInstancesError(Error):
|
|
||||||
"""trace_sigs returned no instances"""
|
|
||||||
|
|
||||||
re_assign = r"""^
|
|
||||||
\s*
|
|
||||||
(?P<name>\w[\w\d]*)
|
|
||||||
(?P<index>\[.*\])?
|
|
||||||
\s*
|
|
||||||
=
|
|
||||||
"""
|
|
||||||
|
|
||||||
rex_assign = re.compile(re_assign, re.X)
|
|
||||||
|
|
||||||
|
|
||||||
def trace_sigs(dut, *args, **kwargs):
|
|
||||||
global _tracing
|
|
||||||
if _tracing:
|
|
||||||
return dut(*args, **kwargs) # skip
|
|
||||||
if not callable(dut):
|
|
||||||
raise ArgTypeError("got %s" % type(dut))
|
|
||||||
if _isgeneratorfunction(dut):
|
|
||||||
raise ArgTypeError("got generator function")
|
|
||||||
_tracing = 1
|
|
||||||
try:
|
|
||||||
outer = getouterframes(currentframe())[1]
|
|
||||||
name = _findInstanceName(outer)
|
|
||||||
if name is None:
|
|
||||||
raise TopLevelNameError
|
|
||||||
h = _HierExtr(name, dut, *args, **kwargs)
|
|
||||||
vcdpath = name + ".vcd"
|
|
||||||
if path.exists(vcdpath):
|
|
||||||
backup = vcdpath + '.' + str(path.getmtime(vcdpath))
|
|
||||||
shutil.copyfile(vcdpath, backup)
|
|
||||||
os.remove(vcdpath)
|
|
||||||
vcdfile = open(vcdpath, 'w')
|
|
||||||
_simulator._tracing = 1
|
|
||||||
_simulator._tf = vcdfile
|
|
||||||
_writeVcdHeader(vcdfile)
|
|
||||||
_writeVcdSigs(vcdfile, h.instances)
|
|
||||||
finally:
|
|
||||||
_tracing = 0
|
|
||||||
return h.m
|
|
||||||
|
|
||||||
|
|
||||||
def _findInstanceName(framerec):
|
|
||||||
f = framerec[0]
|
|
||||||
c = framerec[4][0]
|
|
||||||
m = rex_assign.match(c)
|
|
||||||
name = None
|
|
||||||
if m:
|
|
||||||
basename, index = m.groups()
|
|
||||||
if index:
|
|
||||||
il = []
|
|
||||||
for i in index[1:-1].split("]["):
|
|
||||||
try:
|
|
||||||
s = str(eval(i, f.f_globals, f.f_locals))
|
|
||||||
except:
|
|
||||||
break
|
|
||||||
il.append(s)
|
|
||||||
else:
|
|
||||||
name = basename + '[' + "][".join(il) + ']'
|
|
||||||
else:
|
|
||||||
name = basename
|
|
||||||
return name
|
|
||||||
|
|
||||||
|
|
||||||
class _HierExtr(object):
|
|
||||||
|
|
||||||
def __init__(self, name, dut, *args, **kwargs):
|
|
||||||
self.names = [name]
|
|
||||||
self.instances = instances = []
|
|
||||||
self.level = 0
|
|
||||||
sys.setprofile(self.extractor)
|
|
||||||
try:
|
|
||||||
_top = dut(*args, **kwargs)
|
|
||||||
finally:
|
|
||||||
sys.setprofile(None)
|
|
||||||
if not instances:
|
|
||||||
raise NoInstancesError
|
|
||||||
self.m = _top
|
|
||||||
instances.reverse()
|
|
||||||
instances[0][1] = name
|
|
||||||
|
|
||||||
def extractor(self, frame, event, arg):
|
|
||||||
if event == "call":
|
|
||||||
outer = getouterframes(frame)[1]
|
|
||||||
name = _findInstanceName(outer)
|
|
||||||
self.names.append(name)
|
|
||||||
if name:
|
|
||||||
self.level += 1
|
|
||||||
elif event == "return":
|
|
||||||
name = self.names.pop()
|
|
||||||
if name:
|
|
||||||
if _isGenSeq(arg):
|
|
||||||
sigdict = {}
|
|
||||||
for dict in (frame.f_locals, frame.f_globals):
|
|
||||||
for n, v in dict.items():
|
|
||||||
if isinstance(v, Signal):
|
|
||||||
sigdict[n] = v
|
|
||||||
i = [self.level, name, sigdict]
|
|
||||||
self.instances.append(i)
|
|
||||||
self.level -= 1
|
|
||||||
|
|
||||||
|
|
||||||
_codechars = ""
|
|
||||||
for i in range(33, 127):
|
|
||||||
_codechars += chr(i)
|
|
||||||
_mod = len(_codechars)
|
|
||||||
|
|
||||||
def _genNameCode():
|
|
||||||
n = 0
|
|
||||||
while 1:
|
|
||||||
yield _namecode(n)
|
|
||||||
n += 1
|
|
||||||
|
|
||||||
def _namecode(n):
|
|
||||||
q, r = divmod(n, _mod)
|
|
||||||
code = _codechars[r]
|
|
||||||
while q > 0:
|
|
||||||
q, r = divmod(q, _mod)
|
|
||||||
code = _codechars[r] + code
|
|
||||||
return code
|
|
||||||
|
|
||||||
def _writeVcdHeader(f):
|
|
||||||
print >> f, "$date"
|
|
||||||
print >> f, " %s" % time.asctime()
|
|
||||||
print >> f, "$end"
|
|
||||||
print >> f, "$version"
|
|
||||||
print >> f, " MyHDL %s" % __version__
|
|
||||||
print >> f, "$end"
|
|
||||||
print >> f, "$timesscale"
|
|
||||||
print >> f, " 1ns"
|
|
||||||
print >> f, "$end"
|
|
||||||
print >> f
|
|
||||||
|
|
||||||
def _writeVcdSigs(f, instances):
|
|
||||||
curlevel = 0
|
|
||||||
namegen = _genNameCode()
|
|
||||||
siglist = []
|
|
||||||
for level, name, sigdict in instances:
|
|
||||||
delta = curlevel - level
|
|
||||||
curlevel = level
|
|
||||||
assert(delta >= -1)
|
|
||||||
if delta >= 0:
|
|
||||||
for i in range(delta + 1):
|
|
||||||
print >> f, "$upscope $end"
|
|
||||||
print >> f, "$scope module %s $end" % name
|
|
||||||
for n, s in sigdict.items():
|
|
||||||
if not s._tracing:
|
|
||||||
s._tracing = 1
|
|
||||||
s._code = namegen.next()
|
|
||||||
siglist.append(s)
|
|
||||||
w = s._nrbits
|
|
||||||
if w:
|
|
||||||
if w == 1:
|
|
||||||
print >> f, "$var reg 1 %s %s $end" % (s._code, n)
|
|
||||||
else:
|
|
||||||
print >> f, "$var reg %s %s %s $end" % (w, s.code, n)
|
|
||||||
else:
|
|
||||||
print >> f, "$var real 1 %s %s $end" % (s._code, n)
|
|
||||||
for i in range(curlevel):
|
|
||||||
print >> f, "$upscope $end"
|
|
||||||
print >> f
|
|
||||||
print >> f, "$enddefinitions $end"
|
|
||||||
print >> f, "$dumpvars"
|
|
||||||
for s in siglist:
|
|
||||||
s._printVcd() # initial value
|
|
||||||
print >> f, "$end"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
|||||||
# This file is part of the myhdl library, a Python package for using
|
|
||||||
# Python as a Hardware Description Language.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2003 Jan Decaluwe
|
|
||||||
#
|
|
||||||
# The myhdl library is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU Lesser General Public License as
|
|
||||||
# published by the Free Software Foundation; either version 2.1 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This library is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# Lesser General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU Lesser General Public
|
|
||||||
# License along with this library; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
""" Run the unit tests for bin """
|
|
||||||
|
|
||||||
__author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
|
||||||
__revision__ = "$Revision$"
|
|
||||||
__date__ = "$Date$"
|
|
||||||
|
|
||||||
from __future__ import generators
|
|
||||||
|
|
||||||
import random
|
|
||||||
from random import randrange
|
|
||||||
random.seed(1) # random, but deterministic
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
path = os.path
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
from unittest import TestCase
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
from myhdl import delay, Signal, Simulation
|
|
||||||
from myhdl._trace_sigs import trace_sigs, TopLevelNameError, ArgTypeError, \
|
|
||||||
NoInstancesError
|
|
||||||
|
|
||||||
QUIET=1
|
|
||||||
|
|
||||||
def gen(clk):
|
|
||||||
while 1:
|
|
||||||
yield delay(10)
|
|
||||||
clk.next = not clk
|
|
||||||
|
|
||||||
def fun():
|
|
||||||
clk = Signal(bool(0))
|
|
||||||
inst = gen(clk)
|
|
||||||
return inst
|
|
||||||
|
|
||||||
def dummy():
|
|
||||||
clk = Signal(bool(0))
|
|
||||||
inst = gen(clk)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def top():
|
|
||||||
inst = trace_sigs(fun)
|
|
||||||
return inst
|
|
||||||
|
|
||||||
def top2():
|
|
||||||
inst = [{} for i in range(4)]
|
|
||||||
j = 3
|
|
||||||
inst[j-2]['key'] = trace_sigs(fun)
|
|
||||||
return inst
|
|
||||||
|
|
||||||
|
|
||||||
class TestTraceSigs(TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.paths = paths = ["dut.vcd", "inst.vcd"]
|
|
||||||
for p in paths:
|
|
||||||
if path.exists(p):
|
|
||||||
os.remove(p)
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
for p in self.paths:
|
|
||||||
if path.exists(p):
|
|
||||||
os.remove(p)
|
|
||||||
|
|
||||||
def testTopName(self):
|
|
||||||
p = "dut.vcd"
|
|
||||||
dut = trace_sigs(fun)
|
|
||||||
try:
|
|
||||||
trace_sigs(fun)
|
|
||||||
except TopLevelNameError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail()
|
|
||||||
|
|
||||||
def testArgType1(self):
|
|
||||||
p = "dut.vcd"
|
|
||||||
try:
|
|
||||||
dut = trace_sigs([1, 2])
|
|
||||||
except ArgTypeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail()
|
|
||||||
|
|
||||||
def testArgType2(self):
|
|
||||||
p = "dut.vcd"
|
|
||||||
try:
|
|
||||||
dut = trace_sigs(gen, Signal(0))
|
|
||||||
except ArgTypeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail()
|
|
||||||
|
|
||||||
def testReturnVal(self):
|
|
||||||
p = "dut.vcd"
|
|
||||||
try:
|
|
||||||
dut = trace_sigs(dummy)
|
|
||||||
except NoInstancesError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail()
|
|
||||||
|
|
||||||
def testHierarchicalTrace1(self):
|
|
||||||
p = "inst.vcd"
|
|
||||||
top()
|
|
||||||
self.assert_(path.exists(p))
|
|
||||||
|
|
||||||
def testHierarchicalTrace2(self):
|
|
||||||
pdut = "dut.vcd"
|
|
||||||
psub = "inst.vcd"
|
|
||||||
dut = trace_sigs(top)
|
|
||||||
self.assert_(path.exists(pdut))
|
|
||||||
self.assert_(not path.exists(psub))
|
|
||||||
|
|
||||||
def testIndexedName(self):
|
|
||||||
p = "dut[1][0].vcd"
|
|
||||||
dut = [[None] * 3 for i in range(4)]
|
|
||||||
i, j = 0, 2
|
|
||||||
dut[i+1][j-2] = trace_sigs(top)
|
|
||||||
self.assert_(path.exists(p))
|
|
||||||
os.remove(p)
|
|
||||||
|
|
||||||
def testIndexedName2(self):
|
|
||||||
p = "inst[1][key].vcd"
|
|
||||||
top2()
|
|
||||||
self.assert_(path.exists(p))
|
|
||||||
os.remove(p)
|
|
||||||
|
|
||||||
def testBackupOutputFile(self):
|
|
||||||
p = "dut.vcd"
|
|
||||||
dut = trace_sigs(fun)
|
|
||||||
Simulation(dut).run(1000, quiet=QUIET)
|
|
||||||
size = path.getsize(p)
|
|
||||||
pbak = p + '.' + str(path.getmtime(p))
|
|
||||||
self.assert_(not path.exists(pbak))
|
|
||||||
dut = trace_sigs(fun)
|
|
||||||
self.assert_(path.exists(p))
|
|
||||||
self.assert_(path.exists(pbak))
|
|
||||||
self.assert_(path.getsize(pbak) == size)
|
|
||||||
self.assert_(path.getsize(p) < size)
|
|
||||||
os.remove(pbak)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
Loading…
x
Reference in New Issue
Block a user