def __init__(self, *, bits=32, spi_pins=None, **kwargs): self._bits = bits self._spi_pins = spi_pins self.jtag = Record(_wire_layout()) self.cs_n = Pin(1, "oe") self.clk = Pin(1, "oe") self.mosi = Pin(1, "oe") self.miso = Pin(1, "i") # self.cs_n.o.reset = 1 self.mosi.o.reset_less = True self.jtag_sel1_capture = Signal( ) # JTAG chain 1 is selected & in Capture-DR state? self.jtag_sel1_shift = Signal( ) # JTAG chain 1 is selected & in Shift-DR state? # For JTAGF/JTAGG if set(kwargs).intersection(["jtagf", "jtagg"]): if kwargs.get("jtagf"): self._jtagf = True elif kwargs.get("jtagg"): self._jtagg = True else: raise KeyError("Can't use JTAGF and JTAGG at the same time")
def __init__(self): self.rx_t = Pin(width=1, dir='i') self.rx_i = self.rx_t.i self.tx_t = Pin(width=1, dir='oe') self.tx_o = self.tx_t.o self.bit_cyc = 4 self.dut = UART(pads=self, bit_cyc=self.bit_cyc)
def test_phy_manager(): from nmigen.back import pysim from nmigen.lib.io import Pin mdc = Signal() mdio = Pin(1, 'io') phy_rst = Signal() # Specify a fake 10MHz clock frequency to reduce number of simulation steps phy_manager = PHYManager(10e6, 0, phy_rst, mdio, mdc) def testbench(): # 1ms is 10000 ticks, so check we're still asserting phy_rst for _ in range(10000): assert (yield phy_rst) == 0 yield assert (yield phy_manager.link_up) == 0 # Allow enough clocks to step the state machine through for _ in range(100): yield # Now we wait another 1ms for bring-up, without asserting reset for _ in range(9900): assert (yield phy_rst) == 1 yield assert (yield phy_manager.link_up) == 0 # Wait for the register read to synchronise to MDIO while True: if (yield phy_manager.mdio_mod.mdio.o) == 1: break yield # Clock through BSR register read, setting bits 14, 5, 2 for clk in range(260): if clk in (194, 230, 242): yield (phy_manager.mdio_mod.mdio.i.eq(1)) else: yield (phy_manager.mdio_mod.mdio.i.eq(0)) yield # Finish register reads for _ in range(100): yield # Check link_up becomes 1 assert (yield phy_manager.link_up) == 1 vcdf = open("phy_manager.vcd", "w") with pysim.Simulator(phy_manager, vcd_file=vcdf) as sim: sim.add_clock(1e-6) sim.add_sync_process(testbench()) sim.run()
def __init__(self, tone_frequency=440, clk_frequency=50000000, resolution = 8, pwm_resolution=None): self.pwm_o = Pin(1, "o") self.phi_inc = calc_phi_inc(tone_frequency, clk_frequency) self.resolution = resolution if pwm_resolution==None: self.pwm_resolution = resolution else: self.pwm_resolution = pwm_resolution
def __init__(self, tone_frequency=440, clk_frequency=100000000, count_resolution=8, audio_resolution=None): self.pwm_o = Pin(1, "o") self.phi_inc = calc_phi_inc(tone_frequency, clk_frequency) self.phi_inc_2 = calc_phi_inc(tone_frequency / 2, clk_frequency) self.count_resolution = count_resolution if audio_resolution == None: self.audio_resolution = count_resolution else: self.audio_resolution = audio_resolution
def test_mdio_write(): import random from nmigen.lib.io import Pin from nmigen.back import pysim mdc = Signal() mdio_pin = Pin(1, 'io') mdio = MDIO(20, mdio_pin, mdc) def testbench(): rng = random.Random(0) # Run ten random writes in sequence for testrun in range(10): phy_addr = rng.randint(0, 31) reg_addr = rng.randint(0, 31) reg_value = rng.randint(0, 65535) # Idle clocks at start for _ in range(10): yield # Set up a register write yield (mdio.phy_addr.eq(phy_addr)) yield (mdio.reg_addr.eq(reg_addr)) yield (mdio.write_data.eq(reg_value)) yield (mdio.rw.eq(1)) yield (mdio.start.eq(1)) yield yield (mdio.phy_addr.eq(0)) yield (mdio.write_data.eq(0)) yield (mdio.rw.eq(0)) yield (mdio.reg_addr.eq(0)) yield (mdio.start.eq(0)) # Clock through the write obits = [] oebits = [] mdio_clk = 0 last_mdc = (yield mdc) while True: yield new_mdc = (yield mdc) # Detect rising edge if new_mdc and last_mdc == 0: mdio_clk += 1 obits.append((yield mdio.mdio.o)) oebits.append((yield mdio.mdio.oe)) if mdio_clk == 64: break last_mdc = new_mdc # Idle at end for _ in range(100): yield was_busy = (yield mdio.busy) # Check transmitted bits were correct pre_32 = [1] * 32 st = [0, 1] op = [0, 1] pa5 = [int(x) for x in f"{phy_addr:05b}"] ra5 = [int(x) for x in f"{reg_addr:05b}"] ta = [1, 0] d16 = [int(x) for x in f"{reg_value:016b}"] expected = pre_32 + st + op + pa5 + ra5 + ta + d16 assert obits == expected # Check OE transitioned correctly expected = [1] * 64 assert oebits == expected assert not was_busy vcdf = open("mdio_write.vcd", "w") with pysim.Simulator(mdio, vcd_file=vcdf) as sim: sim.add_clock(1e-6) sim.add_sync_process(testbench()) sim.run()
def test_mdio_read(): import random from nmigen.lib.io import Pin from nmigen.back import pysim mdc = Signal() mdio_pin = Pin(1, 'io') mdio = MDIO(20, mdio_pin, mdc) def testbench(): rng = random.Random(0) # Run ten random reads in sequence for testrun in range(10): phy_addr = rng.randint(0, 31) reg_addr = rng.randint(0, 31) reg_value = rng.randint(0, 65535) # Idle clocks at start for _ in range(10): yield # Set up a register read yield (mdio.phy_addr.eq(phy_addr)) yield (mdio.reg_addr.eq(reg_addr)) yield (mdio.rw.eq(0)) yield (mdio.start.eq(1)) yield yield (mdio.phy_addr.eq(0)) yield (mdio.reg_addr.eq(0)) yield (mdio.start.eq(0)) # Clock through the read ibits = [int(x) for x in f"{reg_value:016b}"] obits = [] oebits = [] mdio_clk = 0 last_mdc = (yield mdc) while True: yield new_mdc = (yield mdc) # Detect rising edge if new_mdc and last_mdc == 0: mdio_clk += 1 obits.append((yield mdio.mdio.o)) oebits.append((yield mdio.mdio.oe)) if mdio_clk >= 48: yield (mdio.mdio.i.eq(ibits[mdio_clk - 48])) if mdio_clk == 63: break last_mdc = new_mdc for _ in range(100): yield read_data = (yield mdio.read_data) was_busy = (yield mdio.busy) # Check transmitted bits were correct pre_32 = [1] * 32 st = [0, 1] op = [1, 0] pa5 = [int(x) for x in f"{phy_addr:05b}"] ra5 = [int(x) for x in f"{reg_addr:05b}"] expected = pre_32 + st + op + pa5 + ra5 assert obits[:46] == expected # Check OE transitioned correctly expected = [1] * 46 + [0] * 17 assert oebits == expected # Check we read the correct value in the end expected = int("".join(str(x) for x in ibits), 2) assert read_data == expected assert not was_busy vcdf = open("mdio_read.vcd", "w") with pysim.Simulator(mdio, vcd_file=vcdf) as sim: sim.add_clock(1e-6) sim.add_sync_process(testbench()) sim.run()