111 lines
2.6 KiB
Python
111 lines
2.6 KiB
Python
from migen.fhdl.structure import *
|
|
from migen.fhdl.module import Module
|
|
|
|
class RisingEdge(Module):
|
|
def __init__(self, i=None, o=None, domain="sys"):
|
|
self.i = ifthenelse(i, i, Signal())
|
|
self.o = ifthenelse(o, o, Signal())
|
|
####
|
|
i_d = Signal()
|
|
sync =[i_d.eq(self.i)]
|
|
self.comb +=[self.o.eq(self.i & ~i_d)]
|
|
self._fragment += Fragment(sync={domain : sync})
|
|
|
|
class FallingEdge(Module):
|
|
def __init__(self, i=None, o=None, domain="sys"):
|
|
self.i = ifthenelse(i, i, Signal())
|
|
self.o = ifthenelse(o, o, Signal())
|
|
####
|
|
i_d = Signal()
|
|
sync =[i_d.eq(self.i)]
|
|
self.comb +=[self.o.eq(~self.i & i_d)]
|
|
self._fragment += Fragment(sync={domain : sync})
|
|
|
|
class FreqGen(Module):
|
|
def __init__(self, clk_freq, freq, o=None):
|
|
cnt_max = int(clk_freq/freq/2)
|
|
width = bits_for(cnt_max)
|
|
|
|
self.o = ifthenelse(o, o, Signal())
|
|
####
|
|
cnt = Signal(width)
|
|
self.sync += [
|
|
If(cnt >= cnt_max,
|
|
cnt.eq(0),
|
|
self.o.eq(~self.o)
|
|
).Else(
|
|
cnt.eq(cnt+1)
|
|
)
|
|
]
|
|
|
|
RISING_EDGE = 1
|
|
FALLING_EDGE = 0
|
|
|
|
class EventGen(Module):
|
|
def __init__(self, i=None, level=1, clk_freq=0, length=1, o=None):
|
|
|
|
cnt_max = int(length*clk_freq)
|
|
width = bits_for(cnt_max)
|
|
|
|
self.i = ifthenelse(i, i, Signal())
|
|
self.o = ifthenelse(o, o, Signal())
|
|
###
|
|
cnt = Signal(width)
|
|
i_edge = Signal()
|
|
|
|
if level == RISING_EDGE:
|
|
self.submodules += RisingEdge(self.i, i_edge)
|
|
elif level == FALLING_EDGE:
|
|
self.submodules += FallingEdge(self.i, i_edge)
|
|
|
|
self.sync += [
|
|
If(i_edge == 1,
|
|
cnt.eq(0),
|
|
self.o.eq(1)
|
|
).Elif(cnt >= cnt_max,
|
|
self.o.eq(0)
|
|
).Else(
|
|
cnt.eq(cnt+1)
|
|
),
|
|
]
|
|
|
|
class PwmGen(Module):
|
|
def __init__(self, width, o=None):
|
|
self.ratio = Signal(width)
|
|
self.o = ifthenelse(o, o, Signal())
|
|
###
|
|
cnt = Signal(width)
|
|
self.sync += [
|
|
If(cnt == 0,
|
|
self.o.eq(1)
|
|
).Elif(cnt >= self.ratio,
|
|
self.o.eq(0)
|
|
),
|
|
cnt.eq(cnt+1)
|
|
]
|
|
|
|
class Cascade(Module):
|
|
def __init__(self, i=None, elements=None, o=None):
|
|
self.i = ifthenelse(i, i, Signal())
|
|
self.o = ifthenelse(o, o, Signal())
|
|
self.comb +=[elements[0].i.eq(self.i)]
|
|
self.comb +=[elements[i+1].i.eq(elements[i].o) for i in range(len(elements)-1)]
|
|
self.comb +=[self.o.eq(elements[len(elements)-1].o)]
|
|
|
|
class PwrOnRst(Module):
|
|
def __init__(self, width, rst=None, simulation=False):
|
|
self.rst = ifthenelse(rst, rst, Signal())
|
|
###
|
|
cnt = Signal(width)
|
|
sync_no_reset = [If(self.rst, cnt.eq(cnt+1))]
|
|
if not simulation:
|
|
self.comb +=[
|
|
If(cnt >= (2**width-1),
|
|
self.rst.eq(0)
|
|
).Else(
|
|
self.rst.eq(1)
|
|
)
|
|
]
|
|
else:
|
|
self.comb += self.rst.eq(0)
|
|
self._fragment += Fragment(sync={"sys_no_reset" : sync_no_reset}) |