diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..882cd80 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sbus-to-ztex-gateware-migen/VintageBusFPGA_Common"] + path = sbus-to-ztex-gateware-migen/VintageBusFPGA_Common + url = git@github.com:rdolbeau/VintageBusFPGA_Common.git diff --git a/sbus-to-ztex-gateware-migen/VintageBusFPGA_Common b/sbus-to-ztex-gateware-migen/VintageBusFPGA_Common new file mode 160000 index 0000000..535024e --- /dev/null +++ b/sbus-to-ztex-gateware-migen/VintageBusFPGA_Common @@ -0,0 +1 @@ +Subproject commit 535024e8857308f8830ebc2af39cddf716a7c3f7 diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py index c67c3cc..32eb4fc 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py @@ -42,7 +42,7 @@ import goblin_fb import goblin_accel # Wishbone stuff -from sbus_wb import WishboneDomainCrossingMaster +from VintageBusFPGA_Common.cdc_wb import WishboneDomainCrossingMaster # CRG ---------------------------------------------------------------------------------------------- diff --git a/sbus-to-ztex-gateware-migen/sbus_wb.py b/sbus-to-ztex-gateware-migen/sbus_wb.py deleted file mode 100644 index 77b8e1c..0000000 --- a/sbus-to-ztex-gateware-migen/sbus_wb.py +++ /dev/null @@ -1,71 +0,0 @@ -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("/home/dolbeau/SBusFPGA/sbus-to-ztex-gateware-migen/wb_async_reg.v", "verilog") diff --git a/sbus-to-ztex-gateware-migen/wb_async_reg.v b/sbus-to-ztex-gateware-migen/wb_async_reg.v deleted file mode 100644 index 8a888b6..0000000 --- a/sbus-to-ztex-gateware-migen/wb_async_reg.v +++ /dev/null @@ -1,225 +0,0 @@ -/* - -Copyright (c) 2015-2016 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Wishbone register - */ -module wb_async_reg # -( - parameter DATA_WIDTH = 32, // width of data bus in bits (8, 16, 32, or 64) - parameter ADDR_WIDTH = 30, // width of address bus in bits - parameter SELECT_WIDTH = (DATA_WIDTH/8) // width of word select bus (1, 2, 4, or 8) -) -( - // master side - input wire wbm_clk, - input wire wbm_rst, - input wire [ADDR_WIDTH-1:0] wbm_adr_i, // ADR_I() address - input wire [DATA_WIDTH-1:0] wbm_dat_i, // DAT_I() data in - output wire [DATA_WIDTH-1:0] wbm_dat_o, // DAT_O() data out - input wire wbm_we_i, // WE_I write enable input - input wire [SELECT_WIDTH-1:0] wbm_sel_i, // SEL_I() select input - input wire wbm_stb_i, // STB_I strobe input - output wire wbm_ack_o, // ACK_O acknowledge output - output wire wbm_err_o, // ERR_O error output - output wire wbm_rty_o, // RTY_O retry output - input wire wbm_cyc_i, // CYC_I cycle input - - // slave side - input wire wbs_clk, - input wire wbs_rst, - output wire [ADDR_WIDTH-1:0] wbs_adr_o, // ADR_O() address - input wire [DATA_WIDTH-1:0] wbs_dat_i, // DAT_I() data in - output wire [DATA_WIDTH-1:0] wbs_dat_o, // DAT_O() data out - output wire wbs_we_o, // WE_O write enable output - output wire [SELECT_WIDTH-1:0] wbs_sel_o, // SEL_O() select output - output wire wbs_stb_o, // STB_O strobe output - input wire wbs_ack_i, // ACK_I acknowledge input - input wire wbs_err_i, // ERR_I error input - input wire wbs_rty_i, // RTY_I retry input - output wire wbs_cyc_o // CYC_O cycle output -); - -reg [ADDR_WIDTH-1:0] wbm_adr_i_reg = 0; -reg [DATA_WIDTH-1:0] wbm_dat_i_reg = 0; -reg [DATA_WIDTH-1:0] wbm_dat_o_reg = 0; -reg wbm_we_i_reg = 0; -reg [SELECT_WIDTH-1:0] wbm_sel_i_reg = 0; -reg wbm_stb_i_reg = 0; -reg wbm_ack_o_reg = 0; -reg wbm_err_o_reg = 0; -reg wbm_rty_o_reg = 0; -reg wbm_cyc_i_reg = 0; - -reg wbm_done_sync1 = 0; -reg wbm_done_sync2 = 0; -reg wbm_done_sync3 = 0; - -reg [ADDR_WIDTH-1:0] wbs_adr_o_reg = 0; -reg [DATA_WIDTH-1:0] wbs_dat_i_reg = 0; -reg [DATA_WIDTH-1:0] wbs_dat_o_reg = 0; -reg wbs_we_o_reg = 0; -reg [SELECT_WIDTH-1:0] wbs_sel_o_reg = 0; -reg wbs_stb_o_reg = 0; -reg wbs_ack_i_reg = 0; -reg wbs_err_i_reg = 0; -reg wbs_rty_i_reg = 0; -reg wbs_cyc_o_reg = 0; - -reg wbs_cyc_o_sync1 = 0; -reg wbs_cyc_o_sync2 = 0; -reg wbs_cyc_o_sync3 = 0; - -reg wbs_stb_o_sync1 = 0; -reg wbs_stb_o_sync2 = 0; -reg wbs_stb_o_sync3 = 0; - -reg wbs_done_reg = 0; - -assign wbm_dat_o = wbm_dat_o_reg; -assign wbm_ack_o = wbm_ack_o_reg; -assign wbm_err_o = wbm_err_o_reg; -assign wbm_rty_o = wbm_rty_o_reg; - -assign wbs_adr_o = wbs_adr_o_reg; -assign wbs_dat_o = wbs_dat_o_reg; -assign wbs_we_o = wbs_we_o_reg; -assign wbs_sel_o = wbs_sel_o_reg; -assign wbs_stb_o = wbs_stb_o_reg; -assign wbs_cyc_o = wbs_cyc_o_reg; - -// master side logic -always @(posedge wbm_clk) begin - if (wbm_rst) begin - wbm_adr_i_reg <= 0; - wbm_dat_i_reg <= 0; - wbm_dat_o_reg <= 0; - wbm_we_i_reg <= 0; - wbm_sel_i_reg <= 0; - wbm_stb_i_reg <= 0; - wbm_ack_o_reg <= 0; - wbm_err_o_reg <= 0; - wbm_rty_o_reg <= 0; - wbm_cyc_i_reg <= 0; - end else begin - if (wbm_cyc_i_reg & wbm_stb_i_reg) begin - // cycle - hold master - if (wbm_done_sync2 & ~wbm_done_sync3) begin - // end of cycle - store slave - wbm_dat_o_reg <= wbs_dat_i_reg; - wbm_ack_o_reg <= wbs_ack_i_reg; - wbm_err_o_reg <= wbs_err_i_reg; - wbm_rty_o_reg <= wbs_rty_i_reg; - wbm_we_i_reg <= 0; - wbm_stb_i_reg <= 0; - end - end else begin - // idle - store master - wbm_adr_i_reg <= wbm_adr_i; - wbm_dat_i_reg <= wbm_dat_i; - wbm_dat_o_reg <= 0; - wbm_we_i_reg <= wbm_we_i & ~(wbm_ack_o | wbm_err_o | wbm_rty_o); - wbm_sel_i_reg <= wbm_sel_i; - wbm_stb_i_reg <= wbm_stb_i & ~(wbm_ack_o | wbm_err_o | wbm_rty_o); - wbm_ack_o_reg <= 0; - wbm_err_o_reg <= 0; - wbm_rty_o_reg <= 0; - wbm_cyc_i_reg <= wbm_cyc_i; - end - end - - // synchronize signals - wbm_done_sync1 <= wbs_done_reg; - wbm_done_sync2 <= wbm_done_sync1; - wbm_done_sync3 <= wbm_done_sync2; -end - -// slave side logic -always @(posedge wbs_clk) begin - if (wbs_rst) begin - wbs_adr_o_reg <= 0; - wbs_dat_i_reg <= 0; - wbs_dat_o_reg <= 0; - wbs_we_o_reg <= 0; - wbs_sel_o_reg <= 0; - wbs_stb_o_reg <= 0; - wbs_ack_i_reg <= 0; - wbs_err_i_reg <= 0; - wbs_rty_i_reg <= 0; - wbs_cyc_o_reg <= 0; - wbs_done_reg <= 0; - end else begin - if (wbs_ack_i | wbs_err_i | wbs_rty_i) begin - // end of cycle - store slave - wbs_dat_i_reg <= wbs_dat_i; - wbs_ack_i_reg <= wbs_ack_i; - wbs_err_i_reg <= wbs_err_i; - wbs_rty_i_reg <= wbs_rty_i; - wbs_we_o_reg <= 0; - wbs_stb_o_reg <= 0; - wbs_done_reg <= 1; - end else if (wbs_stb_o_sync2 & ~wbs_stb_o_sync3) begin - // beginning of cycle - store master - wbs_adr_o_reg <= wbm_adr_i_reg; - wbs_dat_i_reg <= 0; - wbs_dat_o_reg <= wbm_dat_i_reg; - wbs_we_o_reg <= wbm_we_i_reg; - wbs_sel_o_reg <= wbm_sel_i_reg; - wbs_stb_o_reg <= wbm_stb_i_reg; - wbs_ack_i_reg <= 0; - wbs_err_i_reg <= 0; - wbs_rty_i_reg <= 0; - wbs_cyc_o_reg <= wbm_cyc_i_reg; - wbs_done_reg <= 0; - end else if (~wbs_cyc_o_sync2 & wbs_cyc_o_sync3) begin - // cyc deassert - wbs_adr_o_reg <= 0; - wbs_dat_i_reg <= 0; - wbs_dat_o_reg <= 0; - wbs_we_o_reg <= 0; - wbs_sel_o_reg <= 0; - wbs_stb_o_reg <= 0; - wbs_ack_i_reg <= 0; - wbs_err_i_reg <= 0; - wbs_rty_i_reg <= 0; - wbs_cyc_o_reg <= 0; - wbs_done_reg <= 0; - end - end - - // synchronize signals - wbs_cyc_o_sync1 <= wbm_cyc_i_reg; - wbs_cyc_o_sync2 <= wbs_cyc_o_sync1; - wbs_cyc_o_sync3 <= wbs_cyc_o_sync2; - - wbs_stb_o_sync1 <= wbm_stb_i_reg; - wbs_stb_o_sync2 <= wbs_stb_o_sync1; - wbs_stb_o_sync3 <= wbs_stb_o_sync2; -end - -endmodule