mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
First working cosimulation unit test
This commit is contained in:
parent
61c5cd2671
commit
1301a23991
@ -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);
|
||||
|
14
cosimulation/icarus/test/bin2gray.py
Normal file
14
cosimulation/icarus/test/bin2gray.py
Normal file
@ -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)
|
||||
|
||||
|
||||
|
49
cosimulation/icarus/test/test_all.py
Normal file
49
cosimulation/icarus/test/test_all.py
Normal file
@ -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 <jan@jandecaluwe.com>"
|
||||
__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()
|
16
cosimulation/test/bin2gray.py
Normal file
16
cosimulation/test/bin2gray.py
Normal file
@ -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]
|
||||
|
||||
|
49
cosimulation/test/test_all.py
Normal file
49
cosimulation/test/test_all.py
Normal file
@ -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 <jan@jandecaluwe.com>"
|
||||
__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()
|
115
cosimulation/test/test_bin2gray.py
Normal file
115
cosimulation/test/test_bin2gray.py
Normal file
@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
18
cosimulation/test/verilog/bin2gray.v
Normal file
18
cosimulation/test/verilog/bin2gray.v
Normal file
@ -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
|
14
cosimulation/test/verilog/dut_bin2gray.v
Normal file
14
cosimulation/test/verilog/dut_bin2gray.v
Normal file
@ -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
|
@ -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):
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user