diff --git a/nubus-to-ztex-gateware/nubus.py b/nubus-to-ztex-gateware/nubus.py index 408d6d2..18da129 100644 --- a/nubus-to-ztex-gateware/nubus.py +++ b/nubus-to-ztex-gateware/nubus.py @@ -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 diff --git a/nubus-to-ztex-gateware/nubus.v b/nubus-to-ztex-gateware/nubus.v index 4c908cd..9eab85a 100644 --- a/nubus-to-ztex-gateware/nubus.v +++ b/nubus-to-ztex-gateware/nubus.v @@ -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. diff --git a/nubus-to-ztex-gateware/nubus_cpldinfpga.v b/nubus-to-ztex-gateware/nubus_cpldinfpga.v new file mode 100644 index 0000000..bd30661 --- /dev/null +++ b/nubus-to-ztex-gateware/nubus_cpldinfpga.v @@ -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