diff --git a/cosimulation/icarus/myhdl.c b/cosimulation/icarus/myhdl.c index fa5c84ea..03bc1fd8 100644 --- a/cosimulation/icarus/myhdl.c +++ b/cosimulation/icarus/myhdl.c @@ -87,7 +87,9 @@ static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data) init_pipes(); +#ifdef DEBUG vpi_printf("Hello from $from_myhdl %d %d\n", rpipe, wpipe); +#endif from_myhdl_systf_handle = vpi_handle(vpiSysTfCall, NULL); net_iter = vpi_iterate(vpiArgument, from_myhdl_systf_handle); @@ -136,7 +138,9 @@ static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data) init_pipes(); +#ifdef DEBUG vpi_printf("Hello from $to_myhdl %d %d\n", rpipe, wpipe); +#endif to_myhdl_systf_handle = vpi_handle(vpiSysTfCall, NULL); net_iter = vpi_iterate(vpiArgument, to_myhdl_systf_handle); diff --git a/cosimulation/icarus/test/bin2gray.py b/cosimulation/icarus/test/bin2gray.py new file mode 100644 index 00000000..9408348c --- /dev/null +++ b/cosimulation/icarus/test/bin2gray.py @@ -0,0 +1,14 @@ +import os + +from myhdl import Cosimulation + +cmd = "iverilog -o bin2gray -Dwidth=%s " + \ + "../../test/verilog/bin2gray.v " + \ + "../../test/verilog/dut_bin2gray.v " + +def bin2gray(B, G, width): + os.system(cmd % width) + return Cosimulation("vvp -m ../myhdl.vpi bin2gray", B=B, G=G) + + + diff --git a/cosimulation/icarus/test/test_all.py b/cosimulation/icarus/test/test_all.py new file mode 100644 index 00000000..1b74a3b0 --- /dev/null +++ b/cosimulation/icarus/test/test_all.py @@ -0,0 +1,49 @@ +# This file is part of the myhdl library, a Python package for using +# Python as a Hardware Description Language. +# +# Copyright (C) 2003 Jan Decaluwe +# +# The myhdl library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" Run cosimulatoin unit tests. """ + +__author__ = "Jan Decaluwe " +__version__ = "$Revision$" +__date__ = "$Date$" + +import sys + +sys.path.append("../../test") + +import test_bin2gray + +modules = (test_bin2gray, ) + +import unittest + +tl = unittest.defaultTestLoader +def suite(): + alltests = unittest.TestSuite() + for m in modules: + alltests.addTest(tl.loadTestsFromModule(m)) + return alltests + +def main(): + unittest.main(defaultTest='suite', + testRunner=unittest.TextTestRunner(verbosity=2)) + + +if __name__ == '__main__': + main() diff --git a/cosimulation/test/bin2gray.py b/cosimulation/test/bin2gray.py new file mode 100644 index 00000000..f2ef604e --- /dev/null +++ b/cosimulation/test/bin2gray.py @@ -0,0 +1,16 @@ +from __future__ import generators +from myhdl import Signal, delay, Simulation, intbv, bin + +def bin2gray(B, G, width): + """ Gray encoder. + + B -- input intbv signal, binary encoded + G -- output intbv signal, gray encoded + width -- bit width + """ + while 1: + yield B + for i in range(width): + G.next[i] = B[i+1] ^ B[i] + + diff --git a/cosimulation/test/test_all.py b/cosimulation/test/test_all.py new file mode 100644 index 00000000..1b74a3b0 --- /dev/null +++ b/cosimulation/test/test_all.py @@ -0,0 +1,49 @@ +# This file is part of the myhdl library, a Python package for using +# Python as a Hardware Description Language. +# +# Copyright (C) 2003 Jan Decaluwe +# +# The myhdl library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" Run cosimulatoin unit tests. """ + +__author__ = "Jan Decaluwe " +__version__ = "$Revision$" +__date__ = "$Date$" + +import sys + +sys.path.append("../../test") + +import test_bin2gray + +modules = (test_bin2gray, ) + +import unittest + +tl = unittest.defaultTestLoader +def suite(): + alltests = unittest.TestSuite() + for m in modules: + alltests.addTest(tl.loadTestsFromModule(m)) + return alltests + +def main(): + unittest.main(defaultTest='suite', + testRunner=unittest.TextTestRunner(verbosity=2)) + + +if __name__ == '__main__': + main() diff --git a/cosimulation/test/test_bin2gray.py b/cosimulation/test/test_bin2gray.py new file mode 100644 index 00000000..1d419598 --- /dev/null +++ b/cosimulation/test/test_bin2gray.py @@ -0,0 +1,115 @@ +from __future__ import generators + +import unittest +from unittest import TestCase + +from myhdl import Simulation, Signal, delay, intbv, bin + +from bin2gray import bin2gray + +MAX_WIDTH = 10 + +def nextLn(Ln): + """ Return Gray code Ln+1, given Ln. """ + Ln0 = ['0' + codeword for codeword in Ln] + Ln1 = ['1' + codeword for codeword in Ln] + Ln1.reverse() + return Ln0 + Ln1 + +## def bin2gray(B, G, width): +## while 1: +## yield B +## G.next = B[0] + +class TestOriginalGrayCode(TestCase): + + def testOriginalGrayCode(self): + + """ Check that the code is an original Gray code """ + + B = Signal(intbv(1)) + G = Signal(intbv(0)) + Rn = [] + + def stimulus(n): + for i in range(2**n): + B.next = intbv(i) + yield delay(10) + Rn.append(bin(G, width=n)) + + Ln = ['0', '1'] # n == 1 + for n in range(2, MAX_WIDTH): + Ln = nextLn(Ln) + del Rn[:] + dut = bin2gray(B, G, n) + sim = Simulation(dut, stimulus(n)) + sim.run(quiet=1) + self.assertEqual(Ln, Rn) + + +class TestGrayCodeProperties(TestCase): + + def testSingleBitChange(self): + + """ Check that only one bit changes in successive codewords """ + + B = Signal(intbv(1)) + G = Signal(intbv(0)) + G_Z = Signal(intbv(0)) + + def test(width): + B.next = intbv(0) + yield delay(10) + for i in range(1, 2**width): + G_Z.next = G + B.next = intbv(i) + yield delay(10) + diffcode = bin(G ^ G_Z) + self.assertEqual(diffcode.count('1'), 1) + + for width in range(1, MAX_WIDTH): + dut = bin2gray(B, G, width) + sim = Simulation(dut, test(width)) + sim.run(quiet=0) + + + def testUniqueCodeWords(self): + + """ Check that all codewords occur exactly once """ + + B = Signal(intbv(1)) + G = Signal(intbv(0)) + + def test(width): + actual = [] + for i in range(2**width): + B.next = intbv(i) + yield delay(10) + actual.append(int(G)) + actual.sort() + expected = range(2**width) + self.assertEqual(actual, expected) + + for width in range(1, MAX_WIDTH): + dut = bin2gray(B, G, width) + sim = Simulation(dut, test(width)) + sim.run(quiet=1) + + +if __name__ == '__main__': + unittest.main() + + + + + + + + + + + + + + + diff --git a/cosimulation/test/verilog/bin2gray.v b/cosimulation/test/verilog/bin2gray.v new file mode 100644 index 00000000..21c731c9 --- /dev/null +++ b/cosimulation/test/verilog/bin2gray.v @@ -0,0 +1,18 @@ +module bin2gray(B, G); + + parameter width = 8; + input [width-1:0] B; + output [width-1:0] G; + reg [width-1:0] G; + integer i; + wire [width:0] extB; + + assign extB = {1'b0, B}; + + always @(extB) begin + // $display("Ver B %D", extB); + for (i=0; i < width; i=i+1) + G[i] = extB[i+1] ^ extB[i]; + end + +endmodule // bin2gray diff --git a/cosimulation/test/verilog/dut_bin2gray.v b/cosimulation/test/verilog/dut_bin2gray.v new file mode 100644 index 00000000..8948e717 --- /dev/null +++ b/cosimulation/test/verilog/dut_bin2gray.v @@ -0,0 +1,14 @@ +module dut_bin2gray; + + reg [`width-1:0] B; + wire [`width-1:0] G; + + initial begin + $from_myhdl(B); + $to_myhdl(G); + end + + bin2gray dut (.B(B), .G(G)); + defparam dut.width = `width; + +endmodule // bin2gray diff --git a/myhdl/Cosimulation.py b/myhdl/Cosimulation.py index a77da52f..9ff7d23e 100644 --- a/myhdl/Cosimulation.py +++ b/myhdl/Cosimulation.py @@ -139,6 +139,7 @@ class Cosimulation(object): def _get(self): s = os.read(self._rt, _MAXLINE) + # print "Reading " + s if not s: raise SimulationEndError e = s.split() @@ -160,13 +161,16 @@ class Cosimulation(object): for s in self._fromSigs: buf += hex(s)[2:] buf += " " + # print "clear change" self._hasChange = 0 + # print "Writing " + buf os.write(self._wf, buf) def _waiter(self): sigs = tuple(self._fromSigs) while 1: yield sigs + # print "detected change" self._hasChange = 1 def __del__(self): diff --git a/myhdl/Simulation.py b/myhdl/Simulation.py index 78af8854..4a346715 100644 --- a/myhdl/Simulation.py +++ b/myhdl/Simulation.py @@ -127,6 +127,7 @@ class Simulation(object): else: raise TypeError, "Incorrect yield clause type" + # print _siglist if cosim: cosim._get() if _siglist or cosim._hasChange: @@ -137,6 +138,7 @@ class Simulation(object): if t == maxTime: raise StopSimulation, "Simulated for duration %s" % duration + # print _futureEvents if _futureEvents: _futureEvents.sort() t = sim._time = _futureEvents[0][0] @@ -157,6 +159,7 @@ class Simulation(object): os.close(cosim._rt) os.close(cosim._wf) os.waitpid(cosim._child_pid, 0) + _simulator._cosim = 0 raise StopSimulation, "No more events" except StopSimulation, e: