mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
commit
4349b6169c
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
||||
|
||||
|
90
myhdl/test/conversion/toVerilog/test_tristate.py
Normal file
90
myhdl/test/conversion/toVerilog/test_tristate.py
Normal 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()
|
Loading…
x
Reference in New Issue
Block a user