2022-10-31 15:39:16 +01:00

72 lines
3.3 KiB
Python

from migen import *
from migen.genlib.fifo import *
import litex
from litex.soc.interconnect import wishbone
from migen.genlib.cdc import BusSynchronizer
class WishboneDomainCrossingMaster(Module, wishbone.Interface):
"""Wishbone Clock Domain Crossing [Master]"""
def __init__(self, platform, slave, cd_master="sys", cd_slave="sys", force_delay = 0):
# Same Clock Domain, direct connection.
wishbone.Interface.__init__(self, data_width=slave.data_width, adr_width=slave.adr_width)
if cd_master == cd_slave:
raise NameError("Don't use domain crossing for the same domains.")
# Clock Domain Crossing.
else:
self.add_sources(platform)
delay_stb = Signal()
if (force_delay == 0):
self.comb += [ delay_stb.eq(self.stb), ]
else:
counter = Signal(max=force_delay+1)
last_stb = Signal()
master_sync = getattr(self.sync, cd_master)
master_sync += [
If(counter != 0,
counter.eq(counter - 1),
),
last_stb.eq(self.stb),
If(~self.stb & last_stb, # falling edge, force timeout
counter.eq(force_delay),
),
]
self.comb += [ delay_stb.eq(self.stb & (counter == 0)) ]
#fixme: parameters
self.specials += Instance(self.get_netlist_name(),
# master side
i_wbm_clk = ClockSignal(cd_master),
i_wbm_rst = ResetSignal(cd_master),
i_wbm_adr_i = self.adr,
i_wbm_dat_i = self.dat_w,
o_wbm_dat_o = self.dat_r,
i_wbm_we_i = self.we,
i_wbm_sel_i = self.sel,
i_wbm_stb_i = delay_stb,
o_wbm_ack_o = self.ack,
o_wbm_err_o = self.err,
o_wbm_rty_o = Signal(),
i_wbm_cyc_i = self.cyc,
# slave side
i_wbs_clk = ClockSignal(cd_slave),
i_wbs_rst = ResetSignal(cd_slave),
o_wbs_adr_o = slave.adr,
o_wbs_dat_o = slave.dat_w,
i_wbs_dat_i = slave.dat_r,
o_wbs_we_o = slave.we,
o_wbs_sel_o = slave.sel,
o_wbs_stb_o = slave.stb,
i_wbs_ack_i = slave.ack,
i_wbs_err_i = slave.err,
i_wbs_rty_i = Signal(),
o_wbs_cyc_o = slave.cyc)
def get_netlist_name(self):
return "wb_async_reg"
def add_sources(self, platform):
platform.add_source("VintageBusFPGA_Common/wb_async_reg.v", "verilog")