move some files to a new common submodules
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -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
|
||||
Submodule sbus-to-ztex-gateware-migen/VintageBusFPGA_Common added at 535024e885
@@ -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 ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -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")
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user