draft integration of CPLD in FPGA - can't have internal tri-state signals...

This commit is contained in:
Romain Dolbeau 2022-11-01 11:36:51 +01:00
parent 15a6d9cfc1
commit b621ee2eb5
3 changed files with 167 additions and 27 deletions

View File

@ -49,8 +49,25 @@ class NuBus(Module):
#self.sync.nubus += [ grant_mem.eq(grant | grant_mem) ]
#self.comb += pad_user_led_0.eq(arbcy_n_mem)
#self.comb += pad_user_led_1.eq(grant_mem)
# FPGA<->CPLD only, now internal signal
nubus_master_dir = Signal()
rqst_oe_n = Signal()
arbcy_n = Signal()
grant = Signal()
tmoen = Signal()
# those are needed in both Nubus and cpld integrated part now
broadcast_id_3v3_n = plaform.request("id_3v3_n")
# those are 'return' signals (O part of IO separated in I and O)
# the 3v3 signals 'see' the 5V signals from the external drivers
internal_start_3v3_n = Signal()
internal_tm0_3v3_n = Signal()
internal_tm1_3v3_n = Signal()
internal_tm2_3v3_n = Signal()
internal_ack_3v3_n = Signal()
internal_rqst_3v3_n = Signal()
#fixme: parameters
self.specials += Instance(self.get_netlist_name(),
# master side
#p_SIMPLE_MAP = 0x0,
@ -60,20 +77,25 @@ class NuBus(Module):
p_LOCAL_SPACE_EXPOSED_TO_NUBUS = 0,
i_nub_clkn = ClockSignal(cd_nubus),
i_nub_resetn = ~ResetSignal(cd_nubus),
i_nub_idn = platform.request("id_3v3_n"),
i_nub_idn = broadcast_id_3v3_n, # internal now
# io_nub_pfwn = self.nubus_pwf_n,
io_nub_adn = platform.request("ad_3v3_n"),
io_nub_tm0n = platform.request("tm0_3v3_n"),
io_nub_tm1n = platform.request("tm1_3v3_n"),
io_nub_startn = platform.request("start_3v3_n"),
io_nub_rqstn = platform.request("rqst_3v3_n"),
io_nub_ackn = platform.request("ack_3v3_n"),
i_nub_tm0n = platform.request("tm0_3v3_n"),
i_nub_tm1n = platform.request("tm1_3v3_n"),
i_nub_startn = platform.request("start_3v3_n"),
i_nub_rqstn = platform.request("rqst_3v3_n"),
i_nub_ackn = platform.request("ack_3v3_n"),
o_nub_tm0n = internal_tm0_3v3_n,
o_nub_tm1n = internal_tm1_3v3_n,
o_nub_startn = internal_start_3v3_n,
o_nub_rqstn = internal_rqst_3v3_n,
o_nub_ackn = internal_ack_3v3_n,
# io_nub_arbn = platform.request("nubus_arb_n"),
o_arbcy_n = platform.request("arbcy_n"),
i_grant = platform.request("grant"),
o_tmoen = platform.request("tmoen"),
o_arbcy_n = arbcy_n, # internal now
i_grant = grant, # internal now
o_tmoen = tmoen, # internal now
o_NUBUS_AD_DIR = platform.request("nubus_ad_dir"),
o_nubus_master_dir = platform.request("nubus_master_dir"),
o_nubus_master_dir = nubus_master_dir, # internal now
# io_nub_nmrqn = platform.request("nmrq_3v3_n"),
# io_nub_spn = self.nubus_sp_n,
# io_nub_spvn = self.nubus_spv_n,
@ -98,11 +120,48 @@ class NuBus(Module):
o_mem_super = self.mem_super,
o_mem_local = self.mem_local,
o_fpga_to_cpld_signal = platform.request("fpga_to_cpld_signal"),
o_fpga_to_cpld_signal = rqst_oe_n, # internal now
i_nub_clk2xn = ClockSignal(cd_nubus90),
io_nub_tm2n = platform.request("tm2_3v3_n"),
i_nub_tm2n = platform.request("tm2_3v3_n"),
o_nub_tm2n = internal_tm2_3v3_n,
)
self.specials += Instance("nubus_cpldinfpga",
i_nubus_oe = nubus_oe, # FIXME: handled in soc
i_tmoen = tmoen,
i_nubus_master_dir = nubus_master_dir,
i_rqst_oe_n = rqst_oe_n,
i_id_n_3v3 = broadcast_id_3v3_n, # input only
i_arbcy_n = arbcy_n,
i_arb_n_3v3 = platform.request("arb_3v3_n"), # arb only seen by cpld
o_arb_o_n = platform.request("arb_o_n"),
o_grant = grant,
i_tm0_n_3v3 = internal_tm0_3v3_n, # tm0 driving controlled by tmoen
o_tm0_o_n = platform.request("tm_o_n"),
i_tm1_n_3v3 = internal_tm1_3v3_n, # tm1 driving controlled by tmoen
o_tm1_o_n = platform_request("tm1_o_n"),
o_tmx_oe_n = platform_request("tmx_oe_n"),
i_tm2_n_3v3 = internal_tm2_3v3_n, # tm2 currently never driven
o_tm2_o_n = platform_request("tm2_o_n"),
o_tm2_oe_n = platform_request("tm2_oe_n"),
i_start_n_3v3 = internal_start_3v3_n, # start driving enabled by nubus_master_dir
o_start_o_n = platform_request("start_o_n"),
o_start_oe_n = platform_request("start_oe_n"),
i_ack_n_3v3 = internal_ack_3v3_n, # ack driving controlled by tmoen
o_ack_o_n = platform_request("ack_o_n"),
o_ack_oe_n = platform_request("ack_oe_n"),
i_rqst_n_3v3 = internal_rqst_3v3_n, # rqst driving ocntroller by rqst_oe_n
o_rqst_o_n = platform_request("rqst_o_n")
)
def get_netlist_name(self):
return "nubus"
@ -111,10 +170,11 @@ class NuBus(Module):
platform.add_source("nubus.v", "verilog")
# XiBus is from my github, branch 'more_fixes'
platform.add_source("XiBus/nubus.svh", "verilog")
#platform.add_source("XiBus/nubus_arbiter.v", "verilog") # in the CPLD
#platform.add_source("XiBus/nubus_arbiter.v", "verilog") # in the CPLDinfpga
platform.add_source("XiBus/nubus_cpubus.v", "verilog")
platform.add_source("XiBus/nubus_driver.v", "verilog")
#platform.add_source("XiBus/nubus_errors.v", "verilog") # unused
platform.add_source("XiBus/nubus_membus.v", "verilog")
platform.add_source("XiBus/nubus_master.v", "verilog")
platform.add_source("XiBus/nubus_slave.v", "verilog")
platform.add_source("nubus_cpldinfpga.v", "verilog") # internal now

View File

@ -28,19 +28,26 @@ module nubus
(
/* *** NuBus signals *** */
/* those are connected to the FPGA */
/* connected via the CPLD */
input nub_clkn, // Clock (rising is driving edge, faling is sampling)
input nub_resetn, // Reset
input [ 3:0] nub_idn, // Slot Identification
inout nub_tm0n, // Transfer Mode
inout nub_tm1n, // Transfer Mode
inout nub_startn, // Start
inout nub_rqstn, // Request
inout nub_ackn, // Acknowledge
// raw input
input nub_tm0n, // Transfer Mode
input nub_tm1n, // Transfer Mode
input nub_startn, // Start
input nub_rqstn, // Request
input nub_ackn, // Acknowledge
// output to other part of the FPGA
output nub_tm0n_o, // Transfer Mode
output nub_tm1n_o, // Transfer Mode
output nub_startn_o, // Start
output nub_rqstn_o, // Request
output nub_ackn_o, // Acknowledge
// connected via the CPLD but NuBus90 (unimplemented)
// NuBus90 (unimplemented)
input nub_clk2xn,
inout nub_tm2n,
input nub_tm2n,
output nub_tm2n_o,
/* connected via the 74LVT245 */
inout [31:0] nub_adn, // Address/Data
@ -260,11 +267,11 @@ module nubus
.mst_tm0n(cpu_tm0n), // Address lines
.mst_timeout(mst_timeout),
.mis_errorn(TMN_COMPLETE),
.nub_tm0n_o(nub_tm0n), // Transfer mode
.nub_tm1n_o(nub_tm1n), // Transfer mode
.nub_ackn_o(nub_ackn), // Achnowlege
.nub_startn_o(nub_startn), // Transfer start
.nub_rqstn_o(nub_rqstn), // Bus request
.nub_tm0n_o(nub_tm0n_o), // Transfer mode
.nub_tm1n_o(nub_tm1n_o), // Transfer mode
.nub_ackn_o(nub_ackn_o), // Achnowlege
.nub_startn_o(nub_startn_o), // Transfer start
.nub_rqstn_o(nub_rqstn_o), // Bus request
.nub_rqstoen_o(fpga_to_cpld_signal), // Bus request enable
.drv_tmoen_o(drv_tmoen), // Transfer mode enable
.drv_mstdn_o(drv_mstdn) // Guess: Slave sends /ACK. Master responds with /MSTDN, which allows slave to clear /ACK and listen for next transaction.

View File

@ -0,0 +1,73 @@
module nubus_cpldinfpga
(
// Control
input nubus_oe, // disable all 5v drivers
input tmoen, // tm output enable
input nubus_master_dir, // direction of signals, i.e. are we in master mode
// Spares
input rqst_oe_n, // rqstoen (extra line from FPGA to CPLD)
// NuBus
input [3:0] id_n_3v3, // nubus ID of this card to FPGA
// NuBus Arbiter
input arbcy_n, // enable arbitter
input [3:0] arb_n_3v3, // NuBus arbiter's lines
output [3:0] arb_o_n, // NuBus arbiter's control lines
output grant, // Grant access
// Cycle Control (NuBus two-way)
input tm0_n_3v3, // nubus tm0 to/from FPGA
output tm0_o_n, // start from NuBus
input tm1_n_3v3, // nubus tm1 to/from FPGA
output tm1_o_n, // start from NuBus
output tmx_oe_n, // start from NuBus
input tm2_n_3v3, // nubus tm2 to/from FPGA
output tm2_o_n, // start from NuBus
output tm2_oe_n, // start from NuBus
input start_n_3v3, // start to/from FPGA
output start_o_n, // start from NuBus
output start_oe_n, // start from NuBus
input ack_n_3v3, // ack from/to FPGA
output ack_o_n, // ack to NuBus
output ack_oe_n, // ack OE NuBus
// Master Request (OC)
input rqst_n_3v3, // rqst from/to FPGA
output rqst_o_n // rqst to NuBus
);
// placeholders
assign tm2_n_3v3 = tm2_n_5v;
assign tm2_o_n = 0;
assign tm2_oe_n = 1;
// ~nubus_master_dir-controlled signals
assign start_o_n = nubus_oe ? 1 : ( nubus_master_dir ? start_n_3v3 : 1); // master out
assign start_oe_n = nubus_oe ? 1 : ( nubus_master_dir ? 0 : 1); // master out
// rqst_o_n is always driven (the 74lvt125 wired as open collector will convert 1 to Z) and is active low
assign rqst_o_n = nubus_oe ? 1 : (~rqst_oe_n ? rqst_n_3v3 : 1); // master out
assign ack_o_n = nubus_oe ? 1 : (( ~tmoen) ? ack_n_3v3 : 1); // slave out/in
assign ack_oe_n = nubus_oe ? 1 : (( ~tmoen) ? 0 : 1); // slave out/in
assign tm0_o_n = nubus_oe ? 1 : (( ~tmoen) ? tm0_n_3v3 : 1); // slave out/in
assign tm1_o_n = nubus_oe ? 1 : (( ~tmoen) ? tm1_n_3v3 : 1); // slave out/in
assign tmx_oe_n = nubus_oe ? 1 : (( ~tmoen) ? 0 : 1); // slave out/in
nubus_arbiter UArbiter
(
.idn(id_n_3v3),
.arbn(arb_n_3v3),
.arbon(arb_o_n),
.arbcyn(arbcy_n),
.grant(grant)
);
endmodule // nubus_cpld