def sim(cls): """A quick simulation of the transparent latch.""" m = Module() m.submodules.latch = latch = TransparentLatch(32) sim = Simulator(m) def process(): yield latch.n_oe.eq(1) yield latch.le.eq(1) yield Delay(1e-6) yield latch.data_in.eq(0xAAAA1111) yield Delay(1e-6) yield latch.data_in.eq(0x1111AAAA) yield Delay(1e-6) yield latch.le.eq(0) yield Delay(1e-6) yield latch.data_in.eq(0xAAAA1111) yield Delay(1e-6) yield latch.le.eq(1) yield Delay(1e-6) sim.add_process(process) with sim.write_vcd("latch.vcd"): sim.run_until(10e-6)
def fxfilter(self, stimulus): """ Calculate the fixpoint filter response in float format for a frame of stimulus data (float). Parameters ---------- stimulus : ndarray of float One frame of stimuli data (float) scaled as WI.WF Returns ------- output : ndarray of float One frame of response data (float) scaled as WI.WF """ def process(): # convert stimulus to int by multiplying with 2 ^ WF input = np.round(stimulus * (1 << self.fx_filt.p['QI']['WF'])).astype(int) self.output = [] for i in input: yield self.fx_filt.i.eq(int(i)) yield Tick() self.output.append((yield self.fx_filt.o)) sim = Simulator(self.fx_filt) sim.add_clock(1 / 48000) sim.add_process(process) sim.run() # convert output to ndarray of float by dividing the integer response by 2 ^ WF return np.array(self.output, dtype='f') / (1 << self.fx_filt.p['QO']['WF'])
def sim(cls): """A quick simulation of the async memory.""" m = Module() m.submodules.mem = mem = AsyncMemory(width=32, addr_lines=5) sim = Simulator(m) def process(): yield mem.n_oe.eq(0) yield mem.n_wr.eq(1) yield mem.data_in.eq(0xFFFFFFFF) yield Delay(1e-6) yield mem.addr.eq(1) yield mem.n_oe.eq(0) yield Delay(1e-6) yield mem.n_oe.eq(1) yield Delay(1e-6) yield mem.data_in.eq(0xAAAA1111) yield Delay(1e-6) yield mem.n_wr.eq(0) yield Delay(0.2e-6) yield mem.n_wr.eq(1) yield Delay(0.2e-6) yield mem.data_in.eq(0xFFFFFFFF) yield mem.n_oe.eq(0) yield Delay(1e-6) yield mem.addr.eq(0) yield Delay(1e-6) sim.add_process(process) with sim.write_vcd("async_memory.vcd"): sim.run_until(10e-6)
def resolve(expr): """Resolves a nMigen expression that can be constantly evaluated to an integer""" sim = Simulator(Module()) a = [] def testbench(): a.append((yield expr)) sim.add_process(testbench) sim.run() return a[0]
def test_ram_banks(self): sim = Simulator(self.mbc) def proc(): yield from self.reset() yield from self.write(0x4000, 0x1F) assert (yield self.mbc.ram_bank) == 0xF yield from self.write(0x4000, 0x7A) assert (yield self.mbc.ram_bank) == 0xA sim.add_process(proc) sim.reset() sim.run()
def test_ram_en(self): sim = Simulator(self.mbc) def proc(): yield from self.reset() assert (yield self.mbc.ram_en) == 0 yield from self.write(0x0000, 0x0A) assert (yield self.mbc.ram_en) == 1 yield from self.write(0x0000, 0x1A) assert (yield self.mbc.ram_en) == 0 sim.add_process(proc) sim.reset() sim.run()
def gen(): sim = Simulator(m) has_clock = True try: sim.add_clock(1e-6, domain="sync") except ValueError: has_clock = False next_inputs = [0] * len(inputs) next_outputs = [0] * len(outputs) iteration = [0] def input_receiver(): next_input = yield yield next_input def process(): while True: for i in range(len(inputs)): yield inputs[i].eq(next_inputs[i]) if has_clock: yield Tick() for i in range(len(outputs)): next_outputs[i] = (yield outputs[i]) iteration[0] += 1 yield Settle() sim.add_process(process) last_iter = 0 while True: # Receive the input received = yield for i in range(len(received)): next_inputs[i] = received[i] # Iterate until outputs are updated after a clock cycle while last_iter == iteration[0]: sim.advance() last_iter = iteration[0] if len(next_outputs) == 1: yield next_outputs[0] else: yield next_outputs.copy()
def test_rom_banks(self): sim = Simulator(self.mbc) def proc(): yield from self.reset() yield from self.assert_rom_banks(0x000, 0x001) yield from self.write(0x2000, 0x42) yield from self.assert_rom_banks(0x000, 0x042) yield from self.write(0x3000, 0x01) yield from self.assert_rom_banks(0x000, 0x142) yield from self.write(0x2000, 0x00) yield from self.assert_rom_banks(0x000, 0x100) yield from self.write(0x3000, 0x00) yield from self.assert_rom_banks(0x000, 0x000) sim.add_process(proc) sim.reset() sim.run()
def check(self, instruction: int, expected: Dict[str, int]): decoder = CPUDecoder() sim = Simulator(decoder) def input_process(): yield decoder.instruction_in.eq(instruction) def check_process(): yield Delay(1e-6) for k, expected_value in expected.items(): value = yield getattr(decoder, k) if isinstance(expected_value, enum.Enum): value = expected_value.__class__(value) else: value = hex(value) expected_value = hex(expected_value) with self.subTest(f"decoder.{k}"): self.assertEqual(value, expected_value) with sim.write_vcd(f"test_decode_{hex(instruction)}.vcd"): sim.add_process(input_process) sim.add_process(check_process) sim.run()
def assertStatement(self, stmt, inputs, output, reset=0): inputs = [Value.cast(i) for i in inputs] output = Value.cast(output) isigs = [Signal(i.shape(), name=n) for i, n in zip(inputs, "abcd")] osig = Signal(output.shape(), name="y", reset=reset) stmt = stmt(osig, *isigs) frag = Fragment() frag.add_statements(stmt) for signal in flatten(s._lhs_signals() for s in Statement.cast(stmt)): frag.add_driver(signal) 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]): sim.run()
def test_base_rate_sync(): from nmigen.sim import Simulator, Delay clock_sclk = 1.544e6 clock_sync = 16.384e6 m = Module() m.submodules.dut = dut = BaseRateSync() sclk = Signal() serclk = Signal() ser = Signal() SERCLK_SKEW = 10e-9 SER_SKEW = 10e-9 def process_framer(): frequency = clock_sclk period = 1.0 / frequency data = 'THIS_IS_A_TEST_' * 40 data_bits = ''.join(['{:08b}'.format(ord(v)) for v in data]) for bit in data_bits: yield sclk.eq(1) yield Delay(SERCLK_SKEW) yield serclk.eq(1) yield Delay(SER_SKEW) yield ser.eq(int(bit)) yield Delay(period * 0.5 - SERCLK_SKEW - SER_SKEW) yield sclk.eq(0) yield Delay(SERCLK_SKEW) yield serclk.eq(0) yield Delay(period * 0.5 - SERCLK_SKEW) def process_strobe(): last = 0 for _ in range(int(round(4700 * clock_sync / clock_sclk))): serclk_value = yield serclk if serclk_value == 0 and last == 1: yield dut.strobe_in.eq(1) else: yield dut.strobe_in.eq(0) last = serclk_value yield def process_test(): yield Delay(100e-9) for _ in range(4700): yield sim = Simulator(m) sim.add_clock(1.0 / clock_sync) sim.add_process(process_framer) sim.add_sync_process(process_strobe) sim.add_sync_process(process_test) traces = [ sclk, serclk, ser, ] with sim.write_vcd("test_base_rate_sync.vcd", "test_base_rate_sync.gtkw", traces=traces): sim.run()
# with m.If(self.enable): m.d.sync += phase_acc.eq(phase_acc + self.phase_step) return m @staticmethod def calculate_phase_step(clk_frequency: float, frequency: float): return int(round((2 ** 32) * frequency / clk_frequency)) if __name__ == "__main__": # from nmigen_boards.tinyfpga_bx import TinyFPGABXPlatform # platform = TinyFPGABXPlatform() # products = platform.build(Top(), do_program=True) from nmigen.sim import Simulator, Tick dut = NCO(width=8, samples=1024) sim = Simulator(dut) sim.add_clock(1 / 1e6) def proc(): yield dut.phase_step.eq(NCO.calculate_phase_step(clk_frequency=1e6, frequency=440)) for i in range(3000): yield Tick() sim.add_process(proc) with sim.write_vcd("dds.vcd"): sim.run()