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:
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
|
||||
|
||||
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
|
||||
|
@ -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
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