|
| 1 | +from amaranth import * |
| 2 | +from amaranth.sim import Simulator, Tick |
| 3 | + |
| 4 | +from pwm import PWMPeripheral, PWMPins |
| 5 | +import unittest |
| 6 | + |
| 7 | +class TestPwmPeripheral(unittest.TestCase): |
| 8 | + |
| 9 | + REG_NUMR = 0x00 |
| 10 | + REG_DENOM = 0x04 |
| 11 | + REG_CONF = 0x08 |
| 12 | + REG_STOP_INT = 0x0C |
| 13 | + REG_STATUS = 0x10 |
| 14 | + |
| 15 | + def _write_reg(self, dut, reg, value, width=4): |
| 16 | + for i in range(width): |
| 17 | + yield dut.bus.addr.eq(reg + i) |
| 18 | + yield dut.bus.w_data.eq((value >> (8 * i)) & 0xFF) |
| 19 | + yield dut.bus.w_stb.eq(1) |
| 20 | + yield Tick() |
| 21 | + yield dut.bus.w_stb.eq(0) |
| 22 | + |
| 23 | + def _check_reg(self, dut, reg, value, width=4): |
| 24 | + result = 0 |
| 25 | + for i in range(width): |
| 26 | + yield dut.bus.addr.eq(reg + i) |
| 27 | + yield dut.bus.r_stb.eq(1) |
| 28 | + yield Tick() |
| 29 | + result |= (yield dut.bus.r_data) << (8 * i) |
| 30 | + yield dut.bus.r_stb.eq(0) |
| 31 | + self.assertEqual(result, value) |
| 32 | + |
| 33 | + def test_pwm_o(self): |
| 34 | + dut = PWMPeripheral(name="dut", pins=PWMPins()) |
| 35 | + def testbench(): |
| 36 | + yield from self._write_reg(dut, self.REG_NUMR, 0x1F, 4) |
| 37 | + yield from self._write_reg(dut, self.REG_DENOM, 0xFF, 4) |
| 38 | + yield from self._write_reg(dut, self.REG_CONF, 0x03, 4) |
| 39 | + self.assertEqual((yield dut.pins.pwm_o), 1) # assert 32 cycles of logic '1'; 3 cycles go into writing conf register |
| 40 | + for i in range(29): yield Tick() |
| 41 | + self.assertEqual((yield dut.pins.pwm_o), 1) |
| 42 | + yield Tick() |
| 43 | + self.assertEqual((yield dut.pins.pwm_o), 0) # assert 224 cylces of logic '0' |
| 44 | + for i in range(223): yield Tick() |
| 45 | + self.assertEqual((yield dut.pins.pwm_o), 0) |
| 46 | + yield Tick() |
| 47 | + self.assertEqual((yield dut.pins.pwm_o), 1) # assert start of the next pulse |
| 48 | + for i in range(1000): yield Tick() |
| 49 | + sim = Simulator(dut) |
| 50 | + sim.add_clock(2e-6) |
| 51 | + sim.add_testbench(testbench) |
| 52 | + with sim.write_vcd("pwm_o_test.vcd", "pwm_o_test.gtkw"): |
| 53 | + sim.run() |
| 54 | + |
| 55 | + def test_conf(self): |
| 56 | + dut = PWMPeripheral(name="dut", pins=PWMPins()) |
| 57 | + def testbench(): |
| 58 | + yield from self._write_reg(dut, self.REG_NUMR, 0x1F, 4) |
| 59 | + yield from self._write_reg(dut, self.REG_DENOM, 0xFF, 4) |
| 60 | + yield from self._write_reg(dut, self.REG_CONF, 0x0, 4) |
| 61 | + self.assertEqual((yield dut.pins.pwm_o), 0) # assert pwm_o to remain '0', when not enabled |
| 62 | + for i in range(1000): yield Tick() |
| 63 | + sim = Simulator(dut) |
| 64 | + sim.add_clock(2e-6) |
| 65 | + sim.add_testbench(testbench) |
| 66 | + with sim.write_vcd("pwm_conf_test.vcd", "pwm_conf_test.gtkw"): |
| 67 | + sim.run() |
| 68 | + |
| 69 | + def test_dir(self): |
| 70 | + dut = PWMPeripheral(name="dut", pins=PWMPins()) |
| 71 | + def testbench(): |
| 72 | + yield from self._write_reg(dut, self.REG_NUMR, 0x1F, 4) |
| 73 | + yield from self._write_reg(dut, self.REG_DENOM, 0xFF, 4) |
| 74 | + yield from self._write_reg(dut, self.REG_CONF, 0x03, 4) |
| 75 | + self.assertEqual((yield dut.pins.dir_o), 1) # assert direction to be '1' |
| 76 | + for i in range(10): yield Tick() |
| 77 | + yield from self._write_reg(dut, self.REG_CONF, 0x01, 4) |
| 78 | + self.assertEqual((yield dut.pins.dir_o), 0) # assert direction to be '0' |
| 79 | + sim = Simulator(dut) |
| 80 | + sim.add_clock(2e-6) |
| 81 | + sim.add_testbench(testbench) |
| 82 | + with sim.write_vcd("pwm_dir_test.vcd", "pwm_dir_test.gtkw"): |
| 83 | + sim.run() |
| 84 | + |
| 85 | +if __name__ == "__main__": |
| 86 | + unittest.main() |
| 87 | + |
0 commit comments