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

cosimulatoin module added

This commit is contained in:
jand 2003-04-03 22:15:22 +00:00
parent eec897efdc
commit 23b5c1183d
4 changed files with 273 additions and 2 deletions

110
myhdl/Cosimulation.py Normal file
View 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

View File

@ -35,7 +35,7 @@ from types import GeneratorType
schedule = _futureEvents.append
class Simulation:
class Simulation(object):
""" Simulation class.
@ -194,7 +194,7 @@ class StopSimulation(exceptions.Exception):
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):
""" Construct join object

View File

@ -31,6 +31,7 @@ join -- callable to join clauses in a yield statement
intbv -- mutable integer class with bit vector facilities
downrange -- function that returns a downward range
bin -- returns a binary string representation.
Error -- myhdl Error exception
The optional width specifies the desired string
width: padding of the sign-bit is used.
@ -46,6 +47,7 @@ import Simulation
import delay
import intbv
import _simulator
import Cosimulation
StopSimulation = Simulation.StopSimulation
join = Simulation.join
@ -56,6 +58,7 @@ Signal = Signal.Signal
now = _simulator.now
delay = delay.delay
intbv = intbv.intbv
Cosimulation = Cosimulation.Cosimulation
def downrange(start, stop=0):
""" Return a downward range. """
@ -83,5 +86,8 @@ def bin(num, width=0):
pad = '1'
return (width - len(s)) * pad + s
class Error(Exception):
pass

155
myhdl/test_Cosimulation.py Normal file
View 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()