From 4f645619d4024a6c97da9989ea1a9b1f77ab7842 Mon Sep 17 00:00:00 2001 From: jand Date: Fri, 5 Aug 2005 09:48:59 +0000 Subject: [PATCH] simple always blocks to assign statements non-local objects should be signals check --- myhdl/_toVerilog/__init__.py | 3 ++- myhdl/_toVerilog/_analyze.py | 35 ++++++++++++++++++++++------- myhdl/_toVerilog/_convert.py | 32 ++++++++++++++++++++------ myhdl/test/toVerilog/test_all.py | 6 +++-- myhdl/test/toVerilog/test_memory.py | 31 +++++++++++++++++++++---- 5 files changed, 85 insertions(+), 22 deletions(-) diff --git a/myhdl/_toVerilog/__init__.py b/myhdl/_toVerilog/__init__.py index 657816a8..abcb73e3 100644 --- a/myhdl/_toVerilog/__init__.py +++ b/myhdl/_toVerilog/__init__.py @@ -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") diff --git a/myhdl/_toVerilog/_analyze.py b/myhdl/_toVerilog/_analyze.py index 18bc50fb..54e496e5 100644 --- a/myhdl/_toVerilog/_analyze.py +++ b/myhdl/_toVerilog/_analyze.py @@ -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,17 +672,32 @@ 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.ALWAYS_COMB + 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): diff --git a/myhdl/_toVerilog/_convert.py b/myhdl/_toVerilog/_convert.py index 219e9472..41b2ebbd 100644 --- a/myhdl/_toVerilog/_convert.py +++ b/myhdl/_toVerilog/_convert.py @@ -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)) == "": 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) @@ -792,7 +795,22 @@ class _ConvertAlwaysCombVisitor(_ConvertVisitor): self.writeline() self.write("end") 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): diff --git a/myhdl/test/toVerilog/test_all.py b/myhdl/test/toVerilog/test_all.py index 2e00946c..0edcd3d1 100644 --- a/myhdl/test/toVerilog/test_all.py +++ b/myhdl/test/toVerilog/test_all.py @@ -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 ) diff --git a/myhdl/test/toVerilog/test_memory.py b/myhdl/test/toVerilog/test_memory.py index f7a4105d..5529eea3 100644 --- a/myhdl/test/toVerilog/test_memory.py +++ b/myhdl/test/toVerilog/test_memory.py @@ -18,7 +18,26 @@ def ram(dout, din, addr, we, clk, depth=128): mem[int(addr)][:] = din # a = din.val # a[2] = din - dout.next = mem[int(addr)] + 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 @@ -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__':