mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
first VHDL example that works
This commit is contained in:
parent
a6b77fd084
commit
e14c01d30a
@ -54,8 +54,7 @@ class _PosedgeWaiterList(_WaiterList):
|
||||
def _toVerilog(self):
|
||||
return "posedge %s" % self.sig._name
|
||||
def _toVHDL(self):
|
||||
return self.sig._name
|
||||
#return "rising_edge(%s)" % self.sig._name
|
||||
return "rising_edge(%s)" % self.sig._name
|
||||
|
||||
class _NegedgeWaiterList(_WaiterList):
|
||||
def __init__(self, sig):
|
||||
@ -63,8 +62,7 @@ class _NegedgeWaiterList(_WaiterList):
|
||||
def _toVerilog(self):
|
||||
return "negedge %s" % self.sig._name
|
||||
def _toVHDL(self):
|
||||
return self.sig._name
|
||||
#return "falling_edge(%s)" % self.sig._name
|
||||
return "falling_edge(%s)" % self.sig._name
|
||||
|
||||
|
||||
def posedge(sig):
|
||||
|
@ -116,10 +116,9 @@ from _instance import instance
|
||||
from _enum import enum, EnumType, EnumItemType
|
||||
from _traceSignals import traceSignals
|
||||
from _toVerilog._convert import toVerilog
|
||||
try:
|
||||
from _toVHDL._convert import toVHDL
|
||||
except:
|
||||
toVHDL = None
|
||||
|
||||
from _toVHDL._convert import toVHDL
|
||||
|
||||
|
||||
__all__ = ["bin",
|
||||
"concat",
|
||||
|
@ -48,7 +48,8 @@ from myhdl._always import _Always
|
||||
from myhdl._toVerilog import _error, _access, _kind,_context, \
|
||||
_ToVerilogMixin, _Label
|
||||
from myhdl._toVerilog._analyze import _analyzeSigs, _analyzeGens, _analyzeTopFunc, \
|
||||
_Ram, _Rom, _EdgeDetector
|
||||
_Ram, _Rom
|
||||
from myhdl._Signal import _WaiterList
|
||||
|
||||
_converting = 0
|
||||
_profileFunc = None
|
||||
@ -134,6 +135,10 @@ toVHDL = _ToVHDLConvertor()
|
||||
|
||||
|
||||
def _writeModuleHeader(f, intf):
|
||||
print >> f, "library IEEE;"
|
||||
print >> f, "use IEEE.std_logic_1164.all;"
|
||||
print >> f, "use IEEE.numeric_std.all;"
|
||||
print >> f
|
||||
print >> f, "entity %s is" % intf.name
|
||||
if intf.argnames:
|
||||
print >> f, " port ("
|
||||
@ -170,7 +175,7 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
||||
)
|
||||
# the following line implements initial value assignments
|
||||
# print >> f, "%s %s%s = %s;" % (s._driven, r, s._name, int(s._val))
|
||||
print >> f, "signal %s %s%s;" % (s._name, p, r)
|
||||
print >> f, "signal %s: %s%s;" % (s._name, p, r)
|
||||
elif s._read:
|
||||
# the original exception
|
||||
# raise ToVerilogError(_error.UndrivenSignal, s._name)
|
||||
@ -185,9 +190,11 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
||||
continue
|
||||
r = _getRangeString(m.elObj)
|
||||
print >> f, "reg %s%s [0:%s-1];" % (r, m.name, m.depth)
|
||||
print >> f
|
||||
for s in constwires:
|
||||
print >> f, "%s <= %s;" % (s._name, int(s._val))
|
||||
print >> f
|
||||
print >> f, "begin"
|
||||
print >> f
|
||||
|
||||
|
||||
def _writeModuleFooter(f):
|
||||
@ -463,7 +470,6 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
else:
|
||||
self.write(' = ')
|
||||
node.expr.target = self.getObj(node.nodes[0])
|
||||
print node.expr.target
|
||||
self.visit(node.expr)
|
||||
self.write(';')
|
||||
|
||||
@ -559,6 +565,7 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
if op == "==":
|
||||
op = "="
|
||||
self.write(" %s " % op)
|
||||
print context
|
||||
self.visit(code, context)
|
||||
self.write(")")
|
||||
|
||||
@ -726,14 +733,21 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
ifstring = "elsif"
|
||||
self.writeline()
|
||||
self.write(ifstring)
|
||||
self.visit(test)
|
||||
self.visit(test, _context.BOOLEAN)
|
||||
self.write(" then")
|
||||
self.indent()
|
||||
self.visit(suite)
|
||||
self.dedent()
|
||||
if node.else_:
|
||||
self.writeline()
|
||||
self.write("else")
|
||||
edges = self.getEdge(node.else_)
|
||||
if edges is not None:
|
||||
edgeTests = [e._toVHDL() for e in edges]
|
||||
self.write("elsif ")
|
||||
self.write("or ".join(edgeTests))
|
||||
self.write(" then")
|
||||
else:
|
||||
self.write("else")
|
||||
self.indent()
|
||||
self.visit(node.else_)
|
||||
self.dedent()
|
||||
@ -765,13 +779,19 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
elif n in self.ast.symdict:
|
||||
obj = self.ast.symdict[n]
|
||||
if isinstance(obj, bool):
|
||||
s = "%s" % int(obj)
|
||||
s = "'%s'" % int(obj)
|
||||
elif isinstance(obj, (int, long)):
|
||||
self.writeIntSize(obj)
|
||||
s = str(obj)
|
||||
elif isinstance(obj, Signal):
|
||||
addSignBit = isMixedExpr
|
||||
s = str(obj)
|
||||
if context == _context.PRINT:
|
||||
s = "integer'image(to_integer(%s))" % str(obj)
|
||||
elif context == _context.BOOLEAN and \
|
||||
obj._type is bool:
|
||||
s = "%s = '1'" % str(obj)
|
||||
else:
|
||||
addSignBit = isMixedExpr
|
||||
s = str(obj)
|
||||
elif _isMem(obj):
|
||||
m = _getMemInfo(obj)
|
||||
assert m.name
|
||||
@ -796,13 +816,11 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
self.write("// pass")
|
||||
|
||||
def handlePrint(self, node):
|
||||
self.write('$display(')
|
||||
assert len(node.nodes) == 1
|
||||
self.write('report ')
|
||||
s = node.nodes[0]
|
||||
self.visit(s, _context.PRINT)
|
||||
for s in node.nodes[1:]:
|
||||
self.write(', , ')
|
||||
self.visit(s, _context.PRINT)
|
||||
self.write(');')
|
||||
self.write(';')
|
||||
|
||||
def visitPrint(self, node, *args):
|
||||
self.handlePrint(node)
|
||||
@ -912,7 +930,7 @@ class _ConvertVisitor(_ToVerilogMixin):
|
||||
yieldObj = self.getObj(node.value)
|
||||
if isinstance(yieldObj, delay):
|
||||
self.write("for ")
|
||||
elif isinstance(yieldObj, _EdgeDetector):
|
||||
elif isinstance(yieldObj, _WaiterList):
|
||||
self.write("until ")
|
||||
else:
|
||||
self.write("on ")
|
||||
@ -954,7 +972,7 @@ class _ConvertInitialVisitor(_ConvertVisitor):
|
||||
self.funcBuf = funcBuf
|
||||
|
||||
def visitFunction(self, node, *args):
|
||||
self.write("%s: process begin" % self.ast.name)
|
||||
self.write("%s: process is\nbegin" % self.ast.name)
|
||||
self.indent()
|
||||
self.writeDeclarations()
|
||||
self.visit(node.code)
|
||||
@ -1012,13 +1030,45 @@ class _ConvertAlwaysDecoVisitor(_ConvertVisitor):
|
||||
self.funcBuf = funcBuf
|
||||
|
||||
def visitFunction(self, node, *args):
|
||||
self.write("%s: process (" % self.ast.name)
|
||||
assert self.ast.senslist
|
||||
for e in self.ast.senslist[:-1]:
|
||||
self.write(e._toVHDL())
|
||||
senslist = self.ast.senslist
|
||||
first = senslist[0]
|
||||
if isinstance(first, _WaiterList):
|
||||
bt = _WaiterList
|
||||
elif isinstance(first, Signal):
|
||||
bt = Signal
|
||||
elif isinstance(first, delay):
|
||||
bt = delay
|
||||
assert bt
|
||||
for e in senslist:
|
||||
if not isinstance(e, bt):
|
||||
self.raiseError(node, "base type error in sensitivity list")
|
||||
if len(senslist) >= 2 and bt == _WaiterList:
|
||||
ifnode = node.code.nodes[0]
|
||||
assert isinstance(ifnode, astNode.If)
|
||||
asyncEdges = []
|
||||
for test, suite in ifnode.tests:
|
||||
e = self.getEdge(test)
|
||||
if e is None:
|
||||
self.raiseError(node, "no edge test")
|
||||
asyncEdges.append(e)
|
||||
if ifnode.else_ is None:
|
||||
self.raiseError(node, "no else test")
|
||||
edges = []
|
||||
for s in senslist:
|
||||
for e in asyncEdges:
|
||||
if s is e:
|
||||
break
|
||||
else:
|
||||
edges.append(s)
|
||||
ifnode.else_.edge = edges
|
||||
senslist = [s.sig for s in senslist]
|
||||
self.write("%s: process (" % self.ast.name)
|
||||
for e in senslist[:-1]:
|
||||
self.write(e)
|
||||
self.write(', ')
|
||||
self.write(self.ast.senslist[-1]._toVHDL())
|
||||
self.write(")")
|
||||
self.write(senslist[-1])
|
||||
self.write(") is")
|
||||
self.writeline()
|
||||
self.write("begin")
|
||||
self.indent()
|
||||
|
@ -102,6 +102,16 @@ class _ToVerilogMixin(object):
|
||||
return node.kind
|
||||
return None
|
||||
|
||||
def getEdge(self, node):
|
||||
if hasattr(node, 'edge'):
|
||||
return node.edge
|
||||
return None
|
||||
|
||||
def getValue(self, node):
|
||||
if hasattr(node, 'value'):
|
||||
return node.value
|
||||
return None
|
||||
|
||||
def getVal(self, node):
|
||||
val = eval(_unparse(node), self.ast.symdict)
|
||||
return val
|
||||
|
@ -45,6 +45,7 @@ from myhdl._delay import delay
|
||||
from myhdl._toVerilog import _error, _access, _kind, _context, \
|
||||
_ToVerilogMixin, _Label
|
||||
from myhdl._extractHierarchy import _isMem, _UserDefinedVerilog
|
||||
from myhdl._Signal import _WaiterList
|
||||
|
||||
myhdlObjects = myhdl.__dict__.values()
|
||||
builtinObjects = __builtin__.__dict__.values()
|
||||
@ -129,7 +130,7 @@ def _analyzeGens(top, absnames):
|
||||
s = re.sub(r"@.*", "", s)
|
||||
s = s.lstrip()
|
||||
ast = compiler.parse(s)
|
||||
#print ast
|
||||
print ast
|
||||
ast.sourcefile = inspect.getsourcefile(f)
|
||||
ast.lineoffset = inspect.getsourcelines(f)[1]-1
|
||||
ast.symdict = f.func_globals.copy()
|
||||
@ -157,7 +158,7 @@ def _analyzeGens(top, absnames):
|
||||
s = re.sub(r"@.*", "", s)
|
||||
s = s.lstrip()
|
||||
ast = compiler.parse(s)
|
||||
#print ast
|
||||
print ast
|
||||
ast.sourcefile = inspect.getsourcefile(f)
|
||||
ast.lineoffset = inspect.getsourcelines(f)[1]-1
|
||||
ast.symdict = f.f_globals.copy()
|
||||
@ -270,6 +271,7 @@ class _NotSupportedVisitor(_ToVerilogMixin):
|
||||
if node.dest is not None:
|
||||
self.raiseError(node, _error.NotSupported, "printing to a file with >> syntax")
|
||||
self.visitChildNodes(node, *args)
|
||||
self.ast.hasPrint = True
|
||||
|
||||
visitPrint = visitPrintnl
|
||||
|
||||
@ -308,8 +310,8 @@ class ReferenceStack(list):
|
||||
return False
|
||||
|
||||
# auxiliary types to aid type checking
|
||||
class _EdgeDetector(object):
|
||||
pass
|
||||
## class _EdgeDetector(object):
|
||||
## pass
|
||||
|
||||
class _Ram(object):
|
||||
__slots__ = ['elObj', 'depth']
|
||||
@ -339,6 +341,7 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
ast.kind = None
|
||||
ast.isGen = False
|
||||
ast.hasRom = False
|
||||
ast.hasPrint = False
|
||||
self.ast = ast
|
||||
self.labelStack = []
|
||||
self.refStack = ReferenceStack()
|
||||
@ -540,6 +543,11 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
if n.signed:
|
||||
node.signed = True
|
||||
op, arg = node.ops[0]
|
||||
node.expr.target = self.getObj(arg)
|
||||
print type(self.getObj(arg))
|
||||
arg.target = self.getObj(node.expr)
|
||||
print type(self.getObj(node.expr))
|
||||
print arg.target._type
|
||||
# detect specialized case for the test
|
||||
if op == '==' and isinstance(node.expr, astNode.Name):
|
||||
n = node.expr.name
|
||||
@ -549,21 +557,12 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
# check whether it can be part of an edge check
|
||||
elif n in self.ast.sigdict:
|
||||
sig = self.ast.sigdict[n]
|
||||
if isinstance(arg.obj, astNode.Const):
|
||||
v = arg.obj.value
|
||||
if value == 0:
|
||||
v = self.getValue(arg)
|
||||
if v is not None:
|
||||
if v == 0:
|
||||
node.edge = sig.negedge
|
||||
elif value == 1:
|
||||
elif v == 1:
|
||||
node.edge = sig.posedge
|
||||
elif isinstance(arg.obj, astNode.Name):
|
||||
c = arg.obj.name
|
||||
if c in self.ast.symdict:
|
||||
a = self.ast.symdict[n]
|
||||
if isinstance(a, int):
|
||||
if a == 0:
|
||||
node.edge = sig.negedge
|
||||
elif a == 1:
|
||||
node.edge = sig.posedge
|
||||
|
||||
|
||||
def visitConst(self, node, *args):
|
||||
@ -605,8 +604,10 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
node.signed = False
|
||||
obj = self.ast.symdict[node.expr.name]
|
||||
if isinstance(obj, Signal):
|
||||
if node.attrname in ('posedge', 'negedge'):
|
||||
node.obj = _EdgeDetector()
|
||||
if node.attrname == 'posedge':
|
||||
node.obj = obj.posedge
|
||||
elif node.attrname == 'negedge':
|
||||
node.obj = obj.negedge
|
||||
elif node.attrname == 'val':
|
||||
node.obj = obj.val
|
||||
elif isinstance(obj, EnumType):
|
||||
@ -698,11 +699,14 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
if isTupleOfInts(node.obj):
|
||||
node.obj = _Rom(node.obj)
|
||||
self.ast.hasRom = True
|
||||
elif isinstance(node.obj, int):
|
||||
node.value = node.obj
|
||||
elif n in __builtin__.__dict__:
|
||||
node.obj = __builtin__.__dict__[n]
|
||||
else:
|
||||
pass
|
||||
node.signed = _isNegative(node.obj)
|
||||
node.target = node.obj
|
||||
|
||||
def visitReturn(self, node, *args):
|
||||
self.raiseError(node, _error.NotSupported, "return statement")
|
||||
@ -763,13 +767,16 @@ class _AnalyzeVisitor(_ToVerilogMixin):
|
||||
self.ast.isGen = True
|
||||
n = node.value
|
||||
self.visit(n)
|
||||
senslist = []
|
||||
if isinstance(n, astNode.Tuple):
|
||||
for n in n.nodes:
|
||||
if not type(n.obj) in (Signal, _EdgeDetector):
|
||||
if not isinstance(n.obj, (Signal, _WaiterList)):
|
||||
self.raiseError(node, _error.UnsupportedYield)
|
||||
senslist.append(n.obj)
|
||||
else:
|
||||
if not type(n.obj) in (Signal, _EdgeDetector, delay):
|
||||
if not isinstance(n.obj, (Signal, _WaiterList, delay)):
|
||||
self.raiseError(node, _error.UnsupportedYield)
|
||||
senlist = [n.obj]
|
||||
|
||||
|
||||
class _AnalyzeBlockVisitor(_AnalyzeVisitor):
|
||||
|
Loading…
x
Reference in New Issue
Block a user