2019-11-22 01:32:41 -07:00
|
|
|
import os
|
2018-12-18 10:53:50 -07:00
|
|
|
from contextlib import contextmanager
|
|
|
|
|
2019-10-13 12:53:38 -06:00
|
|
|
from .utils import *
|
|
|
|
from .._utils import flatten, union
|
2018-12-15 07:23:42 -07:00
|
|
|
from ..hdl.ast import *
|
2018-12-18 10:53:50 -07:00
|
|
|
from ..hdl.cd import *
|
2018-12-21 04:00:42 -07:00
|
|
|
from ..hdl.mem import *
|
2018-12-28 06:22:10 -07:00
|
|
|
from ..hdl.rec import *
|
2018-12-18 10:53:50 -07:00
|
|
|
from ..hdl.dsl import *
|
2018-12-15 07:23:42 -07:00
|
|
|
from ..hdl.ir import *
|
2018-12-14 07:21:22 -07:00
|
|
|
from ..back.pysim import *
|
|
|
|
|
|
|
|
|
|
|
|
class SimulatorUnitTestCase(FHDLTestCase):
|
2018-12-16 03:31:42 -07:00
|
|
|
def assertStatement(self, stmt, inputs, output, reset=0):
|
2019-10-11 04:49:34 -06:00
|
|
|
inputs = [Value.cast(i) for i in inputs]
|
|
|
|
output = Value.cast(output)
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
isigs = [Signal(i.shape(), name=n) for i, n in zip(inputs, "abcd")]
|
2018-12-16 03:31:42 -07:00
|
|
|
osig = Signal(output.shape(), name="y", reset=reset)
|
2018-12-14 07:21:22 -07:00
|
|
|
|
2018-12-16 03:31:42 -07:00
|
|
|
stmt = stmt(osig, *isigs)
|
2018-12-14 07:21:22 -07:00
|
|
|
frag = Fragment()
|
2018-12-16 03:31:42 -07:00
|
|
|
frag.add_statements(stmt)
|
2019-10-11 07:28:26 -06:00
|
|
|
for signal in flatten(s._lhs_signals() for s in Statement.cast(stmt)):
|
2018-12-16 03:31:42 -07:00
|
|
|
frag.add_driver(signal)
|
2018-12-14 07:21:22 -07:00
|
|
|
|
2019-11-22 01:32:41 -07:00
|
|
|
sim = Simulator(frag)
|
|
|
|
def process():
|
|
|
|
for isig, input in zip(isigs, inputs):
|
|
|
|
yield isig.eq(input)
|
|
|
|
yield Settle()
|
|
|
|
self.assertEqual((yield osig), output.value)
|
|
|
|
sim.add_process(process)
|
|
|
|
with sim.write_vcd("test.vcd", "test.gtkw", traces=[*isigs, osig]):
|
2018-12-14 07:21:22 -07:00
|
|
|
sim.run()
|
|
|
|
|
|
|
|
def test_invert(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a: y.eq(~a)
|
|
|
|
self.assertStatement(stmt, [C(0b0000, 4)], C(0b1111, 4))
|
|
|
|
self.assertStatement(stmt, [C(0b1010, 4)], C(0b0101, 4))
|
|
|
|
self.assertStatement(stmt, [C(0, 4)], C(-1, 4))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_neg(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a: y.eq(-a)
|
|
|
|
self.assertStatement(stmt, [C(0b0000, 4)], C(0b0000, 4))
|
|
|
|
self.assertStatement(stmt, [C(0b0001, 4)], C(0b1111, 4))
|
|
|
|
self.assertStatement(stmt, [C(0b1010, 4)], C(0b0110, 4))
|
|
|
|
self.assertStatement(stmt, [C(1, 4)], C(-1, 4))
|
|
|
|
self.assertStatement(stmt, [C(5, 4)], C(-5, 4))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_bool(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a: y.eq(a.bool())
|
|
|
|
self.assertStatement(stmt, [C(0, 4)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(1, 4)], C(1))
|
|
|
|
self.assertStatement(stmt, [C(2, 4)], C(1))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
2020-02-06 11:27:55 -07:00
|
|
|
def test_as_unsigned(self):
|
|
|
|
stmt = lambda y, a, b: y.eq(a.as_unsigned() == b)
|
|
|
|
self.assertStatement(stmt, [C(0b01, signed(2)), C(0b0001, unsigned(4))], C(1))
|
|
|
|
self.assertStatement(stmt, [C(0b11, signed(2)), C(0b0011, unsigned(4))], C(1))
|
|
|
|
|
|
|
|
def test_as_signed(self):
|
|
|
|
stmt = lambda y, a, b: y.eq(a.as_signed() == b)
|
|
|
|
self.assertStatement(stmt, [C(0b01, unsigned(2)), C(0b0001, signed(4))], C(1))
|
|
|
|
self.assertStatement(stmt, [C(0b11, unsigned(2)), C(0b1111, signed(4))], C(1))
|
|
|
|
|
2019-09-13 07:14:52 -06:00
|
|
|
def test_any(self):
|
|
|
|
stmt = lambda y, a: y.eq(a.any())
|
|
|
|
self.assertStatement(stmt, [C(0b00, 2)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(0b01, 2)], C(1))
|
2019-09-20 04:12:59 -06:00
|
|
|
self.assertStatement(stmt, [C(0b10, 2)], C(1))
|
2019-09-13 07:14:52 -06:00
|
|
|
self.assertStatement(stmt, [C(0b11, 2)], C(1))
|
|
|
|
|
|
|
|
def test_all(self):
|
|
|
|
stmt = lambda y, a: y.eq(a.all())
|
|
|
|
self.assertStatement(stmt, [C(0b00, 2)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(0b01, 2)], C(0))
|
2019-09-20 04:12:59 -06:00
|
|
|
self.assertStatement(stmt, [C(0b10, 2)], C(0))
|
2019-09-13 07:14:52 -06:00
|
|
|
self.assertStatement(stmt, [C(0b11, 2)], C(1))
|
|
|
|
|
2019-09-20 04:12:59 -06:00
|
|
|
def test_xor_unary(self):
|
2019-09-13 08:28:43 -06:00
|
|
|
stmt = lambda y, a: y.eq(a.xor())
|
|
|
|
self.assertStatement(stmt, [C(0b00, 2)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(0b01, 2)], C(1))
|
2019-09-20 04:12:59 -06:00
|
|
|
self.assertStatement(stmt, [C(0b10, 2)], C(1))
|
2019-09-13 08:28:43 -06:00
|
|
|
self.assertStatement(stmt, [C(0b11, 2)], C(0))
|
|
|
|
|
2018-12-14 07:21:22 -07:00
|
|
|
def test_add(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a + b)
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1, 4))
|
|
|
|
self.assertStatement(stmt, [C(-5, 4), C(-5, 4)], C(-10, 5))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_sub(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a - b)
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(1, 4))
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(-1, 4))
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(10, 4)], C(-10, 5))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
2018-12-18 11:02:21 -07:00
|
|
|
def test_mul(self):
|
|
|
|
stmt = lambda y, a, b: y.eq(a * b)
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(2, 8))
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(4, 8))
|
|
|
|
self.assertStatement(stmt, [C(7, 4), C(7, 4)], C(49, 8))
|
|
|
|
|
2019-09-28 13:33:24 -06:00
|
|
|
def test_floordiv(self):
|
|
|
|
stmt = lambda y, a, b: y.eq(a // b)
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(2, 8))
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(1, 8))
|
|
|
|
self.assertStatement(stmt, [C(7, 4), C(2, 4)], C(3, 8))
|
|
|
|
|
2020-03-14 23:22:03 -06:00
|
|
|
def test_mod(self):
|
|
|
|
stmt = lambda y, a, b: y.eq(a % b)
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(0, 4)], C(0, 8))
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(1, 4)], C(0, 8))
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(2, 4)], C(0, 8))
|
|
|
|
self.assertStatement(stmt, [C(7, 4), C(2, 4)], C(1, 8))
|
|
|
|
|
2018-12-14 07:21:22 -07:00
|
|
|
def test_and(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a & b)
|
|
|
|
self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_or(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a | b)
|
|
|
|
self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1110, 4))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
2019-09-20 04:12:59 -06:00
|
|
|
def test_xor_binary(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a ^ b)
|
|
|
|
self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b0110, 4))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
2018-12-15 02:58:30 -07:00
|
|
|
def test_shl(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a << b)
|
|
|
|
self.assertStatement(stmt, [C(0b1001, 4), C(0)], C(0b1001, 5))
|
|
|
|
self.assertStatement(stmt, [C(0b1001, 4), C(3)], C(0b1001000, 7))
|
2018-12-15 02:58:30 -07:00
|
|
|
|
|
|
|
def test_shr(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a >> b)
|
|
|
|
self.assertStatement(stmt, [C(0b1001, 4), C(0)], C(0b1001, 4))
|
|
|
|
self.assertStatement(stmt, [C(0b1001, 4), C(2)], C(0b10, 4))
|
2018-12-15 02:58:30 -07:00
|
|
|
|
2018-12-14 07:21:22 -07:00
|
|
|
def test_eq(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a == b)
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_ne(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a != b)
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1))
|
|
|
|
self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(1))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_lt(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a < b)
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1))
|
|
|
|
self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_ge(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a >= b)
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(1))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_gt(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a > b)
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(0))
|
|
|
|
self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(1))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_le(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(a <= b)
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(0, 4)], C(1))
|
|
|
|
self.assertStatement(stmt, [C(0, 4), C(1, 4)], C(1))
|
|
|
|
self.assertStatement(stmt, [C(1, 4), C(0, 4)], C(0))
|
2018-12-14 07:21:22 -07:00
|
|
|
|
|
|
|
def test_mux(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b, c: y.eq(Mux(c, a, b))
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(3, 4), C(0)], C(3, 4))
|
|
|
|
self.assertStatement(stmt, [C(2, 4), C(3, 4), C(1)], C(2, 4))
|
2018-12-15 03:09:14 -07:00
|
|
|
|
2020-03-22 14:50:07 -06:00
|
|
|
def test_abs(self):
|
|
|
|
stmt = lambda y, a: y.eq(abs(a))
|
|
|
|
self.assertStatement(stmt, [C(3, unsigned(8))], C(3, unsigned(8)))
|
|
|
|
self.assertStatement(stmt, [C(-3, unsigned(8))], C(-3, unsigned(8)))
|
|
|
|
self.assertStatement(stmt, [C(3, signed(8))], C(3, signed(8)))
|
|
|
|
self.assertStatement(stmt, [C(-3, signed(8))], C(3, signed(8)))
|
|
|
|
|
2018-12-15 03:09:14 -07:00
|
|
|
def test_slice(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt1 = lambda y, a: y.eq(a[2])
|
|
|
|
self.assertStatement(stmt1, [C(0b10110100, 8)], C(0b1, 1))
|
|
|
|
stmt2 = lambda y, a: y.eq(a[2:4])
|
|
|
|
self.assertStatement(stmt2, [C(0b10110100, 8)], C(0b01, 2))
|
2018-12-15 03:09:14 -07:00
|
|
|
|
2018-12-16 03:31:42 -07:00
|
|
|
def test_slice_lhs(self):
|
|
|
|
stmt1 = lambda y, a: y[2].eq(a)
|
|
|
|
self.assertStatement(stmt1, [C(0b0, 1)], C(0b11111011, 8), reset=0b11111111)
|
|
|
|
stmt2 = lambda y, a: y[2:4].eq(a)
|
|
|
|
self.assertStatement(stmt2, [C(0b01, 2)], C(0b11110111, 8), reset=0b11111011)
|
|
|
|
|
2019-08-03 07:05:41 -06:00
|
|
|
def test_bit_select(self):
|
|
|
|
stmt = lambda y, a, b: y.eq(a.bit_select(b, 3))
|
2018-12-15 14:08:29 -07:00
|
|
|
self.assertStatement(stmt, [C(0b10110100, 8), C(0)], C(0b100, 3))
|
|
|
|
self.assertStatement(stmt, [C(0b10110100, 8), C(2)], C(0b101, 3))
|
|
|
|
self.assertStatement(stmt, [C(0b10110100, 8), C(3)], C(0b110, 3))
|
2018-12-15 13:58:06 -07:00
|
|
|
|
2019-08-03 07:05:41 -06:00
|
|
|
def test_bit_select_lhs(self):
|
|
|
|
stmt = lambda y, a, b: y.bit_select(a, 3).eq(b)
|
2018-12-16 03:31:42 -07:00
|
|
|
self.assertStatement(stmt, [C(0), C(0b100, 3)], C(0b11111100, 8), reset=0b11111111)
|
|
|
|
self.assertStatement(stmt, [C(2), C(0b101, 3)], C(0b11110111, 8), reset=0b11111111)
|
|
|
|
self.assertStatement(stmt, [C(3), C(0b110, 3)], C(0b11110111, 8), reset=0b11111111)
|
|
|
|
|
2019-08-03 07:05:41 -06:00
|
|
|
def test_word_select(self):
|
|
|
|
stmt = lambda y, a, b: y.eq(a.word_select(b, 3))
|
|
|
|
self.assertStatement(stmt, [C(0b10110100, 8), C(0)], C(0b100, 3))
|
|
|
|
self.assertStatement(stmt, [C(0b10110100, 8), C(1)], C(0b110, 3))
|
|
|
|
self.assertStatement(stmt, [C(0b10110100, 8), C(2)], C(0b010, 3))
|
|
|
|
|
|
|
|
def test_word_select_lhs(self):
|
|
|
|
stmt = lambda y, a, b: y.word_select(a, 3).eq(b)
|
|
|
|
self.assertStatement(stmt, [C(0), C(0b100, 3)], C(0b11111100, 8), reset=0b11111111)
|
|
|
|
self.assertStatement(stmt, [C(1), C(0b101, 3)], C(0b11101111, 8), reset=0b11111111)
|
|
|
|
self.assertStatement(stmt, [C(2), C(0b110, 3)], C(0b10111111, 8), reset=0b11111111)
|
|
|
|
|
2018-12-15 03:09:14 -07:00
|
|
|
def test_cat(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, *xs: y.eq(Cat(*xs))
|
|
|
|
self.assertStatement(stmt, [C(0b10, 2), C(0b01, 2)], C(0b0110, 4))
|
2018-12-15 03:09:14 -07:00
|
|
|
|
2018-12-16 03:31:42 -07:00
|
|
|
def test_cat_lhs(self):
|
|
|
|
l = Signal(3)
|
|
|
|
m = Signal(3)
|
|
|
|
n = Signal(3)
|
|
|
|
stmt = lambda y, a: [Cat(l, m, n).eq(a), y.eq(Cat(n, m, l))]
|
|
|
|
self.assertStatement(stmt, [C(0b100101110, 9)], C(0b110101100, 9))
|
|
|
|
|
2019-11-22 01:32:41 -07:00
|
|
|
def test_nested_cat_lhs(self):
|
|
|
|
l = Signal(3)
|
|
|
|
m = Signal(3)
|
|
|
|
n = Signal(3)
|
|
|
|
stmt = lambda y, a: [Cat(Cat(l, Cat(m)), n).eq(a), y.eq(Cat(n, m, l))]
|
|
|
|
self.assertStatement(stmt, [C(0b100101110, 9)], C(0b110101100, 9))
|
|
|
|
|
2018-12-28 06:22:10 -07:00
|
|
|
def test_record(self):
|
|
|
|
rec = Record([
|
|
|
|
("l", 1),
|
|
|
|
("m", 2),
|
|
|
|
])
|
|
|
|
stmt = lambda y, a: [rec.eq(a), y.eq(rec)]
|
|
|
|
self.assertStatement(stmt, [C(0b101, 3)], C(0b101, 3))
|
|
|
|
|
2018-12-15 03:09:14 -07:00
|
|
|
def test_repl(self):
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a: y.eq(Repl(a, 3))
|
|
|
|
self.assertStatement(stmt, [C(0b10, 2)], C(0b101010, 6))
|
2018-12-15 12:37:36 -07:00
|
|
|
|
|
|
|
def test_array(self):
|
|
|
|
array = Array([1, 4, 10])
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a: y.eq(array[a])
|
|
|
|
self.assertStatement(stmt, [C(0)], C(1))
|
|
|
|
self.assertStatement(stmt, [C(1)], C(4))
|
|
|
|
self.assertStatement(stmt, [C(2)], C(10))
|
2018-12-15 12:37:36 -07:00
|
|
|
|
2018-12-21 05:32:08 -07:00
|
|
|
def test_array_oob(self):
|
|
|
|
array = Array([1, 4, 10])
|
|
|
|
stmt = lambda y, a: y.eq(array[a])
|
|
|
|
self.assertStatement(stmt, [C(3)], C(10))
|
|
|
|
self.assertStatement(stmt, [C(4)], C(10))
|
|
|
|
|
2018-12-16 03:31:42 -07:00
|
|
|
def test_array_lhs(self):
|
|
|
|
l = Signal(3, reset=1)
|
|
|
|
m = Signal(3, reset=4)
|
|
|
|
n = Signal(3, reset=7)
|
|
|
|
array = Array([l, m, n])
|
|
|
|
stmt = lambda y, a, b: [array[a].eq(b), y.eq(Cat(*array))]
|
|
|
|
self.assertStatement(stmt, [C(0), C(0b000)], C(0b111100000))
|
|
|
|
self.assertStatement(stmt, [C(1), C(0b010)], C(0b111010001))
|
|
|
|
self.assertStatement(stmt, [C(2), C(0b100)], C(0b100100001))
|
|
|
|
|
2018-12-21 05:32:08 -07:00
|
|
|
def test_array_lhs_oob(self):
|
|
|
|
l = Signal(3)
|
|
|
|
m = Signal(3)
|
|
|
|
n = Signal(3)
|
|
|
|
array = Array([l, m, n])
|
|
|
|
stmt = lambda y, a, b: [array[a].eq(b), y.eq(Cat(*array))]
|
|
|
|
self.assertStatement(stmt, [C(3), C(0b001)], C(0b001000000))
|
|
|
|
self.assertStatement(stmt, [C(4), C(0b010)], C(0b010000000))
|
|
|
|
|
2018-12-15 12:37:36 -07:00
|
|
|
def test_array_index(self):
|
|
|
|
array = Array(Array(x * y for y in range(10)) for x in range(10))
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a, b: y.eq(array[a][b])
|
2018-12-15 12:37:36 -07:00
|
|
|
for x in range(10):
|
|
|
|
for y in range(10):
|
2018-12-15 14:08:29 -07:00
|
|
|
self.assertStatement(stmt, [C(x), C(y)], C(x * y))
|
2018-12-15 12:37:36 -07:00
|
|
|
|
|
|
|
def test_array_attr(self):
|
|
|
|
from collections import namedtuple
|
|
|
|
pair = namedtuple("pair", ("p", "n"))
|
|
|
|
|
|
|
|
array = Array(pair(x, -x) for x in range(10))
|
2018-12-15 14:08:29 -07:00
|
|
|
stmt = lambda y, a: y.eq(array[a].p + array[a].n)
|
2018-12-15 12:37:36 -07:00
|
|
|
for i in range(10):
|
2018-12-15 14:08:29 -07:00
|
|
|
self.assertStatement(stmt, [C(i)], C(0))
|
2018-12-18 10:53:50 -07:00
|
|
|
|
2020-05-19 21:18:33 -06:00
|
|
|
def test_shift_left(self):
|
|
|
|
stmt1 = lambda y, a: y.eq(a.shift_left(1))
|
|
|
|
self.assertStatement(stmt1, [C(0b10100010, 8)], C( 0b101000100, 9))
|
|
|
|
stmt2 = lambda y, a: y.eq(a.shift_left(4))
|
|
|
|
self.assertStatement(stmt2, [C(0b10100010, 8)], C(0b101000100000, 12))
|
|
|
|
|
|
|
|
def test_shift_right(self):
|
|
|
|
stmt1 = lambda y, a: y.eq(a.shift_right(1))
|
|
|
|
self.assertStatement(stmt1, [C(0b10100010, 8)], C(0b1010001, 7))
|
|
|
|
stmt2 = lambda y, a: y.eq(a.shift_right(4))
|
|
|
|
self.assertStatement(stmt2, [C(0b10100010, 8)], C( 0b1010, 4))
|
|
|
|
|
2020-04-13 07:40:39 -06:00
|
|
|
def test_rotate_left(self):
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_left(1))
|
|
|
|
self.assertStatement(stmt, [C(0b1)], C(0b1))
|
|
|
|
self.assertStatement(stmt, [C(0b1001000)], C(0b0010001))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_left(5))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_left(7))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_left(9))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_left(-1))
|
|
|
|
self.assertStatement(stmt, [C(0b1)], C(0b1))
|
|
|
|
self.assertStatement(stmt, [C(0b1001000)], C(0b0100100))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_left(-5))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_left(-7))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_left(-9))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
|
|
|
|
|
|
|
|
def test_rotate_right(self):
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_right(1))
|
|
|
|
self.assertStatement(stmt, [C(0b1)], C(0b1))
|
|
|
|
self.assertStatement(stmt, [C(0b1001000)], C(0b0100100))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_right(5))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_right(7))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_right(9))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_right(-1))
|
|
|
|
self.assertStatement(stmt, [C(0b1)], C(0b1))
|
|
|
|
self.assertStatement(stmt, [C(0b1001000)], C(0b0010001))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_right(-5))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b0010000))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b0110000))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_right(-7))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b1000000))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b1000001))
|
|
|
|
stmt = lambda y, a: y.eq(a.rotate_right(-9))
|
|
|
|
self.assertStatement(stmt, [C(0b1000000)], C(0b0000010))
|
|
|
|
self.assertStatement(stmt, [C(0b1000001)], C(0b0000110))
|
2018-12-18 10:53:50 -07:00
|
|
|
|
2020-08-25 22:15:26 -06:00
|
|
|
|
2018-12-18 10:53:50 -07:00
|
|
|
class SimulatorIntegrationTestCase(FHDLTestCase):
|
|
|
|
@contextmanager
|
|
|
|
def assertSimulation(self, module, deadline=None):
|
2019-11-22 01:32:41 -07:00
|
|
|
sim = Simulator(module)
|
|
|
|
yield sim
|
|
|
|
with sim.write_vcd("test.vcd", "test.gtkw"):
|
2018-12-18 10:53:50 -07:00
|
|
|
if deadline is None:
|
|
|
|
sim.run()
|
|
|
|
else:
|
|
|
|
sim.run_until(deadline)
|
|
|
|
|
|
|
|
def setUp_counter(self):
|
|
|
|
self.count = Signal(3, reset=4)
|
|
|
|
self.sync = ClockDomain()
|
|
|
|
|
|
|
|
self.m = Module()
|
|
|
|
self.m.d.sync += self.count.eq(self.count + 1)
|
|
|
|
self.m.domains += self.sync
|
|
|
|
|
|
|
|
def test_counter_process(self):
|
|
|
|
self.setUp_counter()
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
self.assertEqual((yield self.count), 4)
|
|
|
|
yield Delay(1e-6)
|
|
|
|
self.assertEqual((yield self.count), 4)
|
|
|
|
yield self.sync.clk.eq(1)
|
2019-11-22 01:32:41 -07:00
|
|
|
self.assertEqual((yield self.count), 4)
|
|
|
|
yield Settle()
|
2018-12-18 10:53:50 -07:00
|
|
|
self.assertEqual((yield self.count), 5)
|
|
|
|
yield Delay(1e-6)
|
|
|
|
self.assertEqual((yield self.count), 5)
|
|
|
|
yield self.sync.clk.eq(0)
|
|
|
|
self.assertEqual((yield self.count), 5)
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
|
|
|
self.assertEqual((yield self.count), 5)
|
2018-12-18 10:53:50 -07:00
|
|
|
for _ in range(3):
|
|
|
|
yield Delay(1e-6)
|
|
|
|
yield self.sync.clk.eq(1)
|
|
|
|
yield Delay(1e-6)
|
|
|
|
yield self.sync.clk.eq(0)
|
|
|
|
self.assertEqual((yield self.count), 0)
|
|
|
|
sim.add_process(process)
|
|
|
|
|
|
|
|
def test_counter_clock_and_sync_process(self):
|
|
|
|
self.setUp_counter()
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
sim.add_clock(1e-6, domain="sync")
|
|
|
|
def process():
|
|
|
|
self.assertEqual((yield self.count), 4)
|
2019-01-21 09:00:25 -07:00
|
|
|
self.assertEqual((yield self.sync.clk), 1)
|
|
|
|
yield
|
2018-12-18 10:53:50 -07:00
|
|
|
self.assertEqual((yield self.count), 5)
|
|
|
|
self.assertEqual((yield self.sync.clk), 1)
|
|
|
|
for _ in range(3):
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.count), 0)
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
|
2019-11-22 01:32:41 -07:00
|
|
|
def test_reset(self):
|
|
|
|
self.setUp_counter()
|
|
|
|
sim = Simulator(self.m)
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
times = 0
|
|
|
|
def process():
|
|
|
|
nonlocal times
|
|
|
|
self.assertEqual((yield self.count), 4)
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.count), 5)
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.count), 6)
|
|
|
|
yield
|
|
|
|
times += 1
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
sim.run()
|
|
|
|
sim.reset()
|
|
|
|
sim.run()
|
|
|
|
self.assertEqual(times, 2)
|
|
|
|
|
2018-12-18 10:53:50 -07:00
|
|
|
def setUp_alu(self):
|
|
|
|
self.a = Signal(8)
|
|
|
|
self.b = Signal(8)
|
|
|
|
self.o = Signal(8)
|
|
|
|
self.x = Signal(8)
|
|
|
|
self.s = Signal(2)
|
|
|
|
self.sync = ClockDomain(reset_less=True)
|
|
|
|
|
|
|
|
self.m = Module()
|
|
|
|
self.m.d.comb += self.x.eq(self.a ^ self.b)
|
|
|
|
with self.m.Switch(self.s):
|
|
|
|
with self.m.Case(0):
|
|
|
|
self.m.d.sync += self.o.eq(self.a + self.b)
|
|
|
|
with self.m.Case(1):
|
|
|
|
self.m.d.sync += self.o.eq(self.a - self.b)
|
|
|
|
with self.m.Case():
|
|
|
|
self.m.d.sync += self.o.eq(0)
|
|
|
|
self.m.domains += self.sync
|
|
|
|
|
|
|
|
def test_alu(self):
|
|
|
|
self.setUp_alu()
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
def process():
|
|
|
|
yield self.a.eq(5)
|
|
|
|
yield self.b.eq(1)
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.x), 4)
|
2019-01-21 09:00:25 -07:00
|
|
|
yield
|
2018-12-18 10:53:50 -07:00
|
|
|
self.assertEqual((yield self.o), 6)
|
|
|
|
yield self.s.eq(1)
|
|
|
|
yield
|
2019-01-21 09:00:25 -07:00
|
|
|
yield
|
2018-12-18 10:53:50 -07:00
|
|
|
self.assertEqual((yield self.o), 4)
|
|
|
|
yield self.s.eq(2)
|
|
|
|
yield
|
2019-01-21 09:00:25 -07:00
|
|
|
yield
|
2018-12-18 10:53:50 -07:00
|
|
|
self.assertEqual((yield self.o), 0)
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
|
|
|
|
def setUp_multiclock(self):
|
|
|
|
self.sys = ClockDomain()
|
|
|
|
self.pix = ClockDomain()
|
|
|
|
|
|
|
|
self.m = Module()
|
|
|
|
self.m.domains += self.sys, self.pix
|
|
|
|
|
|
|
|
def test_multiclock(self):
|
|
|
|
self.setUp_multiclock()
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
sim.add_clock(1e-6, domain="sys")
|
|
|
|
sim.add_clock(0.3e-6, domain="pix")
|
|
|
|
|
|
|
|
def sys_process():
|
|
|
|
yield Passive()
|
|
|
|
yield
|
|
|
|
yield
|
|
|
|
self.fail()
|
|
|
|
def pix_process():
|
|
|
|
yield
|
|
|
|
yield
|
|
|
|
yield
|
|
|
|
sim.add_sync_process(sys_process, domain="sys")
|
|
|
|
sim.add_sync_process(pix_process, domain="pix")
|
|
|
|
|
|
|
|
def setUp_lhs_rhs(self):
|
|
|
|
self.i = Signal(8)
|
|
|
|
self.o = Signal(8)
|
|
|
|
|
|
|
|
self.m = Module()
|
|
|
|
self.m.d.comb += self.o.eq(self.i)
|
|
|
|
|
|
|
|
def test_complex_lhs_rhs(self):
|
|
|
|
self.setUp_lhs_rhs()
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
yield self.i.eq(0b10101010)
|
|
|
|
yield self.i[:4].eq(-1)
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
2018-12-18 10:53:50 -07:00
|
|
|
self.assertEqual((yield self.i[:4]), 0b1111)
|
|
|
|
self.assertEqual((yield self.i), 0b10101111)
|
|
|
|
sim.add_process(process)
|
|
|
|
|
|
|
|
def test_run_until(self):
|
2019-08-03 08:54:20 -06:00
|
|
|
m = Module()
|
|
|
|
s = Signal()
|
|
|
|
m.d.sync += s.eq(0)
|
|
|
|
with self.assertSimulation(m, deadline=100e-6) as sim:
|
2018-12-18 10:53:50 -07:00
|
|
|
sim.add_clock(1e-6)
|
|
|
|
def process():
|
2019-03-28 11:50:14 -06:00
|
|
|
for _ in range(101):
|
|
|
|
yield Delay(1e-6)
|
2018-12-18 10:53:50 -07:00
|
|
|
self.fail()
|
2019-03-28 11:50:14 -06:00
|
|
|
sim.add_process(process)
|
2018-12-18 10:53:50 -07:00
|
|
|
|
|
|
|
def test_add_process_wrong(self):
|
|
|
|
with self.assertSimulation(Module()) as sim:
|
2020-07-28 13:35:25 -06:00
|
|
|
with self.assertRaisesRegex(TypeError,
|
|
|
|
r"^Cannot add a process 1 because it is not a generator function$"):
|
2018-12-18 10:53:50 -07:00
|
|
|
sim.add_process(1)
|
|
|
|
|
2019-11-22 01:32:41 -07:00
|
|
|
def test_add_process_wrong_generator(self):
|
|
|
|
with self.assertSimulation(Module()) as sim:
|
2020-07-06 10:01:49 -06:00
|
|
|
with self.assertRaisesRegex(TypeError,
|
|
|
|
r"^Cannot add a process <.+?> because it is not a generator function$"):
|
2019-11-22 01:32:41 -07:00
|
|
|
def process():
|
|
|
|
yield Delay()
|
|
|
|
sim.add_process(process())
|
|
|
|
|
2019-08-23 02:53:48 -06:00
|
|
|
def test_add_clock_wrong_twice(self):
|
2019-08-03 08:54:20 -06:00
|
|
|
m = Module()
|
|
|
|
s = Signal()
|
|
|
|
m.d.sync += s.eq(0)
|
|
|
|
with self.assertSimulation(m) as sim:
|
2019-06-10 21:54:22 -06:00
|
|
|
sim.add_clock(1)
|
2020-07-28 13:35:25 -06:00
|
|
|
with self.assertRaisesRegex(ValueError,
|
|
|
|
r"^Domain 'sync' already has a clock driving it$"):
|
2019-06-10 21:54:22 -06:00
|
|
|
sim.add_clock(1)
|
|
|
|
|
2019-08-23 02:53:48 -06:00
|
|
|
def test_add_clock_wrong_missing(self):
|
2019-08-23 02:37:59 -06:00
|
|
|
m = Module()
|
|
|
|
with self.assertSimulation(m) as sim:
|
2020-07-28 13:35:25 -06:00
|
|
|
with self.assertRaisesRegex(ValueError,
|
|
|
|
r"^Domain 'sync' is not present in simulation$"):
|
2019-08-23 02:37:59 -06:00
|
|
|
sim.add_clock(1)
|
|
|
|
|
2019-08-23 02:53:48 -06:00
|
|
|
def test_add_clock_if_exists(self):
|
|
|
|
m = Module()
|
|
|
|
with self.assertSimulation(m) as sim:
|
|
|
|
sim.add_clock(1, if_exists=True)
|
|
|
|
|
2018-12-18 10:53:50 -07:00
|
|
|
def test_command_wrong(self):
|
2019-11-22 01:32:41 -07:00
|
|
|
survived = False
|
2018-12-18 10:53:50 -07:00
|
|
|
with self.assertSimulation(Module()) as sim:
|
|
|
|
def process():
|
2019-11-22 01:32:41 -07:00
|
|
|
nonlocal survived
|
2018-12-18 10:53:50 -07:00
|
|
|
with self.assertRaisesRegex(TypeError,
|
2020-07-02 16:49:04 -06:00
|
|
|
r"Received unsupported command 1 from process .+?"):
|
2018-12-18 10:53:50 -07:00
|
|
|
yield 1
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
|
|
|
survived = True
|
2018-12-18 10:53:50 -07:00
|
|
|
sim.add_process(process)
|
2019-11-22 01:32:41 -07:00
|
|
|
self.assertTrue(survived)
|
2018-12-21 04:00:42 -07:00
|
|
|
|
|
|
|
def setUp_memory(self, rd_synchronous=True, rd_transparent=True, wr_granularity=None):
|
|
|
|
self.m = Module()
|
|
|
|
self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
|
|
|
|
self.m.submodules.rdport = self.rdport = \
|
2019-07-01 13:56:49 -06:00
|
|
|
self.memory.read_port(domain="sync" if rd_synchronous else "comb",
|
|
|
|
transparent=rd_transparent)
|
2018-12-21 04:00:42 -07:00
|
|
|
self.m.submodules.wrport = self.wrport = \
|
|
|
|
self.memory.write_port(granularity=wr_granularity)
|
|
|
|
|
|
|
|
def test_memory_init(self):
|
|
|
|
self.setUp_memory()
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
self.assertEqual((yield self.rdport.data), 0xaa)
|
|
|
|
yield self.rdport.addr.eq(1)
|
|
|
|
yield
|
2018-12-21 06:01:08 -07:00
|
|
|
yield
|
2018-12-21 04:00:42 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0x55)
|
|
|
|
yield self.rdport.addr.eq(2)
|
|
|
|
yield
|
2018-12-21 06:01:08 -07:00
|
|
|
yield
|
2018-12-21 04:00:42 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0x00)
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
|
|
|
|
def test_memory_write(self):
|
|
|
|
self.setUp_memory()
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
yield self.wrport.addr.eq(4)
|
|
|
|
yield self.wrport.data.eq(0x33)
|
|
|
|
yield self.wrport.en.eq(1)
|
|
|
|
yield
|
|
|
|
yield self.wrport.en.eq(0)
|
|
|
|
yield self.rdport.addr.eq(4)
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.rdport.data), 0x33)
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
|
|
|
|
def test_memory_write_granularity(self):
|
|
|
|
self.setUp_memory(wr_granularity=4)
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
yield self.wrport.data.eq(0x50)
|
|
|
|
yield self.wrport.en.eq(0b00)
|
|
|
|
yield
|
|
|
|
yield self.wrport.en.eq(0)
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.rdport.data), 0xaa)
|
|
|
|
yield self.wrport.en.eq(0b10)
|
|
|
|
yield
|
|
|
|
yield self.wrport.en.eq(0)
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.rdport.data), 0x5a)
|
|
|
|
yield self.wrport.data.eq(0x33)
|
|
|
|
yield self.wrport.en.eq(0b01)
|
|
|
|
yield
|
|
|
|
yield self.wrport.en.eq(0)
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.rdport.data), 0x53)
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
|
|
|
|
def test_memory_read_before_write(self):
|
|
|
|
self.setUp_memory(rd_transparent=False)
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
yield self.wrport.data.eq(0x33)
|
|
|
|
yield self.wrport.en.eq(1)
|
|
|
|
yield
|
2019-09-20 13:36:19 -06:00
|
|
|
self.assertEqual((yield self.rdport.data), 0xaa)
|
2019-01-21 09:00:25 -07:00
|
|
|
yield
|
2018-12-21 04:00:42 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0xaa)
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
2019-01-21 09:00:25 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0x33)
|
2018-12-21 04:00:42 -07:00
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
|
|
|
|
def test_memory_write_through(self):
|
|
|
|
self.setUp_memory(rd_transparent=True)
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
yield self.wrport.data.eq(0x33)
|
|
|
|
yield self.wrport.en.eq(1)
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.rdport.data), 0xaa)
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
2018-12-21 04:00:42 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0x33)
|
2018-12-21 06:01:08 -07:00
|
|
|
yield
|
|
|
|
yield self.rdport.addr.eq(1)
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
2018-12-21 06:01:08 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0x33)
|
2018-12-21 04:00:42 -07:00
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
|
|
|
|
def test_memory_async_read_write(self):
|
|
|
|
self.setUp_memory(rd_synchronous=False)
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
yield self.rdport.addr.eq(0)
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
2018-12-21 04:00:42 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0xaa)
|
|
|
|
yield self.rdport.addr.eq(1)
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
2018-12-21 04:00:42 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0x55)
|
|
|
|
yield self.rdport.addr.eq(0)
|
|
|
|
yield self.wrport.addr.eq(0)
|
|
|
|
yield self.wrport.data.eq(0x33)
|
|
|
|
yield self.wrport.en.eq(1)
|
|
|
|
yield Tick("sync")
|
|
|
|
self.assertEqual((yield self.rdport.data), 0xaa)
|
2019-11-22 01:32:41 -07:00
|
|
|
yield Settle()
|
2018-12-21 04:00:42 -07:00
|
|
|
self.assertEqual((yield self.rdport.data), 0x33)
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.add_process(process)
|
2018-12-29 08:02:04 -07:00
|
|
|
|
2019-01-13 01:31:38 -07:00
|
|
|
def test_memory_read_only(self):
|
|
|
|
self.m = Module()
|
|
|
|
self.memory = Memory(width=8, depth=4, init=[0xaa, 0x55])
|
|
|
|
self.m.submodules.rdport = self.rdport = self.memory.read_port()
|
|
|
|
with self.assertSimulation(self.m) as sim:
|
|
|
|
def process():
|
|
|
|
self.assertEqual((yield self.rdport.data), 0xaa)
|
|
|
|
yield self.rdport.addr.eq(1)
|
|
|
|
yield
|
|
|
|
yield
|
|
|
|
self.assertEqual((yield self.rdport.data), 0x55)
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.add_sync_process(process)
|
|
|
|
|
2019-01-16 21:31:27 -07:00
|
|
|
def test_sample_helpers(self):
|
|
|
|
m = Module()
|
|
|
|
s = Signal(2)
|
|
|
|
def mk(x):
|
|
|
|
y = Signal.like(x)
|
|
|
|
m.d.comb += y.eq(x)
|
|
|
|
return y
|
|
|
|
p0, r0, f0, s0 = mk(Past(s, 0)), mk(Rose(s)), mk(Fell(s)), mk(Stable(s))
|
|
|
|
p1, r1, f1, s1 = mk(Past(s)), mk(Rose(s, 1)), mk(Fell(s, 1)), mk(Stable(s, 1))
|
|
|
|
p2, r2, f2, s2 = mk(Past(s, 2)), mk(Rose(s, 2)), mk(Fell(s, 2)), mk(Stable(s, 2))
|
|
|
|
p3, r3, f3, s3 = mk(Past(s, 3)), mk(Rose(s, 3)), mk(Fell(s, 3)), mk(Stable(s, 3))
|
|
|
|
with self.assertSimulation(m) as sim:
|
|
|
|
def process_gen():
|
|
|
|
yield s.eq(0b10)
|
|
|
|
yield
|
|
|
|
yield
|
|
|
|
yield s.eq(0b01)
|
|
|
|
yield
|
|
|
|
def process_check():
|
|
|
|
yield
|
|
|
|
yield
|
|
|
|
yield
|
|
|
|
|
|
|
|
self.assertEqual((yield p0), 0b01)
|
|
|
|
self.assertEqual((yield p1), 0b10)
|
|
|
|
self.assertEqual((yield p2), 0b10)
|
|
|
|
self.assertEqual((yield p3), 0b00)
|
|
|
|
|
|
|
|
self.assertEqual((yield s0), 0b0)
|
|
|
|
self.assertEqual((yield s1), 0b1)
|
|
|
|
self.assertEqual((yield s2), 0b0)
|
|
|
|
self.assertEqual((yield s3), 0b1)
|
|
|
|
|
|
|
|
self.assertEqual((yield r0), 0b01)
|
|
|
|
self.assertEqual((yield r1), 0b00)
|
|
|
|
self.assertEqual((yield r2), 0b10)
|
|
|
|
self.assertEqual((yield r3), 0b00)
|
|
|
|
|
|
|
|
self.assertEqual((yield f0), 0b10)
|
|
|
|
self.assertEqual((yield f1), 0b00)
|
|
|
|
self.assertEqual((yield f2), 0b00)
|
|
|
|
self.assertEqual((yield f3), 0b00)
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.add_sync_process(process_gen)
|
|
|
|
sim.add_sync_process(process_check)
|
|
|
|
|
2019-11-22 01:32:41 -07:00
|
|
|
def test_vcd_wrong_nonzero_time(self):
|
|
|
|
s = Signal()
|
|
|
|
m = Module()
|
|
|
|
m.d.sync += s.eq(s)
|
|
|
|
sim = Simulator(m)
|
|
|
|
sim.add_clock(1e-6)
|
|
|
|
sim.run_until(1e-5)
|
|
|
|
with self.assertRaisesRegex(ValueError,
|
2020-07-02 16:49:04 -06:00
|
|
|
r"^Cannot start writing waveforms after advancing simulation time$"):
|
2019-11-22 01:32:41 -07:00
|
|
|
with sim.write_vcd(open(os.path.devnull, "wt")):
|
2018-12-29 08:02:04 -07:00
|
|
|
pass
|
2019-11-22 01:32:41 -07:00
|
|
|
|
2020-02-18 18:21:00 -07:00
|
|
|
|
|
|
|
class SimulatorRegressionTestCase(FHDLTestCase):
|
|
|
|
def test_bug_325(self):
|
|
|
|
dut = Module()
|
|
|
|
dut.d.comb += Signal().eq(Cat())
|
|
|
|
Simulator(dut).run()
|
|
|
|
|
|
|
|
def test_bug_325_bis(self):
|
|
|
|
dut = Module()
|
|
|
|
dut.d.comb += Signal().eq(Repl(Const(1), 0))
|
|
|
|
Simulator(dut).run()
|
2020-08-25 22:15:26 -06:00
|
|
|
|
|
|
|
def test_bug_473(self):
|
|
|
|
sim = Simulator(Module())
|
|
|
|
def process():
|
|
|
|
self.assertEqual((yield -(Const(0b11, 2).as_signed())), 1)
|
|
|
|
sim.add_process(process)
|
|
|
|
sim.run()
|