Example #1
0
File: utils.py Project: FFY00/luna
    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")
Example #2
0
    def _resolve(self, expr):
        sim = Simulator(Module())

        a = []

        def testbench():
            a.append((yield expr))

        sim.add_process(testbench)
        sim.run()
        return a[0]
Example #3
0
def testbench():
    from nmigen.sim.pysim import Settle, Simulator

    unit = NotGate()

    def bench():
        yield unit.input.eq(0)
        yield Settle()
        assert (yield unit.output)

        yield unit.input.eq(1)
        yield Settle()
        assert not (yield unit.output)

    sim = Simulator(unit)
    sim.add_process(bench)
    with sim.write_vcd("notgate.vcd",
                       "notgate.gtkw",
                       traces=[unit.input, unit.output]):
        sim.run()
Example #4
0
    def elaborate(self, platform):
        m = Module()

        m.submodules += [
            self.timing,
            self.still,
        ]

        return m


if __name__ == '__main__':
    color_depth = 4
    image = gradient(color_depth=color_depth)
    timing = VgaTiming(resolutions[ResolutionName.VGA_640_480p_60hz])
    dut = TestBench(
        timing,
        Still(timing, color_depth=color_depth, image=image),
    )

    sim = Simulator(dut)

    def proc():
        for _ in range(800 * 40):
            yield

    sim.add_clock(1e-6, domain='pixel')
    sim.add_sync_process(proc, domain='pixel')
    with sim.write_vcd('still.vcd'):
        sim.run()
Example #5
0
from nmigen.sim.pysim import Simulator, Delay, Settle
from ecp5_pcie.dllp import PCIeDLLPTransmitter
from ecp5_pcie.serdes import PCIeSERDESInterface, Ctrl
import random

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

    output = Signal(18)
    m.submodules.dllpt = dllpt = PCIeDLLPTransmitter()

    m.d.comb += dllpt.send.eq(1)
    m.d.comb += dllpt.source.ready.eq(1)
    m.d.comb += dllpt.send.eq(1)

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

    # The other two DLLPs received from the ROCKPro64
    # Refer to layouts.py for the layout of the dllp record
    dllp_1 = 0b1000011100000001000000000100
    dllp_2 = 0b1000000100000001000000000101

    def process():
        yield dllpt.dllp.eq(dllp_1)
        #yield dllpt.dllp.valid.eq(0)
        for _ in range(20):
            print(hex((yield dllpt.source.symbol[0])), end="\t")
            print(hex((yield dllpt.source.symbol[1])), end="\t")
            print(hex((yield dllpt.source.symbol[2])), end="\t")
            print(hex((yield dllpt.source.symbol[3])))
Example #6
0
File: utils.py Project: FFY00/luna
class LunaGatewareTestCase(unittest.TestCase):

    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)
"""
from nmigen import Signal, Elaboratable, Module
from nmigen.sim.pysim import Simulator


class Top(Elaboratable):
    def __init__(self):
        self.counter = Signal(range(10))

    def elaborate(self, platform):
        m = Module()
        m.d.sync += self.counter.eq(self.counter + 1)

        return m


if __name__ == '__main__':

    def process():
        for tick in range(10):
            print(f"counter = {(yield dut.counter)}")
            yield

    dut = Top()
    sim = Simulator(dut)
    sim.add_clock(1e-6)
    sim.add_sync_process(process)

    with sim.write_vcd(f"{__file__[:-3]}.vcd"):
        sim.run()
Example #8
0
from nmigen import *
from nmigen.build import *
from nmigen.sim.pysim import Simulator, Delay, Settle
from ecp5_pcie.crc import CRC
from nmigen_boards.versa_ecp5_5g import VersaECP55GPlatform
import random

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

    m.submodules.crc = crc = CRC(Signal(16), 0xFFFF, 0x100B, 16)

    sim = Simulator(m)
    sim.add_clock(1/125e6, domain="sync")# For NextPNR, set the maximum clock frequency such that errors are given
    
    def process():
        # Simulate a DLLP which was received from the ROCKPro64
        yield
        yield crc.reset.eq(1)
        yield
        yield crc.reset.eq(0)
        yield crc.input.eq(0x0060)
        yield
        print(hex((yield crc.output)))
        yield crc.input.eq(0x0000)
        yield
        print(hex((yield crc.output)))
        yield
        print()
        # Should output 0x92d8
        print(hex((yield ~Cat(crc.output[::-1]))))
Example #9
0
    def test_sim_noiseshaper(self):
        fmt = Q(8, 18)
        input = fmt.Signal()
        dut = Noiseshaper(input, order=8, n_lev=64)

        sim = Simulator(dut)
        sim.add_clock(1 / 100e6)

        input_hist = []
        output_hist = []
        integrators_hist = [[] for _ in dut.stages]

        n = 8192
        f_nyquist = int(np.ceil(n / (2. * dut.osr)))
        f_test = np.floor(2. / 3. * f_nyquist)
        u = dut.n_lev * 0.5 * np.sin(2 * np.pi * f_test / n * np.arange(n))

        def testbench():
            for x in u:
                yield input.eq(x)

                input_hist.append(fmt.to_float((yield input.value)))
                output_hist.append(
                    fmt.to_float((yield dut.quantized_value.value)))
                for i, integrator in enumerate(dut.stages):
                    integrators_hist[i].append(
                        fmt.to_float((yield integrator.value)))

                yield

        sim.add_sync_process(testbench)

        sim.run()

        from matplotlib import pyplot as plt
        plt.plot(np.arange(n), output_hist, linewidth=1, label="output")
        plt.plot(np.arange(n), input_hist, label="input")
        plt.legend()
        plt.show()
        for i, integrator_hist in reversed(list(enumerate(integrators_hist))):
            plt.plot(np.arange(n),
                     integrator_hist,
                     linewidth=1,
                     label="integrator {}".format(i))
        plt.legend()
        plt.show()

        import deltasigma as ds
        f = np.linspace(0, 0.5, int(n / 2. + 1))

        v, xn, xmax, y = ds.simulateDSM(u,
                                        dut.h,
                                        nlev=len(dut.quantization_values))

        spec = np.fft.fft(v * ds.ds_hann(n)) / (n / 4)
        plt.plot(f, ds.dbv(spec[:int(n / 2. + 1)]), 'b', label='Simulation DS')

        spec = np.fft.fft(output_hist * ds.ds_hann(n)) / (n / 4)
        plt.plot(f,
                 ds.dbv(spec[:int(n / 2. + 1)]),
                 'g',
                 label='Simulation HW',
                 alpha=0.7)
        ds.figureMagic([0, 0.5], 0.05, None, [-160, 0], 20, None, (16, 6),
                       'Output Spectrum')
        plt.xlabel('Normalized Frequency')
        plt.ylabel('dBFS')
        snr = ds.calculateSNR(spec[2:f_nyquist + 1], f_test - 2)
        plt.text(0.05,
                 -10,
                 'SNR = %4.1fdB @ OSR = %d' % (snr, dut.osr),
                 verticalalignment='center')
        NBW = 1.5 / n
        Sqq = 4 * ds.evalTF(dut.h, np.exp(2j * np.pi * f))**2 / 3.
        plt.plot(f, ds.dbp(Sqq * NBW), 'm', linewidth=2, label='Expected PSD')
        plt.text(0.49,
                 -90,
                 'NBW = %4.1E x $f_s$' % NBW,
                 horizontalalignment='right')
        plt.legend(loc=4)
        plt.show()

        pwm_out = py_pwm.modulate(np.array(output_hist) + 32,
                                  n_bits=6,
                                  oversampling_ratio=1)
        n = n * 64
        f = np.linspace(0, 0.5, int(n / 2. + 1))
        spec = np.fft.fft(pwm_out * ds.ds_hann(n)) / (n / 4)
        plt.plot(f, ds.dbv(spec[:int(n / 2. + 1)]), 'b', label='PWM')
        ds.figureMagic([0, 0.5], 0.05, None, [-160, 0], 20, None, (16, 6),
                       'Output Spectrum')
        plt.xlabel('Normalized Frequency')
        plt.ylabel('dBFS')
        snr = ds.calculateSNR(spec[2:f_nyquist + 1], f_test - 2)
        plt.text(0.05,
                 -10,
                 'SNR = %4.1fdB @ OSR = %d' % (snr, dut.osr),
                 verticalalignment='center')
        plt.legend(loc=4)
        plt.show()