Ejemplo n.º 1
0
 def run_sim(self, process):
     sim = Simulator(self.lfsr)
     sim.add_clock(1)  # 1Hz for simplicity of counting
     sim.add_sync_process(process)
     sim.run()
Ejemplo n.º 2
0
class LunaGatewareTestCase(FHDLTestCase):

    domain = 'sync'

    # Convenience property: if set, instantiate_dut will automatically create
    # the relevant fragment with FRAGMENT_ARGUMENTS.
    FRAGMENT_UNDER_TEST = None
    FRAGMENT_ARGUMENTS = {}

    # Convenience properties: if not None, a clock with the relevant frequency
    # will automatically be added.
    FAST_CLOCK_FREQUENCY = None
    SYNC_CLOCK_FREQUENCY = 120e6
    USB_CLOCK_FREQUENCY = None

    def instantiate_dut(self):
        """ Basic-most function to instantiate a device-under-test.

        By default, instantiates FRAGMENT_UNDER_TEST.
        """
        return self.FRAGMENT_UNDER_TEST(**self.FRAGMENT_ARGUMENTS)

    def get_vcd_name(self):
        """ Return the name to use for any VCDs generated by this class. """
        return "test_{}".format(self.__class__.__name__)

    def setUp(self):
        self.dut = self.instantiate_dut()
        self.sim = Simulator(self.dut)

        if self.USB_CLOCK_FREQUENCY:
            self.sim.add_clock(1 / self.USB_CLOCK_FREQUENCY, domain="usb")
        if self.SYNC_CLOCK_FREQUENCY:
            self.sim.add_clock(1 / self.SYNC_CLOCK_FREQUENCY, domain="sync")
        if self.FAST_CLOCK_FREQUENCY:
            self.sim.add_clock(1 / self.FAST_CLOCK_FREQUENCY, domain="fast")

    def initialize_signals(self):
        """ Provide an opportunity for the test apparatus to initialize siganls. """
        yield Signal()

    def traces_of_interest(self):
        """ Returns an interable of traces to include in any generated output. """

        # Default to including all signals.
        return self.sim._signal_names

    def simulate(self, *, vcd_suffix=None):
        """ Runs our core simulation. """

        # If we're generating VCDs, run the test under a VCD writer.
        if os.getenv('GENERATE_VCDS', default=False):

            # Figure out the name of our VCD files...
            vcd_name = self.get_vcd_name()
            if vcd_suffix:
                vcd_name = "{}_{}".format(vcd_name, vcd_suffix)

            # ... and run the simulation while writing them.
            traces = self.traces_of_interest()
            with self.sim.write_vcd(vcd_name + ".vcd",
                                    vcd_name + ".gtkw",
                                    traces=traces):
                self.sim.run()

        else:
            self.sim.run()

    @staticmethod
    def pulse(signal, *, step_after=True):
        """ Helper method that asserts a signal for a cycle. """
        yield signal.eq(1)
        yield
        yield signal.eq(0)

        if step_after:
            yield

    @staticmethod
    def advance_cycles(cycles):
        """ Helper methods that waits for a given number of cycles. """

        for _ in range(cycles):
            yield

    @staticmethod
    def wait_until(strobe, *, timeout=None):
        """ Helper method that advances time until a strobe signal becomes true. """

        cycles_passed = 0

        while not (yield strobe):
            yield

            cycles_passed += 1
            if timeout and cycles_passed > timeout:
                raise RuntimeError(
                    f"Timeout waiting for '{strobe.name}' to go high!")

    def _ensure_clocks_present(self):
        """ Function that validates that a clock is present for our simulation domain. """
        frequencies = {
            'sync': self.SYNC_CLOCK_FREQUENCY,
            'usb': self.USB_CLOCK_FREQUENCY,
            'fast': self.FAST_CLOCK_FREQUENCY,
        }
        self.assertIsNotNone(
            frequencies[self.domain],
            f"no frequency provied for `{self.domain}`-domain clock!")

    def wait(self, time):
        """ Helper method that waits for a given number of seconds in a *_test_case. """

        # Figure out the period of the clock we want to work with...
        if self.domain == 'sync':
            period = 1 / self.SYNC_CLOCK_FREQUENCY
        elif self.domain == 'usb':
            period = 1 / self.USB_CLOCK_FREQUENCY
        elif self.domain == 'fast':
            period = 1 / self.FAST_CLOCK_FREQUENCY

        # ... and, accordingly, how many cycles we want to delay.
        cycles = math.ceil(time / period)
        print(cycles)

        # Finally, wait that many cycles.
        yield from self.advance_cycles(cycles)
Ejemplo n.º 3
0
from nmigen import *
from nmigen.back.pysim import Simulator, Delay, Settle
from ecp5_pcie.lfsr import PCIeLFSR
import random

if __name__ == "__main__":
    m = Module()

    m.submodules.lfsr = lfsr = PCIeLFSR(4, Signal(), 1)

    sim = Simulator(m)
    sim.add_clock(1 / 125e6, domain="rx")

    def process():
        for _ in range(20):
            print(hex((yield lfsr.output)))
            yield

        print()

        yield lfsr.reset.eq(1)
        yield
        yield lfsr.reset.eq(0)

        for _ in range(20):
            print(bin((yield lfsr.output + 0x100000000000000000)))
            yield

    sim.add_sync_process(
        process, domain="rx")  # or sim.add_sync_process(process), see below
Ejemplo n.º 4
0
class MonoFifoRGBTest(unittest.TestCase):
    def setUp(self):
        self.res = RESOLUTIONS['TEST16'] # Requires resolution divisible by 16
        self.video_timer = VideoTimer(self.res)
        self.fifo = SyncFIFO(width=16, depth=2, fwft=True)
        h = self.res.horizontal
        self.rgb = MonoFifoRGB(self.video_timer, self.fifo)

        m = Module()
        m.submodules += [self.fifo, self.rgb, self.video_timer]

        self.sim = Simulator(m)
        self.sim.add_clock(1) # 1Hz for simplicity of counting

        # Make a list of random numbers. Turn that into a list of bits
        self.test_numbers = [random.randrange(65536) for _ in range(500)]
        self.test_bits = all_bits_list(self.test_numbers)
        #sum([[int(b) for b in format(n, '016b')[::-1]] for n in self.test_numbers], [])

    def add_fill_fifo_process(self):
        # A process to continually fill the fifo
        def process():
            i = 0
            while True:
                for d in self.test_numbers:
                    while not (yield self.fifo.w_rdy):
                        yield
                    yield self.fifo.w_data.eq(d)
                    yield self.fifo.w_en.eq(1)
                    #print(f'writing {i}: {d} = {d:016b}')
                    i += 1
                    yield
        self.sim.add_sync_process(process)

    def show_fifo_state(self):
        # for debugging
        def process():
            f = self.fifo
            i = 0
            last_log = ''
            while True:
                r_rdy = yield f.r_rdy
                r_en = yield f.r_en
                r_data = yield f.r_data
                log = f'rdy:{r_rdy}, en:{r_en}, {r_data} = {r_data:016b}'
                if (log != last_log):
                    print(f'read_fifo@{i}: {log}')
                last_log = log
                yield
                i += 1
        self.sim.add_sync_process(process)

    def show_video_timer_state(self):
        # for debugging
        def process():
            vt = self.video_timer
            i = 0
            last_log = ''
            while True:
                active = yield vt.active
                nf = yield vt.at_frame_m1
                nl = yield vt.at_line_m1
                nal = yield vt.at_active_line_m1
                log = f'active:{active} nf:{nf} nl:{nl} nal:{nal}'
                if (log != last_log):
                    print(f'vt@{i}: {log}')
                last_log = log
                yield
                i += 1
        self.sim.add_sync_process(process)
        
    def test_signals(self):
        def process():
            while not (yield self.video_timer.at_frame_m1):
                r = yield self.rgb.red[0]
                g = yield self.rgb.green[0]
                b = yield self.rgb.blue[0]
                self.assertTrue((r, g, b) in [(1, 0, 1), (0, 1, 1)])
                yield
            pixel = 0
            bits = self.test_bits
            while bits:
                r = yield self.rgb.red[0]
                g = yield self.rgb.green[0]
                b = yield self.rgb.blue[0]
                if (yield self.video_timer.active):
                    #s = yield self.rgb.shift_register
                    #pc = yield self.rgb.pixel_counter
                    #srfmt = f'{s:016b}'[::-1]
                    #print(f'pixel {pixel} out: {r} expected: {bits[:16]} sr= {srfmt} pc={pc:03x}')
                    self.assertEqual(bits[0], r)
                    bits = bits[1:]
                    pixel += 1
                yield
        self.add_fill_fifo_process()
        #self.show_fifo_state()
        #self.show_video_timer_state()
        self.sim.add_sync_process(process)
        self.sim.run_until(5000)
Ejemplo n.º 5
0
                            fifo.r_en.eq(~ft_txe_n_i.i & fifo.r_rdy),
                        ]

        return m


if __name__ == "__main__":
    raw = Raw()

    parser = argparse.ArgumentParser()
    p_action = parser.add_subparsers(dest="action")
    p_action.add_parser("simulate")
    p_action.add_parser("generate")
    p_action.add_parser("build")

    args = parser.parse_args()
    if args.action == "simulate":
        sim = Simulator(raw)
        sim.add_clock(25e-9, domain="sync")
        sim.add_clock(25e-9, domain="clk40_neg")
        sim.add_clock(16.67e-9, domain="clk60")
        with sim.write_vcd("raw.vcd", "raw.gtkw"):
            sim.run()

    if args.action == "build":
        os.environ[
            "NMIGEN_add_constraints"
        ] = "set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets pin_ft_clkout_i_0/clk60_clk]"
        platform = FMCWRadar()
        platform.build(raw, do_program=True)
Ejemplo n.º 6
0
class VideoTimerTest(unittest.TestCase):
    def setUp(self):
        self.res = RESOLUTIONS['TEST']
        self.video_timer = VideoTimer(self.res)
        self.sim = Simulator(self.video_timer)
        self.sim.add_clock(1)  # 1Hz for simplicity of counting

    def test_signals(self):
        h = self.res.horizontal
        h_at = h.value_at
        v = self.res.vertical
        v_at = v.value_at

        def process():
            # step through cycles and assert each signal has correct value
            # for that cycle
            cycle = 0
            while True:
                x = yield self.video_timer.x.value
                assert_x = lambda step: self.assertEqual(x, h.value_at(step))
                y = yield self.video_timer.y.value
                assert_y = lambda step: self.assertEqual(y, v.value_at(step))

                pix_x = cycle % h.total
                pix_y = cycle // h.total % v.total
                self.assertEqual(x, h_at(pix_x))
                self.assertEqual(y, v_at(pix_y))

                ls = yield self.video_timer.at_line_m1
                self.assertEqual(ls, pix_x == h.total - 1)

                fs = yield self.video_timer.at_frame_m1
                self.assertEqual(fs, pix_x == h.total - 1
                                 and pix_y == v.total - 1)
                fsm2 = yield self.video_timer.at_frame_m2
                self.assertEqual(fsm2, pix_x == h.total - 2
                                 and pix_y == v.total - 1)

                self.assertEqual((yield self.video_timer.horizontal_sync),
                                 h.sync_start <= pix_x < h.sync_end)
                self.assertEqual((yield self.video_timer.vertical_sync),
                                 v.sync_start <= pix_y < v.sync_end)
                self.assertEqual(
                    (yield self.video_timer.vertical_blanking),
                    (pix_y == (v.active - 1) and pix_x >= h.active)
                    or pix_y >= v.active)
                self.assertEqual(
                    (yield self.video_timer.at_active_line_m1),
                    pix_x == (h.total - 1)
                    and (pix_y == (v.total - 1) or pix_y < v.active - 1))
                self.assertEqual(
                    (yield self.video_timer.at_active_line_m2),
                    pix_x == (h.total - 2)
                    and (pix_y == (v.total - 1) or pix_y < v.active - 1))
                self.assertEqual((yield self.video_timer.active),
                                 pix_x < h.active and pix_y < v.active)
                cycle += 1
                yield

        self.sim.add_sync_process(process)
        # Run 3 and a bit frames
        self.sim.run_until(self.res.frame_clocks * 3 + 100)
Ejemplo n.º 7
0
                sel = yield cpu.bus.sel_o
                if stb:
                    if we:
                        msk = 0xff if sel & 1 else 0
                        msk |= 0xff00 if sel & 2 else 0
                        msk |= 0xff0000 if sel & 4 else 0
                        msk |= 0xff000000 if sel & 8 else 0
                        mem[adr] = (mem.get(adr, 0) & ~msk) | (
                            (yield cpu.bus.dat_o) & msk)
                        print("Mem write addr {:08x} = {:08x}".format(
                            adr * 4, mem[adr]))
                    else:
                        if not adr in mem:
                            do = 0x00213200
                        else:
                            do = mem[adr]
                        yield cpu.bus.dat_i.eq(do)
                yield

        sim = Simulator(top)
        sim.add_clock(1e-7)
        sim.add_sync_process(process)
        with sim.write_vcd("test.vcd", "test.gtkw", traces=cpu.ports()):
            sim.run()
    else:
        parser = main_parser()
        args = parser.parse_args()
        m1, ports1 = ALU.formal()
        m2, ports2 = Cpu(32, 16).formal()
        main_runner(parser, args, m2, ports=ports2)
Ejemplo n.º 8
0
from nmigen import Signal, Value, Elaboratable, Module
from nmigen.back.pysim import Simulator, Delay

from cli import setup

from Simulations.Cases import *

if __name__ == "__main__":
    s = setup(False)
    m = s.m
    core = s.core

    simulation = TestCBA(core, m)
    simulation.load()

    sim = Simulator(m)
    sim.add_clock(1e-9, domain="ph1")

    simulation.add_process(sim)

    with sim.write_vcd("simulate.vcd", "simulate.gtkw", traces=core.ports()):
        sim.run()
Ejemplo n.º 9
0
def test_full_multi_sim():
    import random
    from nmigen.back.pysim import Simulator, Passive
    from ipaddress import IPv4Address
    from udptherbone.slip import SLIPUnframer, SLIPFramer, slip_encode, slip_decode
    from udptherbone.uart import UARTTx, UARTRx

    class Top(Elaboratable):
        def __init__(self, count):
            self.addrs = [Signal(32) for _ in range(count)]
            self.datas = [Signal(32, reset=0xCAFEBABE) for _ in range(count)]

            self.writes = Signal(range(count))
            self.reads = Signal(range(count))

            host_addr = IPv4Address("127.0.0.1")
            host_port = 2574
            dest_addr = IPv4Address("127.0.0.2")
            dest_port = 7777
            self.i = i = StreamSource(Layout([("data", 8, DIR_FANOUT)]),
                                      name="input",
                                      sop=False,
                                      eop=False)
            self.tx1 = tx1 = UARTTx(divisor=4)
            self.rx = rx = UARTRx(divisor=4)
            self.u = u = SLIPUnframer(rx.source)
            self.d = d = UDPDepacketizer(u.source, dest_addr, port=dest_port)
            self.wb = wb = UDPTherbone()
            self.p = p = UDPPacketizer(wb.source,
                                       dest_addr,
                                       host_addr,
                                       source_port=dest_port,
                                       dest_port=host_port)
            self.f = f = SLIPFramer(p.source)
            self.tx = tx = UARTTx(divisor=4)
            self.rx1 = rx1 = UARTRx(divisor=4)
            self.o = o = rx1.source

        def elaborate(self, platform):

            m = Module()

            m.submodules.tx1 = self.tx1
            m.submodules.rx = self.rx
            m.submodules.u = self.u
            m.submodules.d = self.d
            m.submodules.wb = self.wb
            m.submodules.p = self.p
            m.submodules.f = self.f
            m.submodules.tx = self.tx
            m.submodules.rx1 = self.rx1

            m.d.comb += self.rx.rx_i.eq(self.tx1.tx_o)
            m.d.comb += self.rx1.rx_i.eq(self.tx.tx_o)

            m.d.comb += self.tx1.sink.connect(self.i)
            m.d.comb += self.tx.sink.connect(self.f.source)

            m.d.comb += self.wb.sink.connect(self.d.source)

            dut = self.wb

            addrs = self.addrs

            m.d.sync += dut.interface.ack.eq(0)

            with m.If(dut.interface.stb & dut.interface.cyc
                      & dut.interface.we):
                m.d.sync += dut.interface.ack.eq(1)
                with m.Switch(self.writes):
                    for i in range(len(self.datas)):
                        with m.Case(i):
                            m.d.sync += addrs[i].eq(dut.interface.adr)
                            m.d.sync += self.datas[i].eq(dut.interface.dat_w)
                m.d.sync += self.writes.eq(self.writes + 1)

            with m.If(dut.interface.stb & dut.interface.cyc
                      & ~dut.interface.we):
                m.d.sync += dut.interface.ack.eq(1)
                with m.Switch(self.reads):
                    for i in range(len(self.datas)):
                        with m.Case(i):
                            m.d.sync += addrs[i].eq(dut.interface.adr)
                            m.d.sync += dut.interface.dat_r.eq(self.datas[i])
                m.d.sync += self.reads.eq(self.reads + 1)

            return m

    count = 3

    addrs = [random.getrandbits(32) for _ in range(count)]
    print()
    print(list(map(hex, addrs)))
    pkts = [eb_read([addrs[i]]) for i in range(count)]

    datas = [random.getrandbits(32) for _ in range(count)]
    print(list(map(hex, datas)))

    w_pkts = [
        slip_encode(
            raw(
                IP(src='127.0.0.1', dst='127.0.0.2', flags='DF') /
                UDP(dport=7777, sport=2574) / eb_write(addrs[i], [datas[i]])))
        for i in range(count)
    ]
    r_pkts = [
        slip_encode(
            raw(
                IP(src='127.0.0.1', dst='127.0.0.2', flags='DF') /
                UDP(dport=7777, sport=2574) / eb_read([addrs[i]])))
        for i in range(count)
    ]

    top = Top(count)
    i = top.i
    o = top.o

    received = Signal(range(count + 1))

    read = Signal()

    sim = Simulator(top)
    sim.add_clock(1e-6)

    def transmit_proc():
        yield
        for w_pkt in w_pkts:
            g = 0
            while g < len(w_pkt):
                c = w_pkt[g]
                yield i.data.eq(c)
                yield i.valid.eq(1)
                yield
                if (yield i.ready) == 1:
                    g += 1
            yield
            print("sent write pkt")

        pkts = 0
        for r_pkt in r_pkts:
            g = 0
            while g < len(r_pkt):
                c = r_pkt[g]
                yield i.data.eq(c)
                yield i.valid.eq(1)
                yield
                if (yield i.ready) == 1:
                    g += 1
            yield
            print("sent read pkt")
            pkts += 1
            while (yield received) < pkts:
                yield

    def receive_proc():
        import struct
        for g in range(0, 16):
            yield
        recv = [bytearray() for _ in range(count)]
        yield o.ready.eq(1)
        yield
        for g in range(count):
            while True:
                if (yield o.valid) == 1:
                    recv[g].append((yield o.data))
                    if (yield o.data) == 0xc0:
                        break
                yield
            yield
            print("received response pkt")
            yield received.eq(received + 1)

        for g in range(count):
            print(list(map(hex, recv[g])))
            i = IP(slip_decode(recv[g]))
            i.show()
            print(list(map(hex, i.load)))
            assert struct.unpack("!L", i.load[8:12])[0] == 0xdeadbeef
            assert struct.unpack("!L", i.load[12:16])[0] == datas[g]

    sim.add_sync_process(transmit_proc)
    sim.add_sync_process(receive_proc)

    with sim.write_vcd("wb_full_multi.vcd", "wb_full_multi.gtkw"):
        sim.run()
Ejemplo n.º 10
0
def test_write_multi_sim():
    import random
    from nmigen.back.pysim import Simulator, Passive

    class Top(Elaboratable):
        def __init__(self):
            self.dut = UDPTherbone()
            self.done = Signal(2)
            self.addrs = [Signal(32), Signal(32)]
            self.datas = [Signal(32), Signal(32)]
            pass

        def elaborate(self, platform):

            m = Module()

            m.submodules.dut = dut = self.dut

            m.d.comb += dut.interface.ack.eq(1)

            #addr = Mux(self.done[0], self.addrs[0], self.addrs[1])
            #data = Mux(self.done[0], self.datas[0], self.datas[1])
            #addr = self.addrs[self.done]
            #data = self.datas[self.done]

            addrs = self.addrs
            datas = self.datas
            done = self.done

            with m.If(dut.interface.stb & dut.interface.cyc
                      & dut.interface.we):
                with m.Switch(done):
                    with m.Case(0):
                        m.d.sync += addrs[0].eq(dut.interface.adr)
                        m.d.sync += datas[0].eq(dut.interface.dat_w)
                    with m.Case(1):
                        m.d.sync += addrs[1].eq(dut.interface.adr)
                        m.d.sync += datas[1].eq(dut.interface.dat_w)
                m.d.sync += done.eq(done + 1)

            return m

    addr = random.getrandbits(32)
    data0 = random.getrandbits(32)
    data1 = random.getrandbits(32)
    pkt = eb_write(addr, [data0, data1])

    top = Top()
    dut = top.dut
    i = top.dut.sink

    sim = Simulator(top)
    sim.add_clock(1e-6)

    def transmit_proc():
        yield dut.interface.ack.eq(1)
        yield
        g = 0
        while g < len(pkt):
            c = pkt[g]
            if g == 0:
                yield i.sop.eq(1)
            elif g == len(pkt) - 1:
                yield i.eop.eq(1)
            else:
                yield i.sop.eq(0)
                yield i.eop.eq(0)
            yield i.data.eq(c)
            yield i.valid.eq(1)
            yield
            if (yield i.ready) == 1:
                g += 1
        while (yield top.done) < 2:
            yield i.eop.eq(0)
            yield i.valid.eq(0)
            yield

        assert (yield top.addrs[0]) == addr
        assert (yield top.addrs[1]) == addr + 1
        assert (yield top.datas[0]) == data0
        assert (yield top.datas[1]) == data1

    sim.add_sync_process(transmit_proc)

    with sim.write_vcd("wb_multi.vcd", "wb_multi.gtkw"):
        sim.run()
Ejemplo n.º 11
0
def test_read_multi_sim():
    import random
    from nmigen.back.pysim import Simulator, Passive

    class Top(Elaboratable):
        def __init__(self, datas):
            self.dut = UDPTherbone()
            self.read = Signal(range(len(datas)))
            self.addr = Signal(32)
            self.datas = datas
            pass

        def elaborate(self, platform):

            m = Module()

            m.submodules.dut = dut = self.dut

            addr = self.addr

            m.d.sync += dut.interface.ack.eq(0)

            with m.If(dut.interface.stb & dut.interface.cyc
                      & ~dut.interface.we):
                m.d.sync += addr.eq(dut.interface.adr)
                with m.Switch(self.read):
                    for i in range(len(datas)):
                        with m.Case(i):
                            m.d.sync += dut.interface.dat_r.eq(self.datas[i])
                m.d.sync += dut.interface.ack.eq(1)
                m.d.sync += self.read.eq(self.read + 1)

            return m

    count = 5

    addrs = [random.getrandbits(32) for _ in range(count)]
    print()
    print(list(map(hex, addrs)))
    pkts = [eb_read([addrs[i]]) for i in range(count)]

    datas = [random.getrandbits(32) for _ in range(count)]
    print(list(map(hex, datas)))
    top = Top(datas)
    dut = top.dut
    i = top.dut.sink
    o = top.dut.source

    sim = Simulator(top)
    sim.add_clock(1e-6)

    def transmit_proc():
        yield
        for pkt in pkts:
            g = 0
            while g < len(pkt):
                c = pkt[g]
                yield i.sop.eq(0)
                yield i.eop.eq(0)
                if g == 0:
                    yield i.sop.eq(1)
                if g == len(pkt) - 1:
                    yield i.eop.eq(1)
                yield i.data.eq(c)
                yield i.valid.eq(1)
                yield
                if (yield i.ready) == 1:
                    g += 1
            print("sent pkt")

    def receive_proc():
        import struct
        for g in range(0, 16):
            yield
        recv = bytearray()
        yield o.ready.eq(1)
        yield
        recv = [bytearray() for _ in range(count)]
        for g in range(count):
            while not (yield o.sop):
                yield
            while not (yield o.eop):
                if (yield o.valid) == 1:
                    recv[g].append((yield o.data))
                yield
            if (yield o.valid) == 1:
                recv[g].append((yield o.data))

        for g in range(count):
            print(list(map(hex, recv[g])))
            assert struct.unpack("!L", recv[g][8:12])[0] == 0xdeadbeef
            assert struct.unpack("!L", recv[g][12:16])[0] == datas[g]

    sim.add_sync_process(transmit_proc)
    sim.add_sync_process(receive_proc)

    with sim.write_vcd("wb_rd_multi.vcd", "wb_rd_multi.gtkw"):
        sim.run()
Ejemplo n.º 12
0
def test_write_sim():
    import random
    from nmigen.back.pysim import Simulator, Passive

    class Top(Elaboratable):
        def __init__(self):
            self.dut = UDPTherbone()
            self.done = Signal()
            self.addr = Signal(32)
            self.data = Signal(32)
            pass

        def elaborate(self, platform):

            m = Module()

            m.submodules.dut = dut = self.dut

            m.d.comb += dut.interface.ack.eq(1)

            addr = self.addr
            data = self.data
            done = self.done

            with m.If(dut.interface.stb & dut.interface.cyc
                      & dut.interface.we):
                m.d.sync += addr.eq(dut.interface.adr)
                m.d.sync += data.eq(dut.interface.dat_w)
                m.d.sync += done.eq(1)

            return m

    addr = random.getrandbits(32)
    data = random.getrandbits(32)
    pkt = eb_write(addr, [data])

    top = Top()
    dut = top.dut
    i = top.dut.sink

    sim = Simulator(top)
    sim.add_clock(1e-6)

    def transmit_proc():
        yield dut.interface.ack.eq(1)
        yield
        g = 0
        while g < len(pkt):
            c = pkt[g]
            if g == 0:
                yield i.sop.eq(1)
            elif g == len(pkt) - 1:
                yield i.eop.eq(1)
            else:
                yield i.sop.eq(0)
                yield i.eop.eq(0)
            yield i.data.eq(c)
            yield i.valid.eq(1)
            yield
            if (yield i.ready) == 1:
                g += 1
        while not (yield top.done):
            yield i.eop.eq(0)
            yield i.valid.eq(0)
            yield

        assert (yield top.addr) == addr
        assert (yield top.data) == data

    sim.add_sync_process(transmit_proc)

    with sim.write_vcd("wb.vcd", "wb.gtkw"):
        sim.run()
Ejemplo n.º 13
0
def test_read_delay_sim():
    import random
    from nmigen.back.pysim import Simulator, Passive

    class Top(Elaboratable):
        def __init__(self, data):
            self.dut = UDPTherbone()
            self.done = Signal()
            self.addr = Signal(32)
            self.data = data
            pass

        def elaborate(self, platform):

            m = Module()

            m.submodules.dut = dut = self.dut

            addr = self.addr
            done = self.done

            counter = Signal(3)

            m.d.sync += dut.interface.ack.eq(0)

            with m.If(dut.interface.stb & dut.interface.cyc
                      & ~dut.interface.we):
                m.d.sync += counter.eq(1)
                m.d.sync += addr.eq(dut.interface.adr)

            with m.If(counter > 0):
                m.d.sync += counter.eq(counter + 1)

            with m.If(counter == 4):
                m.d.sync += dut.interface.dat_r.eq(self.data)
                m.d.sync += dut.interface.ack.eq(1)
                m.d.sync += done.eq(1)

            return m

    addr = random.getrandbits(32)
    print()
    print(hex(addr))
    pkt = eb_read([addr])

    data = random.getrandbits(32)
    #data = 0xBABECAFE
    print(hex(data))
    top = Top(data)
    dut = top.dut
    i = top.dut.sink
    o = top.dut.source

    sim = Simulator(top)
    sim.add_clock(1e-6)

    def transmit_proc():
        yield
        g = 0
        while g < len(pkt):
            c = pkt[g]
            if g == 0:
                yield i.sop.eq(1)
            elif g == len(pkt) - 1:
                yield i.eop.eq(1)
            else:
                yield i.sop.eq(0)
                yield i.eop.eq(0)
            yield i.data.eq(c)
            yield i.valid.eq(1)
            yield
            if (yield i.ready) == 1:
                g += 1
        while not (yield top.done):
            yield i.eop.eq(0)
            yield i.valid.eq(0)
            yield
        yield

        print("tx done")

        assert (yield top.addr) == addr

    def receive_proc():
        import struct
        for g in range(0, 16):
            yield
        recv = bytearray()
        yield o.ready.eq(1)
        yield
        while not (yield o.eop):
            if (yield o.valid) == 1:
                recv.append((yield o.data))
            yield
        if (yield o.valid) == 1:
            recv.append((yield o.data))
        yield

        assert struct.unpack("!L", recv[8:12])[0] == 0xdeadbeef
        assert struct.unpack("!L", recv[12:16])[0] == data

    sim.add_sync_process(transmit_proc)
    sim.add_sync_process(receive_proc)

    with sim.write_vcd("wb_rd_dly.vcd", "wb_rd_dly.gtkw"):
        sim.run()
    ]

    #Instantiate the LDPC_Encoder Module with the generator matrix and output codeword size as parameters
    m.submodules.LDPC_Encoder = LDPC_Encoder = LDPC_Encoder(generatorMatrix, 6)

    #Simulation

    #[SIGNAL] - data_input - A top level signal which connects the 'data_input' signal on the LDPC Encoder
    data_input = Signal(len(generatorMatrix))

    #[SIGNAL] - start - A top level signal which connects the 'start' signal on the LDPC Encoder
    start = Signal(1)

    #Link the local data_input and start signals to the LDPC Input Ports
    m.d.comb += LDPC_Encoder.data_input.eq(data_input)
    m.d.comb += LDPC_Encoder.start.eq(start)

    #Create a simulator instance with the local nMigen module which contains the LDPC Encoder
    sim = Simulator(m)

    #Add a synchronous testbench process to the simulator
    sim.add_sync_process(testbench_process)

    #Add a clock to the simulator
    sim.add_clock(1e-6)

    #Run the simulation with all input and output ports from the LDPC_Encoder and write out the results
    with sim.write_vcd("test_6_3.vcd",
                       "test_6_3.gtkw",
                       traces=[data_input, start] + LDPC_Encoder.ports()):
        sim.run()
Ejemplo n.º 15
0
class LunaGatewareTestCase(FHDLTestCase):

    # Convenience property: if set, instantiate_dut will automatically create
    # the relevant fragment with FRAGMENT_ARGUMENTS.
    FRAGMENT_UNDER_TEST = None
    FRAGMENT_ARGUMENTS = {}

    # Convenience property: if not None, a clock with the relevant frequency
    # will automatically be added.
    CLOCK_FREQUENCY = 60e6

    def instantiate_dut(self):
        """ Basic-most function to instantiate a device-under-test.

        By default, instantiates FRAGMENT_UNDER_TEST.
        """
        return self.FRAGMENT_UNDER_TEST(**self.FRAGMENT_ARGUMENTS)

    def get_vcd_name(self):
        """ Return the name to use for any VCDs generated by this class. """
        return "test_{}".format(self.__class__.__name__)

    def setUp(self):
        self.dut = self.instantiate_dut()
        self.sim = Simulator(self.dut)

        if self.CLOCK_FREQUENCY:
            self.sim.add_clock(1 / self.CLOCK_FREQUENCY)

    def initialize_signals(self):
        pass

    def get_timestamp(self):
        """ Returns the current timestamp in the simulation."""

        # FIXME: figure out how to do this correctly
        return self.sim._state.timestamp

    def traces_of_interest(self):
        """ Returns an interable of traces to include in any generated output. """
        return ()

    def simulate(self, *, vcd_suffix=None):
        """ Runs our core simulation. """

        # If we're generating VCDs, run the test under a VCD writer.
        if os.getenv('GENERATE_VCDS', default=False):

            # Figure out the name of our VCD files...
            vcd_name = self.get_vcd_name()
            if vcd_suffix:
                vcd_name = "{}_{}".format(vcd_name, vcd_suffix)

            # ... and run the simulation while writing them.
            traces = self.traces_of_interest()
            with self.sim.write_vcd(vcd_name + ".vcd",
                                    vcd_name + ".gtkw",
                                    traces=traces):
                self.sim.run()

        else:
            self.sim.run()

    @staticmethod
    def pulse(signal):
        """ Helper method that asserts a signal for a cycle. """
        yield signal.eq(1)
        yield
        yield signal.eq(0)
        yield

    @staticmethod
    def advance_cycles(cycles):
        """ Helper methods that waits for a given number of cycles. """

        for _ in range(cycles):
            yield
Ejemplo n.º 16
0
class FakeSinglePortRamTest(unittest.TestCase):

    def setUp(self):
        m = Module()
        m.submodules.ram = self.ram = FakeSinglePortRam()
        self.sim = Simulator(m)
        self.sim.add_clock(1) # 1Hz for simplicity of counting

    def run_sim(self, p):
        self.sim.add_sync_process(p)
        self.sim.run()
        #with self.sim.write_vcd("zz.vcd", "zz.gtkw"):
        #    self.sim.run()

    def test_write_read(self):
        r = self.ram
        def process():
            yield r.cs.eq(1)
            yield r.addr.eq(5)
            yield r.data_in.eq(0x1234)
            yield r.wren.eq(1)
            yield # Writes ram[5]=0x1234

            yield r.addr.eq(25)
            yield r.data_in.eq(0x5678)
            yield # Writes ram[25]=0x5678

            yield r.addr.eq(5)
            yield r.wren.eq(0)
            yield # Command to read ram[5]
            self.assertEqual(0, (yield r.data_out)) # Should be zero until read completes
            yield # Command completes
            self.assertEqual(0x1234, (yield r.data_out))
        self.run_sim(process)

    def test_cs(self):
        r = self.ram
        def process():
            yield r.cs.eq(1)
            yield r.addr.eq(10)
            yield r.data_in.eq(0x1234)
            yield r.wren.eq(1)
            yield # Writes ram[10]=0x1234

            yield r.cs.eq(0)
            yield r.addr.eq(11)
            yield r.data_in.eq(0x1234)
            yield r.wren.eq(1)
            yield # DOES NOT write ram[11]=0x1234

            yield r.cs.eq(1)
            yield r.wren.eq(0)
            yield r.addr.eq(10)
            yield # Command to read ram[10]
            yield
            self.assertEqual(0x1234, (yield r.data_out))

            yield r.cs.eq(0)
            yield r.wren.eq(0)
            yield r.addr.eq(10)
            yield # Does not read ram[10]
            yield
            self.assertEqual(0, (yield r.data_out))

            yield r.cs.eq(1)
            yield r.wren.eq(0)
            yield r.addr.eq(11)
            yield # Command to read ram[11], which is empty
            yield
            self.assertEqual(0, (yield r.data_out))

            self.assertEqual(0, (yield r.data_out)) # Should be zero until read completes
            yield # Command completes
        self.run_sim(process)
Ejemplo n.º 17
0
# yield sig.eq(val) --> update the simulated signal

dut = UpCounter(25)

def bench():
    # Disabled counter should not overflow
    yield dut.en.eq(0) # disable counter
    for _ in range(30):
        yield # advance the sim by 1 clock
        assert not (yield dut.ovf) # ovf should be 0

    # Once enabled, the counter should overflow in 25 cycles
    yield dut.en.eq(1) # enable counter
    for _ in range(25):
        yield 
        assert not (yield dut.ovf)
    
    yield
    assert (yield dut.ovf)

    # The overflow should clear in one cycle
    yield 
    assert not (yield dut.ovf)

sim = Simulator(dut)
sim.add_clock(1e-6) # 1MHz
sim.add_sync_process(bench)
with sim.write_vcd("up_counter.vcd"):
    sim.run()