Skip to content

Instantly share code, notes, and snippets.

@cr1901
Last active January 27, 2016 08:49
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 cr1901/7dd73f989bada9c01c27 to your computer and use it in GitHub Desktop.
Save cr1901/7dd73f989bada9c01c27 to your computer and use it in GitHub Desktop.
Migen Frequency Counter
from migen.fhdl.std import *
from migen.genlib.fifo import AsyncFIFO
from migen.fhdl.bitcontainer import flen
from migen.fhdl import verilog
class FreqCounter(Module):
# measured_sig: Signal to measure frequency
# ref_clk: counts up to a gate_time number of cycles. It should be at least
# twice as fast as the maximum frequency of the measured signal to avoid
# samples being missed.
# storage: should be an already instantiated (a)synchronous FIFO. The ref clock
# and clock used to write to the FIFO must be the same clock!
# posedge: If true, edge transitions from low to high count as a frequency event.
# Otherwise, high to low transitions count.
def __init__(self, measured_sig, ref_clk, storage, gate_time=50000000, posedge=True):
self.clock_domains.cd_ref_clk = ClockDomain()
self.comb += [self.cd_ref_clk.clk.eq(ref_clk)]
event = Signal(1)
prev_sig = Signal(1)
gate_count = Signal(max=gate_time)
freq_count = Signal(max=gate_time)
storage_strobe = Signal(1)
self.comb += [storage.din.eq(freq_count)]
self.sync.ref_clk += [prev_sig.eq(measured_sig)]
if posedge:
self.comb += [event.eq(measured_sig & ~prev_sig)]
else:
self.comb += [event.eq(~measured_sig & prev_sig)]
# We will latch data into the queue on the leading edge of the next
# clock if gate_count has saturated.
self.comb += [storage.re.eq(gate_count == gate_time - 1)]
self.sync.ref_clk += [storage.re.eq(0),
If(gate_count == gate_time - 1,
gate_count.eq(0),
freq_count.eq(0)).
Else(
# TODO: We should probably count an edge transition detected
# on the leading edge just before the gate_count resets.
If(event,
freq_count.eq(freq_count + 1))
)]
class TestModule(Module):
def __init__(self, width=flen(50000000), num_samples=16):
self.measured_sig = Signal(1)
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_ref = ClockDomain(reset_less=True)
# self.submodules.storage = AsyncFIFO(width, num_samples)
self.submodules.storage = ClockDomainsRenamer({"read" : "sys", \
"write" : "ref"})(AsyncFIFO(width, num_samples))
self.submodules.freq_counter = FreqCounter(self.measured_sig, \
self.cd_ref.clk, self.storage)
m = TestModule()
with open("freq_count.v", "w") as fp:
fp.write(str(verilog.convert(m, ios={m.cd_sys.clk, \
m.cd_sys.rst, m.cd_ref.clk, m.measured_sig})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment