1
0
mirror of https://github.com/myhdl/myhdl.git synced 2024-12-14 07:44:38 +08:00

simple always blocks to assign statements

non-local objects should be signals check
This commit is contained in:
jand 2005-08-05 09:48:59 +00:00
parent 8225583303
commit 4f645619d4
5 changed files with 85 additions and 22 deletions

View File

@ -62,10 +62,11 @@ _error.UnsupportedListComp = \
"Unsupported list comprehension form: should be [intbv()[n:] for i in range(m)]"
_error.ListElementAssign = \
"Can't assign to list element; use slice assignment to change its value"
_error.NotASignal = "Non-local object should be a Signal"
_access = enum("INPUT", "OUTPUT", "INOUT", "UNKNOWN")
_kind = enum("NORMAL", "DECLARATION", "ALWAYS", "INITIAL", "ALWAYS_COMB", "TASK")
_kind = enum("NORMAL", "DECLARATION", "ALWAYS", "INITIAL", "ALWAYS_COMB", "SIMPLE_ALWAYS_COMB", "TASK", "REG")
_context = enum("BOOLEAN", "YIELD", "PRINT", "UNKNOWN")

View File

@ -89,7 +89,7 @@ def _analyzeGens(top, genNames):
s = inspect.getsource(f)
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()
@ -110,7 +110,7 @@ def _analyzeGens(top, genNames):
s = inspect.getsource(f)
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()
@ -325,6 +325,8 @@ class _AnalyzeVisitor(_ToVerilogMixin):
node.obj = int()
def visitAssAttr(self, node, access=_access.OUTPUT, *args):
if node.attrname != 'next':
self.raiseError(node, _error.NotSupported, "attribute assignment")
self.ast.kind = _kind.TASK
self.visit(node.expr, _access.OUTPUT)
@ -544,6 +546,8 @@ class _AnalyzeVisitor(_ToVerilogMixin):
self.ast.inputs.add(n)
elif access == _access.OUTPUT:
self.ast.kind = _kind.TASK
if n in self.ast.outputs:
node.kind = _kind.REG
self.ast.outputs.add(n)
elif access == _access.UNKNOWN:
pass
@ -650,7 +654,7 @@ class _AnalyzeBlockVisitor(_AnalyzeVisitor):
s = self.ast.sigdict[n]
if s._driven:
self.raiseError(node, _error.SigMultipleDriven, n)
s._driven = True
s._driven = "reg"
for n in self.ast.inputs:
s = self.ast.sigdict[n]
s._read = True
@ -668,18 +672,33 @@ class _AnalyzeBlockVisitor(_AnalyzeVisitor):
class _AnalyzeAlwaysCombVisitor(_AnalyzeBlockVisitor):
def __init__(self, ast, senslist):
_AnalyzeVisitor.__init__(self, ast)
_AnalyzeBlockVisitor.__init__(self, ast)
self.ast.senslist = senslist
for n, v in self.ast.symdict.items():
if isinstance(v, Signal):
self.ast.sigdict[n] = v
def visitFunction(self, node, *args):
self.refStack.push()
self.visit(node.code)
self.ast.kind = _kind.SIMPLE_ALWAYS_COMB
for n in node.code.nodes:
if isinstance(n, astNode.Assign) and \
isinstance(n.nodes[0], astNode.AssAttr) and \
self.getKind(n.nodes[0].expr) != _kind.REG:
pass
else:
self.ast.kind = _kind.ALWAYS_COMB
return
self.refStack.pop()
def visitModule(self, node, *args):
_AnalyzeBlockVisitor.visitModule(self, node, *args)
if self.ast.kind == _kind.SIMPLE_ALWAYS_COMB:
for n in self.ast.outputs:
s = self.ast.sigdict[n]
s._driven = "wire"
class _AnalyzeFuncVisitor(_AnalyzeVisitor):

View File

@ -123,7 +123,7 @@ def _writeModuleHeader(f, intf):
r = _getRangeString(s)
if s._driven:
print >> f, "output %s%s;" % (r, portname)
print >> f, "reg %s%s;" % (r, portname)
print >> f, "%s %s%s;" % (s._driven, r, portname)
else:
print >> f, "input %s%s;" % (r, portname)
print >> f
@ -137,8 +137,8 @@ def _writeSigDecls(f, intf, siglist):
r = _getRangeString(s)
if s._driven:
# the following line implements initial value assignments
print >> f, "reg %s%s = %s;" % (r, s._name, int(s._val))
# print >> f, "reg %s%s;" % (r, s._name)
print >> f, "%s %s%s = %s;" % (s._driven, r, s._name, int(s._val))
# print >> f, "%s %s%s;" % (s._driven, r, s._name)
elif s._read:
# the original exception
# raise ToVerilogError(_error.UndrivenSignal, s._name)
@ -210,6 +210,8 @@ def _convertGens(genlist, vfile):
Visitor = _ConvertAlwaysVisitor
elif ast.kind == _kind.INITIAL:
Visitor = _ConvertInitialVisitor
elif ast.kind == _kind.SIMPLE_ALWAYS_COMB:
Visitor = _ConvertSimpleAlwaysCombVisitor
else: # ALWAYS_COMB
Visitor = _ConvertAlwaysCombVisitor
v = Visitor(ast, blockBuf, funcBuf)
@ -331,8 +333,7 @@ class _ConvertVisitor(_ToVerilogMixin):
self.unaryOp(node, '-')
def visitAssAttr(self, node, *args):
if node.attrname != 'next':
self.raiseError(node, _error.NotSupported, "attribute assignment")
assert node.attrname == 'next'
self.isSigAss = True
self.visit(node.expr)
@ -398,7 +399,7 @@ class _ConvertVisitor(_ToVerilogMixin):
return
elif f in (int, long):
opening, closing = '', ''
elif type(f) in (ClassType, type) and issubclass(f, Exception):
elif type(f) is ClassType and issubclass(f, Exception):
self.write(f.__name__)
elif f in (posedge, negedge):
opening, closing = ' ', ''
@ -618,8 +619,10 @@ class _ConvertVisitor(_ToVerilogMixin):
self.write(obj._name)
elif str(type(obj)) == "<class 'myhdl._enum.EnumItem'>":
self.write(obj._toVerilog())
else:
elif type(obj) is ClassType and issubclass(obj, Exception):
self.write(n)
else:
self.raiseError(node, _error.NotASignal, n)
else:
raise AssertionError("name ref: %s" % n)
@ -794,6 +797,21 @@ class _ConvertAlwaysCombVisitor(_ConvertVisitor):
self.writeline(2)
class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
def __init__(self, ast, blockBuf, funcBuf):
_ConvertVisitor.__init__(self, ast, blockBuf)
self.funcBuf = funcBuf
def visitAssAttr(self, node, *args):
self.write("assign ")
self.visit(node.expr)
def visitFunction(self, node, *args):
self.visit(node.code)
self.writeline()
class _ConvertFunctionVisitor(_ConvertVisitor):
def __init__(self, ast, funcBuf):

View File

@ -28,12 +28,14 @@ import unittest
import test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \
test_inc_initial, test_hec, test_loops, test_infer, test_errors, \
test_RandomScrambler, test_beh, test_GrayInc, test_misc
test_RandomScrambler, test_beh, test_GrayInc, test_misc, \
test_memory
modules = (test_bin2gray, test_inc, test_fsm, test_ops, test_NotSupported, \
test_inc_initial, test_hec, test_loops, test_infer, test_errors, \
test_RandomScrambler, test_beh, test_GrayInc, test_misc
test_RandomScrambler, test_beh, test_GrayInc, test_misc, \
test_memory
)

View File

@ -20,6 +20,25 @@ def ram(dout, din, addr, we, clk, depth=128):
# a[2] = din
dout.next = mem[int(addr)]
def ram2(dout, din, addr, we, clk, depth=128):
memL = [intbv(0,min=dout._min,max=dout._max) for i in range(depth)]
def wrLogic() :
while 1:
yield posedge(clk)
if we:
memL[int(addr)][:] = din
def rdLogic() :
while 1:
yield posedge(clk)
dout.next = memL[int(addr)]
WL = wrLogic()
RL = rdLogic()
return WL,RL
objfile = "mem.o"
analyze_cmd = "iverilog -o %s mem_inst.v tb_mem_inst.v" % objfile
simulate_cmd = "vvp -m ../../../cosimulation/icarus/myhdl.vpi %s" % objfile
@ -32,7 +51,7 @@ def ram_v(dout, din, addr, we, clk, depth=4):
class TestMemory(TestCase):
def bench(self, depth=128):
def bench(self, ram, depth=128):
dout = Signal(intbv(0)[8:])
dout_v = Signal(intbv(0)[8:])
@ -68,8 +87,12 @@ class TestMemory(TestCase):
return clkgen(), stimulus(), mem_inst, mem_v_inst
def test(self):
sim = self.bench()
## def test1(self):
## sim = self.bench(ram)
## Simulation(sim).run()
def test2(self):
sim = self.bench(ram2)
Simulation(sim).run()
if __name__ == '__main__':