mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
always error checks
This commit is contained in:
parent
3c78606452
commit
58218d7df3
@ -23,29 +23,27 @@ __author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||
__revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
import sys
|
||||
import inspect
|
||||
from types import FunctionType
|
||||
import compiler
|
||||
from sets import Set
|
||||
import re
|
||||
|
||||
from myhdl import AlwaysError
|
||||
from myhdl._util import _isGenFunc
|
||||
from myhdl._delay import delay
|
||||
from myhdl._Signal import Signal, _WaiterList, posedge, negedge
|
||||
from myhdl._Waiter import _Waiter
|
||||
from myhdl._Waiter import _Waiter, _SignalWaiter, _SignalTupleWaiter, \
|
||||
_DelayWaiter, _EdgeWaiter, _EdgeTupleWaiter
|
||||
|
||||
class _error:
|
||||
pass
|
||||
_error.ArgType = "function with always decorator should be classic"
|
||||
_error.NrOfArgs = "function with always decorator should not have arguments"
|
||||
_error.DecArgType = "decorator argument should be a Signal, edge, or delay"
|
||||
_error.ArgType = "decorated object should be a classic (non-generator) function"
|
||||
_error.NrOfArgs = "decorated function should not have arguments"
|
||||
_error.DecNrOfArgs = "decorator should have arguments"
|
||||
|
||||
|
||||
def always(*args):
|
||||
assert len(args) > 0
|
||||
for arg in args:
|
||||
assert isinstance(arg, (Signal, _WaiterList, delay))
|
||||
if not isinstance(arg, (Signal, _WaiterList, delay)):
|
||||
raise AlwaysError(_error.DecArgType)
|
||||
def _always_decorator(func):
|
||||
if not isinstance(func, FunctionType):
|
||||
raise AlwaysError(_error.ArgType)
|
||||
@ -74,7 +72,21 @@ class _Always(object):
|
||||
bt = None
|
||||
break
|
||||
# now set waiter class
|
||||
|
||||
W = _Waiter
|
||||
|
||||
if bt is delay:
|
||||
W = _DelayWaiter
|
||||
elif len(self.senslist) == 1:
|
||||
if bt is Signal:
|
||||
W = _SignalWaiter
|
||||
elif bt is _WaiterList:
|
||||
W = _EdgeWaiter
|
||||
else:
|
||||
if bt is Signal:
|
||||
W = _SignalTupleWaiter
|
||||
elif bt is _WaiterList:
|
||||
W = _EdgeTupleWaiter
|
||||
|
||||
self.waiter = W(self.gen)
|
||||
|
||||
|
218
myhdl/test/test_always.py
Normal file
218
myhdl/test/test_always.py
Normal file
@ -0,0 +1,218 @@
|
||||
# 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 the unit tests for the @always decorator """
|
||||
|
||||
__author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||
__revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
import random
|
||||
from random import randrange
|
||||
# random.seed(3) # random, but deterministic
|
||||
|
||||
import unittest
|
||||
from unittest import TestCase
|
||||
import inspect
|
||||
from sets import Set
|
||||
|
||||
from myhdl import Signal, Simulation, instances, processes, AlwaysError, \
|
||||
intbv, posedge, negedge, delay, StopSimulation, now
|
||||
|
||||
from myhdl._always import always, _Always, _error
|
||||
|
||||
from myhdl._Waiter import _inferWaiter, _Waiter
|
||||
from myhdl._Waiter import _SignalWaiter,_SignalTupleWaiter, _DelayWaiter, \
|
||||
_EdgeWaiter, _EdgeTupleWaiter
|
||||
|
||||
|
||||
QUIET=1
|
||||
|
||||
def g():
|
||||
pass
|
||||
|
||||
x = Signal(0)
|
||||
|
||||
class AlwaysCompilationTest(TestCase):
|
||||
|
||||
|
||||
def testArgIsFunction(self):
|
||||
h = 5
|
||||
try:
|
||||
always(delay(3))(h)
|
||||
except AlwaysError, e:
|
||||
self.assertEqual(e.kind, _error.ArgType)
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
def testArgIsNormalFunction(self):
|
||||
try:
|
||||
@always(delay(3))
|
||||
def h():
|
||||
yield None
|
||||
except AlwaysError, e:
|
||||
self.assertEqual(e.kind, _error.ArgType)
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
def testArgHasNoArgs(self):
|
||||
try:
|
||||
@always(delay(3))
|
||||
def h(n):
|
||||
return n
|
||||
except AlwaysError, e:
|
||||
self.assertEqual(e.kind, _error.NrOfArgs)
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
def testDecArgType1(self):
|
||||
try:
|
||||
@always
|
||||
def h(n):
|
||||
return n
|
||||
except AlwaysError, e:
|
||||
self.assertEqual(e.kind, _error.DecArgType)
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
def testDecArgType2(self):
|
||||
try:
|
||||
@always(g)
|
||||
def h(n):
|
||||
return n
|
||||
except AlwaysError, e:
|
||||
self.assertEqual(e.kind, _error.DecArgType)
|
||||
else:
|
||||
self.fail()
|
||||
|
||||
|
||||
|
||||
def SignalFunc1(a, b, c, d, r):
|
||||
|
||||
@always(a)
|
||||
def logic():
|
||||
r.next = a + b + c + d
|
||||
|
||||
return logic
|
||||
|
||||
|
||||
def SignalTupleFunc1(a, b, c, d, r):
|
||||
|
||||
@always(a, b, c)
|
||||
def logic():
|
||||
r.next = a + b + c + d
|
||||
|
||||
return logic
|
||||
|
||||
|
||||
def DelayFunc(a, b, c, d, r):
|
||||
|
||||
@always(delay(3))
|
||||
def logic():
|
||||
r.next = a + b + c + d
|
||||
|
||||
return logic
|
||||
|
||||
|
||||
def EdgeFunc1(a, b, c, d, r):
|
||||
|
||||
@always(c.posedge)
|
||||
def logic():
|
||||
r.next = a + b + c + d
|
||||
|
||||
return logic
|
||||
|
||||
|
||||
def EdgeTupleFunc1(a, b, c, d, r):
|
||||
|
||||
@always(c.posedge, d.negedge)
|
||||
def logic():
|
||||
r.next = a + b + c + d
|
||||
|
||||
return logic
|
||||
|
||||
|
||||
def GeneralFunc(a, b, c, d, r):
|
||||
|
||||
@always(c.posedge, d)
|
||||
def logic():
|
||||
r.next = a + b + c + d
|
||||
|
||||
return logic
|
||||
|
||||
|
||||
|
||||
class InferWaiterTest(TestCase):
|
||||
|
||||
def bench(self, MyHDLFunc, waiterType):
|
||||
|
||||
a, b, c, d, r, s = [Signal(intbv(0)) for i in range(6)]
|
||||
|
||||
inst_r = MyHDLFunc(a, b, c, d, r)
|
||||
self.assertEqual(type(inst_r.waiter), waiterType)
|
||||
|
||||
inst_s = MyHDLFunc(a, b, c, d, s)
|
||||
|
||||
def stimulus():
|
||||
for i in range(1000):
|
||||
yield delay(randrange(1, 10))
|
||||
if randrange(2):
|
||||
a.next = randrange(32)
|
||||
if randrange(2):
|
||||
b.next = randrange(32)
|
||||
c.next = randrange(2)
|
||||
d.next = randrange(2)
|
||||
raise StopSimulation
|
||||
|
||||
def check():
|
||||
while 1:
|
||||
yield a, b, c, r, s
|
||||
self.assertEqual(r, s)
|
||||
|
||||
return inst_r, _Waiter(inst_s.gen), _Waiter(stimulus()), _Waiter(check())
|
||||
|
||||
def testSignal1(self):
|
||||
sim = Simulation(self.bench(SignalFunc1, _SignalWaiter))
|
||||
sim.run()
|
||||
|
||||
def testSignalTuple1(self):
|
||||
sim = Simulation(self.bench(SignalTupleFunc1, _SignalTupleWaiter))
|
||||
sim.run()
|
||||
|
||||
def testDelay(self):
|
||||
sim = Simulation(self.bench(DelayFunc, _DelayWaiter))
|
||||
sim.run()
|
||||
|
||||
def testEdge1(self):
|
||||
sim = Simulation(self.bench(EdgeFunc1, _EdgeWaiter))
|
||||
sim.run()
|
||||
|
||||
def testEdgeTuple1(self):
|
||||
sim = Simulation(self.bench(EdgeTupleFunc1, _EdgeTupleWaiter))
|
||||
sim.run()
|
||||
|
||||
def testGeneral(self):
|
||||
sim = Simulation(self.bench(GeneralFunc, _Waiter))
|
||||
sim.run()
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
@ -32,11 +32,10 @@ from unittest import TestCase
|
||||
import inspect
|
||||
from sets import Set
|
||||
|
||||
from myhdl import Signal, Simulation, instances, processes, \
|
||||
from myhdl import Signal, Simulation, instances, processes, AlwaysCombError, \
|
||||
intbv, posedge, negedge, delay, StopSimulation, now
|
||||
|
||||
from myhdl._always_comb import always_comb, _AlwaysComb, \
|
||||
AlwaysCombError, _error
|
||||
from myhdl._always_comb import always_comb, _AlwaysComb, _error
|
||||
|
||||
from myhdl._Waiter import _Waiter,_SignalWaiter,_SignalTupleWaiter
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user