Skip to content

Instantly share code, notes, and snippets.

@cr1901
Created March 23, 2016 16:35
Show Gist options
  • Save cr1901/36405a8e44111a6efbef to your computer and use it in GitHub Desktop.
Save cr1901/36405a8e44111a6efbef to your computer and use it in GitHub Desktop.
MiSoC Frequency Counter
from migen.fhdl.std import *
from migen.genlib.fifo import AsyncFIFO
from migen.fhdl.bitcontainer import flen
from migen.bank.description import *
class FreqCounterDebug(Module, AutoCSR):
def __init__(self, counter_param_list):
for params in counter_param_list:
setattr(self.submodules, params[0], FreqCounter(*params[1:]))
class FreqCounter(Module, AutoCSR):
# 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.
# self.freq_out is the last measured frequency over the interval.
# 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, 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)
self.freq_out = CSRStatus(32)
self.freq_cnt = CSRStatus(32)
self.gate_cnt = CSRStatus(32)
self.comb += [self.freq_cnt.status.eq(freq_count)]
self.comb += [self.gate_cnt.status.eq(gate_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.sync.ref_clk += [If(gate_count == gate_time - 1,
gate_count.eq(0),
freq_count.eq(0),
self.freq_out.status.eq(freq_count)).
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)),
gate_count.eq(gate_count + 1))]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment