mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
error reporting with user defined verilog
This commit is contained in:
parent
307dca2f2c
commit
93440598e9
@ -48,7 +48,7 @@ __author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||
__revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
__version__ = "0.5a"
|
||||
__version__ = "0.5a1"
|
||||
|
||||
import warnings
|
||||
|
||||
|
@ -26,6 +26,7 @@ __revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
import sys
|
||||
import inspect
|
||||
from inspect import currentframe, getframeinfo, getouterframes
|
||||
import re
|
||||
import string
|
||||
@ -35,7 +36,7 @@ from compiler import ast
|
||||
import linecache
|
||||
from sets import Set
|
||||
|
||||
from myhdl import Signal, ExtractHierarchyError
|
||||
from myhdl import Signal, ExtractHierarchyError, ToVerilogError
|
||||
from myhdl._util import _isGenFunc
|
||||
from myhdl._isGenSeq import _isGenSeq
|
||||
from myhdl._always_comb import _AlwaysComb
|
||||
@ -72,22 +73,32 @@ def _makeMemInfo(mem):
|
||||
def _isMem(mem):
|
||||
return id(mem) in _memInfoMap
|
||||
|
||||
_customVerilogMap = {}
|
||||
_userDefinedVerilogMap = {}
|
||||
|
||||
class _CustomVerilog(object):
|
||||
__slots__ = ['code', 'namespace']
|
||||
def __init__(self, code, namespace):
|
||||
class _UserDefinedVerilog(object):
|
||||
__slots__ = ['code', 'namespace', 'sourcefile', 'funcname', 'sourceline']
|
||||
def __init__(self, code, namespace, sourcefile, funcname, sourceline):
|
||||
self.code = code
|
||||
self.namespace = namespace
|
||||
self.sourcefile = sourcefile
|
||||
self.funcname = funcname
|
||||
self.sourceline = sourceline
|
||||
|
||||
def __str__(self):
|
||||
code = self.code % self.namespace
|
||||
try:
|
||||
code = self.code % self.namespace
|
||||
except:
|
||||
type, value, tb = sys.exc_info()
|
||||
info = "in file %s, function %s starting on line %s:\n " % \
|
||||
(self.sourcefile, self.funcname, self.sourceline)
|
||||
msg = "%s: %s" % (type, value)
|
||||
raise ToVerilogError("Error in user defined Verilog code", msg, info)
|
||||
code = "\n%s\n" % code
|
||||
return code
|
||||
|
||||
def _addCustomVerilog(arg, code, namespace):
|
||||
assert id(arg) not in _customVerilogMap
|
||||
_customVerilogMap[id(arg)] = _CustomVerilog(code, namespace)
|
||||
def _addUserDefinedVerilog(arg, code, namespace, sourcefile, funcname, sourceline):
|
||||
assert id(arg) not in _userDefinedVerilogMap
|
||||
_userDefinedVerilogMap[id(arg)] = _UserDefinedVerilog(code, namespace, sourcefile, funcname, sourceline)
|
||||
|
||||
|
||||
def _isListOfSigs(obj):
|
||||
@ -202,7 +213,10 @@ class _HierExtr(object):
|
||||
code = frame.f_locals["__verilog__"]
|
||||
namespace = frame.f_globals.copy()
|
||||
namespace.update(frame.f_locals)
|
||||
_addCustomVerilog(arg, code, namespace)
|
||||
sourcefile = inspect.getsourcefile(frame)
|
||||
funcname = frame.f_code.co_name
|
||||
sourceline = inspect.getsourcelines(frame)[1]
|
||||
_addUserDefinedVerilog(arg, code, namespace, sourcefile, funcname, sourceline)
|
||||
# building hierarchy only makes sense if there are generators
|
||||
if isGenSeq and arg:
|
||||
sigdict = {}
|
||||
|
@ -43,7 +43,7 @@ from myhdl._always_comb import _AlwaysComb
|
||||
from myhdl._always import _Always
|
||||
from myhdl._toVerilog import _error, _access, _kind, _context, \
|
||||
_ToVerilogMixin, _Label
|
||||
from myhdl._extractHierarchy import _isMem, _CustomVerilog
|
||||
from myhdl._extractHierarchy import _isMem, _UserDefinedVerilog
|
||||
|
||||
myhdlObjects = myhdl.__dict__.values()
|
||||
builtinObjects = __builtin__.__dict__.values()
|
||||
@ -115,7 +115,7 @@ def _analyzeSigs(hierarchy):
|
||||
def _analyzeGens(top, absnames):
|
||||
genlist = []
|
||||
for g in top:
|
||||
if isinstance(g, _CustomVerilog):
|
||||
if isinstance(g, _UserDefinedVerilog):
|
||||
ast = g
|
||||
elif isinstance(g, (_AlwaysComb, _Always)):
|
||||
f = g.func
|
||||
|
@ -26,6 +26,7 @@ __revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import inspect
|
||||
import compiler
|
||||
from compiler import ast as astNode
|
||||
@ -39,7 +40,7 @@ import myhdl
|
||||
from myhdl import *
|
||||
from myhdl import ToVerilogError, ToVerilogWarning
|
||||
from myhdl._extractHierarchy import _HierExtr, _isMem, _getMemInfo, \
|
||||
_CustomVerilog, _customVerilogMap
|
||||
_UserDefinedVerilog, _userDefinedVerilogMap
|
||||
|
||||
from myhdl._always_comb import _AlwaysComb
|
||||
from myhdl._always import _Always
|
||||
@ -53,14 +54,14 @@ _profileFunc = None
|
||||
|
||||
def _checkArgs(arglist):
|
||||
for arg in arglist:
|
||||
if not type(arg) in (GeneratorType, _AlwaysComb, _Always, _CustomVerilog):
|
||||
if not type(arg) in (GeneratorType, _AlwaysComb, _Always, _UserDefinedVerilog):
|
||||
raise ToVerilogError(_error.ArgType, arg)
|
||||
|
||||
def _flatten(*args):
|
||||
arglist = []
|
||||
for arg in args:
|
||||
if id(arg) in _customVerilogMap:
|
||||
arglist.append(_customVerilogMap[id(arg)])
|
||||
if id(arg) in _userDefinedVerilogMap:
|
||||
arglist.append(_userDefinedVerilogMap[id(arg)])
|
||||
elif isinstance(arg, (list, tuple, Set)):
|
||||
for item in arg:
|
||||
arglist.extend(_flatten(item))
|
||||
@ -249,7 +250,7 @@ def _convertGens(genlist, vfile):
|
||||
blockBuf = StringIO()
|
||||
funcBuf = StringIO()
|
||||
for ast in genlist:
|
||||
if isinstance(ast, _CustomVerilog):
|
||||
if isinstance(ast, _UserDefinedVerilog):
|
||||
blockBuf.write(str(ast))
|
||||
continue
|
||||
if ast.kind == _kind.ALWAYS:
|
||||
|
@ -44,10 +44,7 @@ def incGen(count, enable, clock, reset, n):
|
||||
if enable:
|
||||
count.next = (count + 1) % n
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def inc(count, enable, clock, reset, n):
|
||||
""" Incrementer with enable.
|
||||
|
||||
@ -86,6 +83,37 @@ end
|
||||
return incProcess
|
||||
|
||||
|
||||
def incErr(count, enable, clock, reset, n):
|
||||
|
||||
@always(clock.posedge, reset.negedge)
|
||||
def incProcess():
|
||||
# make it fail in conversion
|
||||
import types
|
||||
if reset == ACTIVE_LOW:
|
||||
count.next = 0
|
||||
else:
|
||||
if enable:
|
||||
count.next = (count + 1) % n
|
||||
|
||||
count.driven = "reg"
|
||||
|
||||
__verilog__ = \
|
||||
"""
|
||||
always @(posedge %(clock)s, negedge %(reset)s) begin
|
||||
if (reset == 0) begin
|
||||
%(count)s <= 0;
|
||||
end
|
||||
else begin
|
||||
if (enable) begin
|
||||
%(count)s <= (%(countq)s + 1) %% %(n)s;
|
||||
end
|
||||
end
|
||||
end
|
||||
"""
|
||||
|
||||
return incProcess
|
||||
|
||||
|
||||
|
||||
def inc_comb(nextCount, count, n):
|
||||
|
||||
@ -240,6 +268,21 @@ class TestInc(TestCase):
|
||||
self.assertEqual(e.kind, _error.NotSupported)
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
def testIncErr(self):
|
||||
m = 8
|
||||
n = 2 ** m
|
||||
count_v = Signal(intbv(0)[m:])
|
||||
enable = Signal(bool(0))
|
||||
clock, reset = [Signal(bool()) for i in range(2)]
|
||||
try:
|
||||
inc_inst = toVerilog(incErr, count_v, enable, clock, reset, n=n)
|
||||
except ToVerilogError, e:
|
||||
pass
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
x
Reference in New Issue
Block a user