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

Merge pull request #21 from cogenda/issue_19

fix Issue 19
This commit is contained in:
jandecaluwe 2015-03-13 23:03:41 +01:00
commit 4349b6169c
6 changed files with 120 additions and 14 deletions

View File

@ -132,13 +132,18 @@ class Cosimulation(object):
e = buf.split()
for i in range(1, len(e), 2):
s, v = self._toSigDict[e[i]], e[i+1]
try:
next = int(v, 16)
if s._nrbits and s._min is not None and s._min < 0:
if next >= (1 << (s._nrbits-1)):
next |= (-1 << s._nrbits)
except ValueError:
next = intbv(0)
if v in 'zZ':
next = None
elif v in 'xX':
next = s._init
else:
try:
next = int(v, 16)
if s._nrbits and s._min is not None and s._min < 0:
if next >= (1 << (s._nrbits-1)):
next |= (-1 << s._nrbits)
except ValueError:
next = intbv(0)
s.next = next
self._getMode = 0

View File

@ -245,13 +245,15 @@ class _TristateSignal(_ShadowSignal):
def toVerilog(self):
lines = []
for d in self._drivers:
lines.append("assign %s = %s;" % (self._name, d._name))
if d._driven:
lines.append("assign %s = %s;" % (self._name, d._name))
return "\n".join(lines)
def toVHDL(self):
lines = []
for d in self._drivers:
lines.append("%s <= %s;" % (self._name, d._name))
if d._driven:
lines.append("%s <= %s;" % (self._name, d._name))
return "\n".join(lines)

View File

@ -42,7 +42,7 @@ from myhdl.conversion._misc import (_error, _access, _kind,
_ConversionMixin, _Label, _genUniqueSuffix)
from myhdl._extractHierarchy import _isMem, _getMemInfo, _UserCode
from myhdl._Signal import _Signal, _WaiterList
from myhdl._ShadowSignal import _ShadowSignal, _SliceSignal
from myhdl._ShadowSignal import _ShadowSignal, _SliceSignal, _TristateDriver
from myhdl._util import _isTupleOfInts, _dedent, _flatten, _makeAST
from myhdl._resolverefs import _AttrRefTransformer
from myhdl._compat import builtins, integer_types
@ -808,6 +808,9 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
# mark shadow signal as driven only when they are seen somewhere
if isinstance(sig, _ShadowSignal):
sig._driven = 'wire'
# mark tristate signal as driven if its driver is seen somewhere
if isinstance(sig, _TristateDriver):
sig._sig._driven = 'wire'
if not isinstance(sig, _Signal):
# print "not a signal: %s" % n
pass

View File

@ -173,9 +173,15 @@ class _ToVerilogConvertor(object):
_writeTestBench(tbfile, intf, self.trace)
tbfile.close()
# build portmap for cosimulation
portmap = {}
for n, s in intf.argdict.iteritems():
if hasattr(s, 'driver'): portmap[n] = s.driver()
else: portmap[n] = s
self.portmap = portmap
### clean-up properly ###
self._cleanup(siglist)
self.portmap = intf.argdict
return h.top
@ -322,7 +328,7 @@ def _writeSigDecls(f, intf, siglist, memlist):
print(file=f)
# shadow signal assignments
for s in siglist:
if hasattr(s, 'toVerilog') and s._read:
if hasattr(s, 'toVerilog') and s._driven:
print(s.toVerilog(), file=f)
print(file=f)

View File

@ -28,14 +28,14 @@ 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_ram, test_rom, test_always_comb, test_dec, test_signed, \
test_edge, test_custom, test_newcustom
test_edge, test_custom, test_newcustom, test_tristate
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_ram, test_rom, test_always_comb, test_dec, test_signed, \
test_edge, test_custom
test_edge, test_custom, test_tristate
)

View File

@ -0,0 +1,90 @@
import os
path = os.path
import unittest
from myhdl import *
from util import setupCosimulation
def tristate_obuf(A, Y, OE):
'''three-state output buffer'''
Y_d = Y.driver()
@always_comb
def hdl():
Y_d.next = A if OE else None
return hdl
class OBuf(object):
def __init__(self):
self.Y = TristateSignal(True)
self.A = Signal(False)
self.OE = Signal(False)
def interface(self):
return self.A, self.Y, self.OE
def tristate_obuf_i(obuf):
'''three-state output buffer, using interface'''
# Caveat: A local name of the interface signals must be declared,
# Otherwise, _HierExtr.extract() will not add them to symdict
# and conversion will fail.
A, Y, OE = obuf.interface()
Y_d = Y.driver()
@always_comb
def hdl():
Y_d.next = A if OE else None
return hdl
class TestTristate(unittest.TestCase):
def bench(self, obuf=None):
if obuf:
toVerilog(tristate_obuf_i, obuf)
A, Y, OE = obuf.interface()
else:
Y = TristateSignal(True)
A = Signal(True)
OE = Signal(False)
toVerilog(tristate_obuf, A, Y, OE)
inst = setupCosimulation(name='tristate_obuf', **toVerilog.portmap)
#inst = tristate_obuf(A, Y, OE)
@instance
def stimulus():
yield delay(1)
#print now(), A, OE, Y
self.assertEqual(Y, None)
OE.next = True
yield delay(1)
#print now(), A, OE, Y
self.assertEqual(Y, A)
A.next = not A
yield delay(1)
#print now(), A, OE, Y
self.assertEqual(Y, A)
OE.next = False
yield delay(1)
#print now(), A, OE, Y
self.assertEqual(Y, None)
raise StopSimulation
return instances()
def testOBuf(self):
sim = Simulation(self.bench())
sim.run()
def testOBufInterface(self):
obuf = OBuf()
sim = Simulation(self.bench(obuf))
sim.run()
if __name__ == '__main__':
unittest.main()