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

Fix Icarus cosimulation vpi bug for static signals (#444)

* created a test that shows the cosimulation bug

* fix icarus vpi so that all to_myhdl signals are updated at least once even if they are static
This commit is contained in:
chiplukes 2024-10-05 02:07:42 -06:00 committed by GitHub
parent 75bb3a7598
commit f0da5a6fa2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 162 additions and 1 deletions

View File

@ -201,7 +201,9 @@ static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data) {
strcat(buf, " ");
sprintf(s, "%d ", vpi_get(vpiSize, net_handle));
strcat(buf, s);
changeFlag[i] = 0;
// initialize this to one such that Verilog signals that never
// change at least update the connected MyHDL Signal once
changeFlag[i] = 1;
id = malloc(sizeof(int));
*id = i;
cb_data_s.user_data = (PLI_BYTE8 *) id;

View File

@ -0,0 +1,12 @@
import os
from myhdl import Cosimulation
cmd = "iverilog -o const_1.o " + \
"../../test/verilog/const_1.v " + \
"../../test/verilog/dut_const_1.v "
def const_1(q, clk):
os.system(cmd)
return Cosimulation("vvp -m ../myhdl.vpi const_1.o", **locals())

View File

@ -0,0 +1,46 @@
# This file is part of the myhdl library, a Python package for using
# Python as a Hardware Description Language.
#
# Copyright (C) 2003-2008 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 cosimulation unit tests. """
import sys
sys.path.append("../../test")
#sys.path.append("../../../example/manual")
import test_const_1
modules = (test_const_1 )
import unittest
tl = unittest.defaultTestLoader
def suite():
alltests = unittest.TestSuite()
alltests.addTest(tl.loadTestsFromModule(test_const_1))
return alltests
def main():
unittest.main(defaultTest='suite',
testRunner=unittest.TextTestRunner(verbosity=2))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,80 @@
import unittest
from unittest import TestCase
import random
from random import randrange
random.seed(2)
from myhdl import Simulation, StopSimulation, Signal, \
delay, intbv, negedge, posedge, now
from const_1 import const_1
ACTIVE_LOW, INACTIVE_HIGH = 0, 1
class TestConst(TestCase):
vals = [randrange(2) for i in range(1000)]
def clkGen(self, clk):
while 1:
yield delay(10)
clk.next = not clk
def stimulus(self, clk):
for v in self.vals:
yield negedge(clk)
raise StopSimulation
def check(self, q, clk):
for v in self.vals:
yield posedge(clk)
self.assertEqual(q, 1)
def bench(self):
# Note: when this is initialized different (ie: 0) than the constant value of q (1)
# the cosimulation never updates the signal q and the assertion in check fails
q, clk = [Signal(intbv(0)) for i in range(2)]
CONST_1 = const_1(q, clk)
CLK_1 = self.clkGen(clk)
ST_1 = self.stimulus(clk)
CH_1 = self.check(q, clk)
sim = Simulation(CONST_1, CLK_1, ST_1, CH_1)
return sim
def test1(self):
""" const test """
sim = self.bench()
sim.run(quiet=1)
def test2(self):
""" const test with simulation suspends """
sim = self.bench()
while sim.run(duration=randrange(1,5), quiet=1):
pass
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,8 @@
module const_1(q, clk);
input clk;
output q;
wire q = 1;
endmodule // inc

View File

@ -0,0 +1,13 @@
module dut_const_1;
reg clk;
wire q;
initial begin
$from_myhdl(clk);
$to_myhdl(q);
end
const_1 dut (.q(q), .clk(clk) );
endmodule // inc