Skip to content

Instantly share code, notes, and snippets.

@adamgreig
Last active October 23, 2017 05:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamgreig/b4d6711cbd8bbd3e881c07b0d16f5841 to your computer and use it in GitHub Desktop.
Save adamgreig/b4d6711cbd8bbd3e881c07b0d16f5841 to your computer and use it in GitHub Desktop.
migen lfsr on de0-nano
from migen import Module, Signal, ClockDomain, Instance
from migen.build.platforms import de0nano
# Load the DE0-Nano platform and request resources
plat = de0nano.Platform()
led = plat.request("user_led")
pins = plat.request("gpio_0")
clk50 = plat.request("clk50")
class PLL(Module):
"""Helper for instantiating onboard PLLs"""
def __init__(self, period_in, name, phase_shift, operation_mode):
self.clk_in = Signal()
self.clk_out = Signal()
self.specials += Instance("ALTPLL",
p_bandwidth_type="AUTO",
p_clk0_divide_by=1,
p_clk0_duty_cycle=50,
p_clk0_multiply_by=8,
p_clk0_phase_shift="{}".format(
str(phase_shift)),
p_compensate_clock="CLK0",
p_inclk0_input_frequency=int(period_in*1000),
p_intended_device_family="Cyclone IV E",
p_lpm_hint="CBX_MODULE_PREFIX={}_pll"
.format(name),
p_lpm_type="altpll",
p_operation_mode=operation_mode,
i_inclk=self.clk_in,
o_clk=self.clk_out,
i_areset=0,
i_clkena=0x3f,
i_clkswitch=0,
i_configupdate=0,
i_extclkena=0xf,
i_fbin=1,
i_pfdena=1,
i_phasecounterselect=0xf,
i_phasestep=1,
i_phaseupdown=1,
i_pllena=1,
i_scanaclr=0,
i_scanclk=0,
i_scanclkena=1,
i_scandata=0,
i_scanread=0,
i_scanwrite=0)
class CRG(Module):
"""Manual clock and reset generator, so that we can use the PLL
and our custom clock domains.
"""
def __init__(self, clk50):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_por = ClockDomain(reset_less=True)
sys_pll = PLL(20, "sys", 0, "NORMAL")
self.submodules += sys_pll
self.comb += [
sys_pll.clk_in.eq(clk50),
self.cd_sys.clk.eq(sys_pll.clk_out)
]
# Power on Reset (vendor agnostic)
rst_n = Signal()
self.sync.por += rst_n.eq(1)
self.comb += [
self.cd_por.clk.eq(self.cd_sys.clk),
self.cd_sys.rst.eq(~rst_n),
]
# Make our LFSR module with our custom clocking and reset
m = Module()
m.submodules.crg = CRG(clk50)
# Set up an LFSR clock domain running off a divider
counter = Signal(26)
m.sync += counter.eq(counter + 1)
lfsrclk = counter[1]
m.clock_domains.lfsr = ClockDomain("lfsr", reset_less=True)
m.comb += m.lfsr.clk.eq(lfsrclk)
# The LFSR register itself
lfsr = Signal(16, reset=1)
m.sync.lfsr += [lfsr[x].eq(lfsr[x+1]) for x in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)]
m.sync.lfsr += lfsr[10].eq(lfsr[11] ^ lfsr[0])
m.sync.lfsr += lfsr[11].eq(lfsr[12])
m.sync.lfsr += lfsr[12].eq(lfsr[13] ^ lfsr[0])
m.sync.lfsr += lfsr[13].eq(lfsr[14] ^ lfsr[0])
m.sync.lfsr += lfsr[14].eq(lfsr[15])
m.sync.lfsr += lfsr[15].eq(lfsr[0])
# Output the LFSR register to the GPIO
m.comb += [pins[idx].eq(lfsr[idx]) for idx in range(16)]
# Output the LFSR output bit and clock
m.comb += pins[23].eq(lfsr[0])
m.comb += pins[22].eq(lfsrclk)
# Blink LED off the divider to show activity
m.comb += led.eq(counter[25])
# Build this module and then program it onto the FPGA
plat.build(m)
prog = plat.create_programmer()
prog.load_bitstream("build/top.sof")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment