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()
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)
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
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)
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)
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)
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)
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()
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()
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()
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()
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()
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()
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
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)
# 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()