Exemplo n.º 1
0
 def setUp(self):
     # Ensure IS_SIM_RUN set
     global _IS_SIM_RUN
     _IS_SIM_RUN = True
     # Create DUT and add to simulator
     self.m = Module()
     self.dut = self.create_dut()
     self.m.submodules['dut'] = self.dut
     self.m.submodules['dummy'] = _DummySyncModule()
     self.sim = Simulator(self.m)
Exemplo n.º 2
0
    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")
        if self.SS_CLOCK_FREQUENCY:
            self.sim.add_clock(1 / self.SS_CLOCK_FREQUENCY, domain="ss")
Exemplo n.º 3
0
def test_counter():
    """Simple testbench for the Counter above."""

    # Create a counter with a rollover at 18.
    # This awkward non-power-of-two value will help test that we're not
    # rolling over by accident of the bit width of the counter.
    counter = Counter(limit=18)

    # Test benches are written as Python generators, which yield
    # commands to the simulator such as "send me the current value of this
    # signal" or "advance the simulation by one clock cycle".
    def testbench():
        for step in range(20):
            # Check outputs are correct at each step.
            assert (yield counter.counter) == (step % 18)
            if step == 17:
                assert (yield counter.rollover)
            else:
                assert not (yield counter.rollover)

            # Advance simulation by one cycle.
            yield

    sim = Simulator(counter)

    # To test synchronous processes, we create a clock at some nominal
    # frequency (which only changes the displayed timescale in the output),
    # and add our testbench as a "synchronous" process.
    sim.add_clock(1 / 10e6)
    sim.add_sync_process(testbench)

    sim.run()
Exemplo n.º 4
0
def test_comb_alu():
    alu = ALU()

    def testbench():
        for a in range(20):
            yield alu.a.eq(a)
            for b in range(20):
                yield alu.b.eq(b)

                # In this combinatorial testbench, we use `yield Settle()`
                # to request the simulator advance until all combinatorial
                # statements have been fully resolved.
                yield alu.op.eq(1)
                yield Settle()
                assert (yield alu.y) == a + b

                yield alu.op.eq(0)
                yield Settle()
                assert (yield alu.y) == (a - b) % 512

    sim = Simulator(alu)

    # Instead of `sim.add_sync_process`, which would try to use a clock domain
    # (by default, "sync") and error out saying it doesn't exist, we use
    # `sim.add_process`.
    sim.add_process(testbench)

    sim.run()
Exemplo n.º 5
0
class TestBase(unittest.TestCase):
    """Base class for testing an Amaranth module.

    The module can use sync, comb or both.
    """
    def setUp(self):
        # Ensure IS_SIM_RUN set
        global _IS_SIM_RUN
        _IS_SIM_RUN = True
        # Create DUT and add to simulator
        self.m = Module()
        self.dut = self.create_dut()
        self.m.submodules['dut'] = self.dut
        self.m.submodules['dummy'] = _DummySyncModule()
        self.sim = Simulator(self.m)

    def create_dut(self):
        """Returns an instance of the device under test"""
        raise NotImplementedError

    def add_process(self, process):
        """Add main test process to the simulator"""
        self.sim.add_sync_process(process)

    def add_sim_clocks(self):
        """Add clocks as required by sim.
        """
        self.sim.add_clock(1, domain='sync')

    def run_sim(self, process, write_trace=False):
        self.add_process(process)
        self.add_sim_clocks()
        if write_trace:
            with self.sim.write_vcd("zz.vcd", "zz.gtkw"):
                self.sim.run()
            # Discourage commiting code with tracing active
            self.fail("Simulation tracing active. "
                      "Turn off after debugging complete.")
        else:
            self.sim.run()
Exemplo n.º 6
0
        uart.tx_data, uart.tx_rdy, uart.tx_ack,
        uart.rx_data, uart.rx_rdy, uart.rx_err, uart.rx_ovf, uart.rx_ack
    ]

    import argparse

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

    args = parser.parse_args()
    if args.action == "simulate":
        from amaranth.sim import Simulator, Passive

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

        def loopback_proc():
            yield Passive()
            while True:
                yield uart.rx_i.eq((yield uart.tx_o))
                yield
        sim.add_sync_process(loopback_proc)

        def transmit_proc():
            assert (yield uart.tx_ack)
            assert not (yield uart.rx_rdy)

            yield uart.tx_data.eq(0x5A)
            yield uart.tx_rdy.eq(1)
Exemplo n.º 7
0
            yield Tick("usb")
        # send USB MIDI sysex
        yield from sysex(0x04, 0xf0, 0x0a, 0x0b, 0x07, 0x0c, 0x0d, 0xf7)
        for _ in range(40):
            yield Tick("usb")
        yield dut.midi_stream.valid.eq(1)
        yield from midi_message(0x93, 60, 0x7f, set_valid=False)
        yield Tick("usb")
        yield from midi_message(0x93, 61, 0x7f, set_valid=False)
        yield dut.midi_stream.valid.eq(0)
        for _ in range(128):
            yield Tick("usb")

    def jt51_process():
        yield Tick("jt51")
        yield Tick("jt51")
        yield Tick("jt51")
        yield Tick("jt51")
        yield dut.jt51_stream.ready.eq(1)
        for _ in range(50):
            yield Tick("jt51")

    sim = Simulator(dut)
    sim.add_clock(1.0/60e6, domain="usb")
    sim.add_clock(1.0/3e6,  domain="jt51")
    sim.add_sync_process(usb_process, domain="usb")
    sim.add_sync_process(jt51_process, domain="jt51")

    with sim.write_vcd(f'midicontroller.vcd'):
        sim.run()
Exemplo n.º 8
0
    # Disabled counter should not overflow.
    yield dut.en.eq(0)
    for _ in range(30):
        yield
        assert not (yield dut.ovf)

    # Once enabled, the counter should overflow in 25 cycles.
    yield dut.en.eq(1)
    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)  # 1 MHz
sim.add_sync_process(bench)
with sim.write_vcd("up_counter.vcd"):
    sim.run()
# --- CONVERT ---
from amaranth.back import verilog

top = UpCounter(25)
with open("up_counter.v", "w") as f:
    f.write(verilog.convert(top, ports=[top.en, top.ovf]))
Exemplo n.º 9
0
def reg_test(
    name: str,
    timeout_cycles: Optional[int],
    reg_num: int,
    expected_val: Optional[int],
    expected_mem: Optional[MemoryContents],
    reg_init: RegistryContents,
    mem_cfg: EBRMemConfig,
    verbose: bool = False,
):

    cpu = MtkCpu(
        reg_init=reg_init.reg, 
        with_debug=False, # XXX
        mem_config=mem_cfg
    )

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

    assert (reg_num is None and expected_val is None) or (
        reg_num is not None and expected_val is not None
    )
            
    # Since Amaranth HDL's 'Memory' instance simulation in included,
    # we don't need to use custom implementation (however some coverage drop
    # is present - 'Memory' class is assumed single-cycle-access, while
    # 'get_sim_memory_test' processing delay is random).
    # sim.add_sync_process(get_sim_memory_test(cpu=cpu, mem_dict=mem_dict))
    # instead only collect write transactions directly on a bus.
    result_mem = {}
    sim.add_sync_process(capture_write_transactions(cpu=cpu, dict_reference=result_mem))
    
    sim.add_sync_process(
        get_sim_register_test(
            name=name,
            cpu=cpu,
            reg_num=reg_num,
            expected_val=expected_val,
            timeout_cycles=timeout_cycles,
        )
    )

    csr_unit : CsrUnit = cpu.csr_unit
    # frag = Fragment.get(cpu, platform=None)
    # main_fsm = frag.find_generated("fsm")
    e = cpu.exception_unit
    sim_traces = [
        # main_fsm.state,
        # e.m_instruction,
        # e.mtval.value,
        # csr_unit.mtvec.base,
        # csr_unit.mtvec.mode,
        # *csr_unit.mepc.fields.values(),
        *csr_unit.mcause.fields.values(),
        *csr_unit.satp.fields.values(),
        # *csr_unit.mie.fields.values(),
        # *csr_unit.mstatus.fields.values(),
        # *csr_unit.mtime.fields.values(),
        # *csr_unit.mtimecmp.fields.values(),
        cpu.instr,
        cpu.pc,
        # csr_unit.rs1,
        # csr_unit.csr_idx,
        # csr_unit.rd,
        # csr_unit.rd_val,
        # csr_unit.vld,
        # csr_unit.ONREAD,
        # csr_unit.ONWRITE,
        cpu.arbiter.pe.i,
        cpu.arbiter.pe.o,
        cpu.arbiter.pe.none,
        cpu.arbiter.bus_free_to_latch,

        cpu.arbiter.error_code,
        cpu.arbiter.addr_translation_en,
        cpu.arbiter.translation_ack,
        cpu.arbiter.start_translation,
        cpu.arbiter.phys_addr,
        cpu.arbiter.root_ppn,

        *cpu.arbiter.pte.fields.values(),

        cpu.arbiter.generic_bus.addr,
        cpu.arbiter.generic_bus.read_data,
        cpu.arbiter.vpn,
    ]

    # from amaranth.back import verilog
    # s = verilog.convert(cpu)
    # open("cpu.v", "w").write(s)

    with sim.write_vcd("cpu.vcd", "cpu.gtkw", traces=sim_traces):
        sim.run()

    if expected_mem is not None:
        MemoryContents(result_mem).assert_equality(expected_mem)
Exemplo n.º 10
0
                break
            yield
            
    return m, f


def unit_testbench(case: ComponentTestbenchCase):
    if case.component_type == MemoryArbiter:
        m, f = memory_arbiter_tb()
    elif case.component_type == GPIO_Wishbone:
        m, f = gpio_tb()
    else:
        print(f"===== Skipping not covered type {case.component_type}")
        return

    sim = Simulator(m)
    sim.add_clock(1e-6)
    sim.add_sync_process(f)

    with sim.write_vcd(f"{case.name}.vcd"):
        sim.run()


# returns ELF path
def compile_sw_project(proj_name : str) -> Path:
    sw_dir = Path(__file__).parent.parent.parent / "sw"
    proj_dir = sw_dir / proj_name
    if not proj_dir.exists() or not proj_dir.is_dir():
        raise ValueError(f"Compilation failed: Directory {proj_dir} does not exists!")
    from mtkcpu.utils.linker import write_linker_script
    write_linker_script(sw_dir / "common" / "linker.ld", CODE_START_ADDR)
Exemplo n.º 11
0
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
    SS_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")
        if self.SS_CLOCK_FREQUENCY:
            self.sim.add_clock(1 / self.SS_CLOCK_FREQUENCY, domain="ss")

    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. """
        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, *, 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,
            'ss': self.SS_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)
Exemplo n.º 12
0
def test_with_samplerate(samplerate: int = 48000):
    clk_freq = 50e6
    dut = ADATTransmitter()
    adat_freq = NRZIDecoder.adat_freq(samplerate)
    clockratio = clk_freq / adat_freq

    print(f"FPGA clock freq: {clk_freq}")
    print(f"ADAT clock freq: {adat_freq}")
    print(f"FPGA/ADAT freq: {clockratio}")

    sim = Simulator(dut)
    sim.add_clock(1.0 / clk_freq, domain="sync")
    sim.add_clock(1.0 / adat_freq, domain="adat")

    def write(addr: int,
              sample: int,
              last: bool = False,
              drop_valid: bool = False):
        while (yield dut.ready_out == 0):
            yield from wait(1)
        if last:
            yield dut.last_in.eq(1)
        yield dut.addr_in.eq(addr)
        yield dut.sample_in.eq(sample)
        yield dut.valid_in.eq(1)
        yield Tick("sync")
        if drop_valid:
            yield dut.valid_in.eq(0)
        if last:
            yield dut.last_in.eq(0)

    def wait(n_cycles: int):
        for _ in range(int(clockratio) * n_cycles):
            yield Tick("sync")

    def sync_process():
        yield Tick("sync")
        yield Tick("sync")
        yield dut.user_data_in.eq(0xf)
        for i in range(4):
            yield from write(i, i, drop_valid=True)
        for i in range(4):
            yield from write(4 + i, 0xc + i, i == 3, drop_valid=True)
        yield dut.user_data_in.eq(0xa)
        yield Tick("sync")
        for i in range(8):
            yield from write(i, (i + 1) << 4, i == 7)
        yield dut.user_data_in.eq(0xb)
        yield Tick("sync")
        for i in range(8):
            yield from write(i, (i + 1) << 8, i == 7)
        yield dut.user_data_in.eq(0xc)
        yield Tick("sync")
        for i in range(8):
            yield from write(i, (i + 1) << 12, i == 7)
        yield dut.user_data_in.eq(0xd)
        yield Tick("sync")
        for i in range(8):
            yield from write(i, (i + 1) << 16, i == 7)
        yield dut.user_data_in.eq(0xe)
        yield Tick("sync")
        for i in range(8):
            yield from write(i, (i + 1) << 20, i == 7, drop_valid=True)
        yield from wait(900)

    def adat_process():
        nrzi = []
        i = 0
        while i < 1800:
            yield Tick("adat")
            out = yield dut.adat_out
            nrzi.append(out)
            i += 1

        # skip initial zeros
        nrzi = nrzi[nrzi.index(1):]
        signal = decode_nrzi(nrzi)
        decoded = adat_decode(signal)
        print(decoded)
        user_bits = [decoded[frame][0] for frame in range(7)]
        assert user_bits == [0x0, 0xf, 0xa, 0xb, 0xc, 0xd,
                             0xe], print_assert_failure(user_bits)
        assert decoded[0][1:] == [0, 0, 0, 0, 0, 0, 0,
                                  0], print_assert_failure(decoded[0][1:])
        assert decoded[1][1:] == [0, 1, 2, 3, 0xc, 0xd, 0xe,
                                  0xf], print_assert_failure(decoded[1][1:])
        assert decoded[2][1:] == [
            0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80
        ], print_assert_failure(decoded[2][1:])
        assert decoded[3][1:] == [
            0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800
        ], print_assert_failure(decoded[3][1:])
        assert decoded[4][1:] == [
            0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000
        ], print_assert_failure(decoded[4][1:])
        assert decoded[5][1:] == [
            0x10000, 0x20000, 0x30000, 0x40000, 0x50000, 0x60000, 0x70000,
            0x80000
        ], print_assert_failure(decoded[5][1:])

    sim.add_sync_process(sync_process, domain="sync")
    sim.add_sync_process(adat_process, domain="adat")

    with sim.write_vcd(f'transmitter-smoke-test-{str(samplerate)}.vcd'):
        sim.run()
Exemplo n.º 13
0
def test_riscv_dv(cfg: RiscvDvTestConfig):
    sys.setrecursionlimit(10**6) # otherwise amaranth/sim/_pyrtl.py:441: RecursionError, because of huge memory size
    max_code_size = cfg.test_elf.stat().st_size
    program = read_elf(cfg.test_elf)
    mem_cfg = EBRMemConfig.from_mem_dict(
        start_addr=cfg.start_addr,
        num_bytes=max_code_size,
        simulate=True,
        mem_dict=MemoryContents(program),
    )

    cpu = MtkCpu(
        with_debug=False,
        mem_config=mem_cfg
    )

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

    traces = [
        cpu.pc,
        cpu.instr,
        cpu.rd,
        cpu.should_write_rd,
        *cpu.csr_unit.satp.fields.values(),
        cpu.exception_unit.current_priv_mode,
        
        cpu.arbiter.pe.i,
        cpu.arbiter.pe.o,
        cpu.arbiter.pe.none,
        cpu.arbiter.bus_free_to_latch,

        cpu.arbiter.error_code,
        cpu.arbiter.addr_translation_en,
        cpu.arbiter.translation_ack,
        cpu.arbiter.start_translation,
        cpu.arbiter.phys_addr,
        cpu.arbiter.root_ppn,

        *cpu.arbiter.pte.fields.values(),

        cpu.arbiter.generic_bus.addr,
        cpu.arbiter.generic_bus.read_data,
        cpu.arbiter.vpn,
        cpu.arbiter.error_code,
    ]

    csv_output = tempfile.NamedTemporaryFile(
        suffix=f".mtkcpu.{cfg.test_name}.csv", 
        dir=Path(__file__).parent.name, 
        delete=False
    )
    fn = riscv_dv_sim_process(
        cpu=cpu,
        iss_csv=cfg.iss_csv,
        compare_every=cfg.compare_every,
        csv_output=Path(csv_output.name),
    )
    sim.add_sync_process(fn)
    
    with sim.write_vcd("cpu.vcd", "cpu.gtkw", traces=traces):
        sim.run()
    print("== Waveform dumped to cpu.vcd file")
Exemplo n.º 14
0
#        lane.rx_symbol, lane.tx_symbol,# lane.tx_symbol,
#        lane.rx_aligned, lane.rx_locked & lane.rx_present & lane.rx_aligned, dtr.temperature, phy.ltssm.debug_state#, phy.dll.tx.started_sending, phy.dll.tx.started_sending#dtr.temperature
#        ), "rx")#, enable = (sample_data != 0) | start_condition)#, enable = phy.ltssm.debug_state == State.L0)
#
        return m


# -------------------------------------------------------------------------------------------------

if __name__ == "__main__":
    m = Module()
    m.submodules.pcie = pcie = VirtualPCIeTestbench()

    dll_status = pcie.phy_d.dll.status

    sim = Simulator(m)

    #sim.add_clock(8e-9, domain="tx")
    #sim.add_clock(8e-9, domain="rx")
    sim.add_clock(1e-8, domain="sync")  # Everything in sync domain

    def process():
        a = 1
        last_state = 0
        last_retry_buffer_occupation = 0
        last_receive_buffer_occupation = 0
        last_tx_seq_num = 0
        last_rx_seq_num = 0
        ack_scheduled_last = 0
        for i in range(100 * 1000 * 24):
            state = State((yield pcie.phy_d.ltssm.debug_state)).name
Exemplo n.º 15
0
        m.d.comb += buffer.tlp_sink.symbol[0].eq(val)
        m.d.comb += Cat(buffer.tlp_sink.valid).eq(
            Mux(val <= end_val, 0b1111, 0b0000))
        m.d.rx += val.eq(val + 1)

    m.d.rx += buffer.tlp_source.ready.eq(1)

    def store_tlp(start, end, id):
        return [
            val.eq(start),
            end_val.eq(end),
            buffer.store_tlp.eq(1),
            buffer.store_tlp_id.eq(id)
        ]

    sim = Simulator(m)

    sim.add_clock(1E-9, domain="rx")

    def process():
        sm1 = 1
        for i in range(1000):
            if i == 0:
                for statement in store_tlp(5, 8, 0xAB):
                    yield statement
                print("Store 1")

            # This shouldn't overwrite an existing TLP
            if i == 50:
                for statement in store_tlp(9, 17, 0xAB):
                    yield statement
Exemplo n.º 16
0
def test_with_samplerate(samplerate: int=48000):
    """run adat signal simulation with the given samplerate"""
    # 24 bit plus the 6 nibble separator bits for eight channel
    # then 1 separator, 10 sync bits (zero), 1 separator and 4 user bits

    clk_freq = 100e6
    dut = ADATReceiverTester(clk_freq)
    adat_freq = NRZIDecoder.adat_freq(samplerate)
    clockratio = clk_freq / adat_freq

    sim = Simulator(dut)
    sim.add_clock(1.0/clk_freq, domain="sync")
    sim.add_clock(1.0/adat_freq, domain="adat")

    sixteen_adat_frames = sixteen_frames_with_channel_num_msb_and_sample_num()

    testdata = \
        one_empty_adat_frame() + \
        sixteen_adat_frames[0:256] + \
        [0] * 64 + \
        sixteen_adat_frames[256:]

    testdata_nrzi = encode_nrzi(testdata)

    print(f"FPGA clock freq: {clk_freq}")
    print(f"ADAT clock freq: {adat_freq}")
    print(f"FPGA/ADAT freq: {clockratio}")

    no_cycles = len(testdata_nrzi) + 500

    # Send the adat stream
    def adat_process():
        for bit in testdata_nrzi:  # [224:512 * 2]:
            yield dut.adat_in.eq(bit)
            yield Tick("adat")

    # Process the adat stream and validate output
    def sync_process():
        # Obtain the output data
        out_data = [[0 for x in range(9)] for y in range(16)] #store userdata in the 9th column
        sample = 0
        for _ in range(int(clockratio) * no_cycles):
            yield Tick("sync")
            if (yield dut.output_enable == 1):
                channel = yield dut.addr_out

                out_data[sample][channel] = yield dut.sample_out

                if (channel == 7):
                    out_data[sample][8] = yield dut.user_data_out
                    sample += 1

        #print(out_data)


        #
        # The receiver needs 2 sync pads before it starts outputting data:
        #   * The first sync pad is needed for the nrzidecoder to sync
        #   * The second sync pad is needed for the receiver to sync
        #   Therefore each time after the connection was lost the first frame will be lost while syncing.
        # In our testdata we loose the initial one_empty_adat_frame and the second sample (#1, count starts with 0)
        #

        sampleno = 0
        for i in range(16):
            if (sampleno == 1): #skip the first frame while the receiver syncs after an interruption
                sampleno += 1
            elif (sampleno == 16): #ensure the data ended as expected
                assert out_data[i] == [0, 0, 0, 0, 0, 0, 0, 0, 0], "Sample {} was: {}".format(sampleno, print_frame(out_data[sampleno]))
            else:
                assert out_data[i] == [((0 << 20) | sampleno), ((1 << 20) | sampleno), ((2 << 20) | sampleno),
                                       ((3 << 20) | sampleno), ((4 << 20) | sampleno), ((5 << 20) | sampleno),
                                       ((6 << 20) | sampleno), ((7 << 20) | sampleno), 0b0101]\
                    , "Sample #{} was: {}".format(sampleno, print_frame(out_data[sampleno]))
            sampleno += 1

        print("Success!")

    sim.add_sync_process(sync_process, domain="sync")
    sim.add_sync_process(adat_process, domain="adat")
    with sim.write_vcd(f'receiver-smoke-test-{str(samplerate)}.vcd'):
        sim.run()
Exemplo n.º 17
0
assert to_array(0x3E, 8) == [False, True, True, True, True, True, False, False]



if __name__ == "__main__":
    test_bytes = [0x1, 0x23] + [i for i in range(256)] * 4

    test_bytes = test_bytes

    m = Module()
    in_symbol = Signal(8)
    reset_crc = Signal(reset=1)
    m.submodules.crc = crc = LCRC(in_symbol, reset_crc)

    sim = Simulator(m)

    sim.add_clock(1, domain="sync")

    def process():
        for i in range(len(test_bytes) + 2):
            crc_value = ((yield crc.output))
            yield in_symbol.eq(test_bytes[min(i, len(test_bytes) - 1)])
            yield reset_crc.eq(0)
            print(i, hex(crc_value))
            yield

            if i == len(test_bytes) + 1:
                assert crc_value == lcrc(test_bytes)
                print("Test passed! LCRC:", hex(crc_value))
Exemplo n.º 18
0
def create_jtag_simulator(cpu):
    # cursed stuff for retrieving jtag FSM state for 'traces=vcd_traces' variable
    # https://freenode.irclog.whitequark.org/amaranth/2020-07-26#27592720;
    frag = Fragment.get(cpu, platform=None)
    jtag_fsm = frag.find_generated("debug", "jtag", "fsm")
    sim = Simulator(frag)
    sim.add_clock(1e-6)

    jtag_fsm_sig = jtag_fsm.state
    main_clk_sig = sim._fragment.domains["sync"].clk

    jtag_loc = cpu.debug.jtag

    dmcontrol_r = cpu.debug.dmi_regs[DMIReg.DMCONTROL].r.fields.values()
    dmcontrol_w = cpu.debug.dmi_regs[DMIReg.DMCONTROL].w.fields.values()

    hartinfo_r = cpu.debug.dmi_regs[DMIReg.HARTINFO].r.fields.values()
    hartinfo_w = cpu.debug.dmi_regs[DMIReg.HARTINFO].w.fields.values()

    abstracts_r = cpu.debug.dmi_regs[DMIReg.ABSTRACTS].r.fields.values()
    abstracts_w = cpu.debug.dmi_regs[DMIReg.ABSTRACTS].w.fields.values()

    dmstatus_r = cpu.debug.dmi_regs[DMIReg.DMSTATUS].r.fields.values()
    dmstatus_w = cpu.debug.dmi_regs[DMIReg.DMSTATUS].w.fields.values()

    command_w = cpu.debug.dmi_regs[DMIReg.COMMAND].w.fields.values()
    command_r = cpu.debug.dmi_regs[DMIReg.COMMAND].r.fields.values()

    data0_w = cpu.debug.dmi_regs[DMIReg.DATA0].w.fields.values()
    data0_r = cpu.debug.dmi_regs[DMIReg.DATA0].r.fields.values()

    vcd_traces = [
        cpu.debug.dmi_op,
        cpu.debug.dmi_address,
        cpu.debug.dmi_data,
        # jtag_loc.regs[JtagIR.DMI].update,
        # jtag_loc.regs[JtagIR.DMI].capture,
        # jtag_loc.DATA_WRITE,
        # jtag_loc.DATA_READ,
        # jtag_loc.DMI_WRITE,
        cpu.mtime,
        cpu.debug.ONWRITE,
        cpu.debug.ONREAD,
        # cpu.debug.HANDLER,
        cpu.debug.DBG_DMI_ADDR,

        jtag_loc.BAR,
        *data0_r,

        # *dmcontrol_r,
        # jtag_loc.BAR,
        # *dmcontrol_w,
        # jtag_loc.BAR,
        # *dmcontrol_r,
        # jtag_loc.BAR,
        # jtag_loc.regs[JtagIR.DMI].r.op,
        # jtag_loc.BAR,
        # *dmstatus_r,
        # *hartinfo_w,
        jtag_loc.BAR,
        *abstracts_w,
        jtag_loc.BAR,
        *abstracts_r,
        jtag_loc.BAR,
        *command_w,
        jtag_loc.BAR,
        *cpu.debug.command_regs[DMICommand.AccessRegister].fields.values(),
        jtag_loc.BAR,
        *dmstatus_r,
        jtag_loc.BAR,
        *dmcontrol_w,

        cpu.gprf_debug_data,
        cpu.gprf_debug_addr,
        cpu.halt,
    ]
    return {
        "sim": sim,
        "frag": frag,
        "vcd_traces": vcd_traces,
        "jtag_fsm": jtag_fsm,
    }
Exemplo n.º 19
0
            yield sync.rst.eq(1)
            yield
            yield sync.rst.eq(0)
            yield
            assert not (yield cpu.o_trap)

            for _ in range(3):
                yield cpu.i_stall.eq(1)
                yield

            for _ in range(50):
                yield cpu.i_stall.eq(0)
                yield
                assert not (yield cpu.o_trap)

        sim = Simulator(top)
        sim.add_clock(1e-6)
        sim.add_sync_process(bench)
        with sim.write_vcd("cpu.vcd"):
            sim.run()

        # with open("cpu.v", "w") as file:
        #     file.write(verilog.convert(cpu, ports=cpu.ports()))
    else:
        parser = main_parser()
        args = parser.parse_args()
        main_runner(parser,
                    args,
                    top,
                    ports=cpu.ports() + [sync.clk, sync.rst])
Exemplo n.º 20
0
def basic_vm_test():
	cpu = MtkCpu(
		mem_config=EBRMemConfig(
			mem_size_words=0x123,
    		mem_content_words=None, # Optional[List[int]]
    		mem_addr=CODE_START_ADDR,
    		simulate=True,
		)
	)

	def wait_decode() -> int: # returns pc of instr being decoded
		while True:
			is_decode = yield cpu.fetch
			if is_decode:
				return (yield cpu.pc)
			yield

	def wait_pc(target_pc : int, instr_limit: Optional[int]=None):
		import logging
		logging.info(f"== waiting for pc {target_pc}")
		miss = 0
		while True:
			pc = wait_decode()
			logging.info(f"pc: {pc}")
			if pc == target_pc:
				logging(f"pc {target_pc} found")
			else:
				miss += 1
				if miss == instr_limit:
					raise ValueError(f"limit of {instr_limit} instructions exceeded while waiting for {target_pc}")
		
	# TODO test is not finished.
	def main():
		yield cpu.current_priv_mode.eq(PrivModeBits.USER)
		yield cpu.csr_unit.satp.eq(0x8000_0123)
		res = []
		for _ in range (30):
			priv = yield cpu.current_priv_mode
			priv = yield cpu.arbiter.addr_translation_en
			priv = yield cpu.csr_unit.satp.mode
			priv = yield cpu.pc
			res.append(hex(priv))
			yield
		raise ValueError(res)


	sim = Simulator(cpu)
	sim.add_clock(1e-6)
	sim.add_sync_process(main)

	from mtkcpu.utils.tests.sim_tests import get_state_name, find_fsm

	# fsm = find_fsm(cpu.arbiter, "fsm")
	# main_fsm = find_fsm(cpu, "fsm")
	# raise ValueError(fsm)

	traces = [
		sim._fragment.domains["sync"].clk,
		cpu.pc,
		cpu.arbiter.addr_translation_en,
		cpu.arbiter.translation_ack,
		cpu.arbiter.start_translation,
		# fsm.state,
		cpu.arbiter.pe.i,
		cpu.arbiter.pe.o,
		cpu.arbiter.pe.none,
		cpu.csr_unit.satp.mode,
		cpu.csr_unit.satp.ppn,
		cpu.arbiter.first,
		cpu.arbiter.error_code,
		# main_fsm.state
	]

	with sim.write_vcd(f"vm.vcd", "vm.gtkw", traces=traces):
		sim.run()
Exemplo n.º 21
0
def test_with_samplerate(samplerate: int=48000):
    """run adat signal simulation with the given samplerate"""
    # 24 bit plus the 6 nibble separator bits for eight channel
    # then 1 separator, 10 sync bits (zero), 1 separator and 4 user bits

    clk_freq = 100e6
    dut = NRZIDecoderTester(clk_freq)
    adat_freq = NRZIDecoder.adat_freq(samplerate)
    clockratio = clk_freq / adat_freq


    sim = Simulator(dut)
    sim.add_clock(1.0/clk_freq, domain="sync")
    sim.add_clock(1.0/adat_freq, domain="adat")

    print(f"FPGA clock freq: {clk_freq}")
    print(f"ADAT clock freq: {adat_freq}")
    print(f"FPGA/ADAT freq: {clockratio}")

    sixteen_adat_frames = sixteen_frames_with_channel_num_msb_and_sample_num()
    interrupted_adat_stream = [0] * 64

    testdata = one_empty_adat_frame() + \
        sixteen_adat_frames[0:256] + \
        interrupted_adat_stream + \
        sixteen_adat_frames[256:]

    testdata_nrzi = encode_nrzi(testdata)

    no_cycles = len(testdata_nrzi)

    # Send the adat stream
    def adat_process():
        bitcount :int = 0
        for bit in testdata_nrzi: #[224:512 * 2]:
            if (bitcount == 4 * 256 + 64):
                yield dut.invalid_frame_in.eq(1)
                yield Tick("adat")
                yield dut.invalid_frame_in.eq(0)
                for _ in range(20):
                    yield Tick("adat")
            else:
                yield dut.invalid_frame_in.eq(0)

            yield dut.nrzi_in.eq(bit)
            yield Tick("adat")
            bitcount += 1

    # Process the adat stream and validate output
    def sync_process():
        # Obtain the output data
        out_data = []
        for _ in range(int(clockratio) * no_cycles):
            yield Tick("sync")
            if (yield dut.data_out_en == 1):
                bit = yield dut.data_out
                yield out_data.append(bit)

        #
        # Validate output
        #

        # omit a 1 at the end of the sync pad
        out_data = out_data[1:]

        # Whenever the state machine switches from SYNC to DECODE we need to omit the first 11 sync bits
        validate_output(out_data[:256 - 12], one_empty_adat_frame()[12:256])
        out_data = out_data[256-12:]

        validate_output(out_data[:256], sixteen_adat_frames[:256])
        out_data = out_data[256:]

        # now the adat stream was interrupted, it continues to output zeroes, until it enters the SYNC state
        validate_output(out_data[:10], interrupted_adat_stream[:10])
        out_data = out_data[10:]

        # followed by 2 well formed adat frames

        # omit the first 11 sync bits
        validate_output(out_data[:256 - 12], sixteen_adat_frames[256 + 12:2 * 256])
        out_data = out_data[256 - 12:]

        validate_output(out_data[:256], sixteen_adat_frames[2 * 256:3 * 256])
        out_data = out_data[256:]

        # followed by one invalid frame - the state machine SYNCs again

        # followed by 13 well-formed frames

        # omit the first 11 sync bits
        validate_output(out_data[:256 - 12], sixteen_adat_frames[3 * 256 + 12:4 * 256])
        out_data = out_data[256-12:]

        for i in range(4, 16):
            validate_output(out_data[:256], sixteen_adat_frames[i * 256:(i + 1) * 256])
            out_data = out_data[256:]

        print("Success!")


    sim.add_sync_process(sync_process, domain="sync")
    sim.add_sync_process(adat_process, domain="adat")
    with sim.write_vcd(f'nrzi-decoder-bench-{str(samplerate)}.vcd'):
        sim.run()