mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
cosimulatoin module added
This commit is contained in:
parent
eec897efdc
commit
23b5c1183d
110
myhdl/Cosimulation.py
Normal file
110
myhdl/Cosimulation.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
""" Module that provides the Cosimulation class """
|
||||||
|
|
||||||
|
__author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||||
|
__version__ = "$Revision$"
|
||||||
|
__date__ = "$Date$"
|
||||||
|
|
||||||
|
from __future__ import generators
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import exceptions
|
||||||
|
|
||||||
|
from Signal import Signal
|
||||||
|
import myhdl
|
||||||
|
|
||||||
|
_flag = 0
|
||||||
|
MAXLINE = 4096
|
||||||
|
|
||||||
|
class Cosimulation(object):
|
||||||
|
|
||||||
|
""" Cosimulation class. """
|
||||||
|
|
||||||
|
def __init__(self, exe="", **kwargs):
|
||||||
|
|
||||||
|
""" Construct a cosimulation object. """
|
||||||
|
|
||||||
|
global _flag
|
||||||
|
if _flag:
|
||||||
|
raise myhdl.Error, "Cosimulation: Only a single cosimulator allowed"
|
||||||
|
_flag = 1
|
||||||
|
|
||||||
|
self.rt, self.wt = rt, wt = os.pipe()
|
||||||
|
self.rf, self.wf = rf, wf = os.pipe()
|
||||||
|
|
||||||
|
self._fromSigs = []
|
||||||
|
self._fromSizes = []
|
||||||
|
self._toSigs = []
|
||||||
|
self._toSizes = []
|
||||||
|
|
||||||
|
child_pid = os.fork()
|
||||||
|
|
||||||
|
if child_pid == 0:
|
||||||
|
os.close(rt)
|
||||||
|
os.close(wf)
|
||||||
|
os.environ['MYHDL_TO_PIPE'] = str(wt)
|
||||||
|
os.environ['MYHDL_FROM_PIPE'] = str(rf)
|
||||||
|
arglist = exe.split()
|
||||||
|
try:
|
||||||
|
os.execvp(arglist[0], arglist)
|
||||||
|
except OSError, e:
|
||||||
|
raise myhdl.Error, "Cosimulation: " + str(e)
|
||||||
|
else:
|
||||||
|
os.close(wt)
|
||||||
|
os.close(rf)
|
||||||
|
while 1:
|
||||||
|
s = os.read(rt, MAXLINE)
|
||||||
|
if not s:
|
||||||
|
raise myhdl.Error, "Cosimulation down"
|
||||||
|
e = s.split()
|
||||||
|
if e[0] == "FROM":
|
||||||
|
self._fromSigs = [e[i] for i in range(1, len(e), 2)]
|
||||||
|
self._fromSizes = [int(e[i]) for i in range(2, len(e), 2)]
|
||||||
|
os.write(wf, "OK")
|
||||||
|
elif e[0] == "TO":
|
||||||
|
self._toSigs = [e[i] for i in range(1, len(e), 2)]
|
||||||
|
self._toSizes = [int(e[i]) for i in range(2, len(e), 2)]
|
||||||
|
os.write(wf, "OK")
|
||||||
|
else:
|
||||||
|
self.buf = e
|
||||||
|
break
|
||||||
|
if long(e[0]) != 0:
|
||||||
|
raise myhdl.Error, "Cosimulation: myhdl call when not at time 0"
|
||||||
|
if not self._fromSigs and not self._toSigs:
|
||||||
|
raise myhdl.Error, "Cosimulation: no communicating signals"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
""" Clear flag when this object destroyed - to suite unittest. """
|
||||||
|
global _flag
|
||||||
|
_flag = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ from types import GeneratorType
|
|||||||
|
|
||||||
schedule = _futureEvents.append
|
schedule = _futureEvents.append
|
||||||
|
|
||||||
class Simulation:
|
class Simulation(object):
|
||||||
|
|
||||||
""" Simulation class.
|
""" Simulation class.
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ class StopSimulation(exceptions.Exception):
|
|||||||
|
|
||||||
class join(object):
|
class join(object):
|
||||||
|
|
||||||
""" Join trigger objects to from a single trigger object. """
|
""" Join trigger objects to form a single trigger object. """
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
""" Construct join object
|
""" Construct join object
|
||||||
|
@ -31,6 +31,7 @@ join -- callable to join clauses in a yield statement
|
|||||||
intbv -- mutable integer class with bit vector facilities
|
intbv -- mutable integer class with bit vector facilities
|
||||||
downrange -- function that returns a downward range
|
downrange -- function that returns a downward range
|
||||||
bin -- returns a binary string representation.
|
bin -- returns a binary string representation.
|
||||||
|
Error -- myhdl Error exception
|
||||||
|
|
||||||
The optional width specifies the desired string
|
The optional width specifies the desired string
|
||||||
width: padding of the sign-bit is used.
|
width: padding of the sign-bit is used.
|
||||||
@ -46,6 +47,7 @@ import Simulation
|
|||||||
import delay
|
import delay
|
||||||
import intbv
|
import intbv
|
||||||
import _simulator
|
import _simulator
|
||||||
|
import Cosimulation
|
||||||
|
|
||||||
StopSimulation = Simulation.StopSimulation
|
StopSimulation = Simulation.StopSimulation
|
||||||
join = Simulation.join
|
join = Simulation.join
|
||||||
@ -56,6 +58,7 @@ Signal = Signal.Signal
|
|||||||
now = _simulator.now
|
now = _simulator.now
|
||||||
delay = delay.delay
|
delay = delay.delay
|
||||||
intbv = intbv.intbv
|
intbv = intbv.intbv
|
||||||
|
Cosimulation = Cosimulation.Cosimulation
|
||||||
|
|
||||||
def downrange(start, stop=0):
|
def downrange(start, stop=0):
|
||||||
""" Return a downward range. """
|
""" Return a downward range. """
|
||||||
@ -83,5 +86,8 @@ def bin(num, width=0):
|
|||||||
pad = '1'
|
pad = '1'
|
||||||
return (width - len(s)) * pad + s
|
return (width - len(s)) * pad + s
|
||||||
|
|
||||||
|
class Error(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
155
myhdl/test_Cosimulation.py
Normal file
155
myhdl/test_Cosimulation.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# 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 unit tests for Cosimulation """
|
||||||
|
|
||||||
|
__author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||||
|
__version__ = "$Revision$"
|
||||||
|
__date__ = "$Date$"
|
||||||
|
|
||||||
|
from __future__ import generators
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import errno
|
||||||
|
import unittest
|
||||||
|
from unittest import TestCase
|
||||||
|
import random
|
||||||
|
from random import randrange
|
||||||
|
random.seed(1) # random, but deterministic
|
||||||
|
|
||||||
|
MAXLINE = 4096
|
||||||
|
|
||||||
|
from myhdl import Cosimulation, Error
|
||||||
|
|
||||||
|
class CosimulationTest(TestCase):
|
||||||
|
|
||||||
|
exe = "python test_Cosimulation.py CosimulationTest"
|
||||||
|
|
||||||
|
fromSigs = ['a', 'bb', 'ccc']
|
||||||
|
fromSizes = [1, 11, 63]
|
||||||
|
toSigs = ['d', 'ee', 'fff', 'g']
|
||||||
|
toSizes = [32, 12, 3, 6]
|
||||||
|
|
||||||
|
def testWrongExe(self):
|
||||||
|
self.assertRaises(Error, Cosimulation, "bla -x 45")
|
||||||
|
|
||||||
|
def testNotUnique(self):
|
||||||
|
cosim1 = Cosimulation(self.exe + ".cosimNotUnique")
|
||||||
|
self.assertRaises(Error, Cosimulation, self.exe + ".cosimNotUnique")
|
||||||
|
|
||||||
|
def cosimNotUnique(self):
|
||||||
|
wt = int(os.environ['MYHDL_TO_PIPE'])
|
||||||
|
rf = int(os.environ['MYHDL_FROM_PIPE'])
|
||||||
|
os.write(wt, "TO a")
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
os.write(wt, "FROM d")
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
os.write(wt, "0000")
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
|
||||||
|
def testFromSignals(self):
|
||||||
|
cosim = Cosimulation(self.exe + ".cosimFromSignals")
|
||||||
|
self.assertEqual(cosim._fromSigs, self.fromSigs)
|
||||||
|
self.assertEqual(cosim._fromSizes, self.fromSizes)
|
||||||
|
self.assertEqual(cosim._toSigs, [])
|
||||||
|
self.assertEqual(cosim._toSizes, [])
|
||||||
|
|
||||||
|
def cosimFromSignals(self):
|
||||||
|
wt = int(os.environ['MYHDL_TO_PIPE'])
|
||||||
|
rf = int(os.environ['MYHDL_FROM_PIPE'])
|
||||||
|
buf = "FROM "
|
||||||
|
for s, w in zip(self.fromSigs, self.fromSizes):
|
||||||
|
buf += "%s %s " % (s, w)
|
||||||
|
os.write(wt, buf)
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
os.write(wt, "0000")
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
|
||||||
|
def testToSignals(self):
|
||||||
|
cosim = Cosimulation(self.exe + ".cosimToSignals")
|
||||||
|
self.assertEqual(cosim._fromSigs, [])
|
||||||
|
self.assertEqual(cosim._fromSizes, [])
|
||||||
|
self.assertEqual(cosim._toSigs, self.toSigs)
|
||||||
|
self.assertEqual(cosim._toSizes, self.toSizes)
|
||||||
|
|
||||||
|
def cosimToSignals(self):
|
||||||
|
wt = int(os.environ['MYHDL_TO_PIPE'])
|
||||||
|
rf = int(os.environ['MYHDL_FROM_PIPE'])
|
||||||
|
buf = "TO "
|
||||||
|
for s, w in zip(self.toSigs, self.toSizes):
|
||||||
|
buf += "%s %s " % (s, w)
|
||||||
|
os.write(wt, buf)
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
os.write(wt, "0000")
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
|
||||||
|
def testFromToSignals(self):
|
||||||
|
cosim = Cosimulation(self.exe + ".cosimFromToSignals")
|
||||||
|
self.assertEqual(cosim._fromSigs, self.fromSigs)
|
||||||
|
self.assertEqual(cosim._fromSizes, self.fromSizes)
|
||||||
|
self.assertEqual(cosim._toSigs, self.toSigs)
|
||||||
|
self.assertEqual(cosim._toSizes, self.toSizes)
|
||||||
|
|
||||||
|
def cosimFromToSignals(self):
|
||||||
|
wt = int(os.environ['MYHDL_TO_PIPE'])
|
||||||
|
rf = int(os.environ['MYHDL_FROM_PIPE'])
|
||||||
|
buf = "FROM "
|
||||||
|
for s, w in zip(self.fromSigs, self.fromSizes):
|
||||||
|
buf += "%s %s " % (s, w)
|
||||||
|
os.write(wt, buf)
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
buf = "TO "
|
||||||
|
for s, w in zip(self.toSigs, self.toSizes):
|
||||||
|
buf += "%s %s " % (s, w)
|
||||||
|
os.write(wt, buf)
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
os.write(wt, "0000")
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
|
||||||
|
def testTimeZero(self):
|
||||||
|
self.assertRaises(Error, Cosimulation, self.exe + ".cosimTimeZero")
|
||||||
|
|
||||||
|
def cosimTimeZero(self):
|
||||||
|
wt = int(os.environ['MYHDL_TO_PIPE'])
|
||||||
|
rf = int(os.environ['MYHDL_FROM_PIPE'])
|
||||||
|
buf = "FROM "
|
||||||
|
for s, w in zip(self.fromSigs, self.fromSizes):
|
||||||
|
buf += "%s %s " % (s, w)
|
||||||
|
os.write(wt, buf)
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
os.write(wt, "0001")
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
|
||||||
|
def testNoComm(self):
|
||||||
|
self.assertRaises(Error, Cosimulation, self.exe + ".cosimNoComm")
|
||||||
|
|
||||||
|
def cosimNoComm(self):
|
||||||
|
wt = int(os.environ['MYHDL_TO_PIPE'])
|
||||||
|
rf = int(os.environ['MYHDL_FROM_PIPE'])
|
||||||
|
os.write(wt, "0000")
|
||||||
|
os.read(rf, MAXLINE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user