diff options
Diffstat (limited to 'src/lib/netlist/devices/nld_roms.cpp')
-rw-r--r-- | src/lib/netlist/devices/nld_roms.cpp | 453 |
1 files changed, 225 insertions, 228 deletions
diff --git a/src/lib/netlist/devices/nld_roms.cpp b/src/lib/netlist/devices/nld_roms.cpp index e2e4ba4eb77..ef4ccc71c8f 100644 --- a/src/lib/netlist/devices/nld_roms.cpp +++ b/src/lib/netlist/devices/nld_roms.cpp @@ -11,7 +11,7 @@ template <typename N, typename T> constexpr bool TOR(N n, T &a) { - return (n == 0 ? false : TOR(n-1, a) || a[n-1]()); + return (n == 0) ? false : (TOR(n - 1, a) || a[n - 1]()); } template <typename T> @@ -20,275 +20,273 @@ constexpr bool TOR(T &a) return TOR(a.size(), a); } -namespace netlist -{ - namespace devices +namespace netlist::devices { + + NETLIB_OBJECT(mk28000_prom) { - NETLIB_OBJECT(mk28000_prom) + NETLIB_CONSTRUCTOR(mk28000_prom) + , m_enable_lo(*this, "m_enable_lo", false) + , m_enable_hi(*this, "m_enable_hi", false) + , m_latched_rom(*this, "m_latched_rom", 0) + , m_A(*this, 1, "A{}", NETLIB_DELEGATE(addr)) + , m_ARQ(*this, "ARQ", NETLIB_DELEGATE(addr)) + , m_OE1(*this, "OE1", NETLIB_DELEGATE(oe1)) + , m_OE2(*this, "OE2", NETLIB_DELEGATE(oe2)) + , m_O(*this, 1, "O{}", 0) + , m_ROM(*this, "ROM") + , m_power_pins(*this) + { + } + + private: + NETLIB_HANDLERI(oe1) { - NETLIB_CONSTRUCTOR(mk28000_prom) - , m_enable_lo(*this, "m_enable_lo", false) - , m_enable_hi(*this, "m_enable_hi", false) - , m_latched_rom(*this, "m_latched_rom", 0) - , m_A(*this, 1, "A{}", NETLIB_DELEGATE(addr)) - , m_ARQ(*this, "ARQ", NETLIB_DELEGATE(addr)) - , m_OE1(*this, "OE1", NETLIB_DELEGATE(oe1)) - , m_OE2(*this, "OE2", NETLIB_DELEGATE(oe2)) - , m_O(*this, 1, "O{}", 0) - , m_ROM(*this, "ROM") - , m_power_pins(*this) + m_enable_lo = m_OE1(); + uint8_t o = m_enable_lo ? m_latched_rom : 0; + for (std::size_t i=0; i<4; i++) { + m_O.set_tristate(!m_enable_lo, NLTIME_FROM_NS(600), NLTIME_FROM_NS(600)); + m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(600)); } + } - private: - NETLIB_HANDLERI(oe1) + NETLIB_HANDLERI(oe2) + { + m_enable_hi = m_OE2(); + uint8_t o = m_enable_hi ? m_latched_rom : 0; + for (std::size_t i=4; i<8; i++) { - m_enable_lo = m_OE1(); - uint8_t o = m_enable_lo ? m_latched_rom : 0; - for (std::size_t i=0; i<4; i++) - { - m_O.set_tristate(!m_enable_lo, NLTIME_FROM_NS(600), NLTIME_FROM_NS(600)); - m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(600)); - } + m_O.set_tristate(!m_enable_hi, NLTIME_FROM_NS(600), NLTIME_FROM_NS(600)); + m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(600)); } + } - NETLIB_HANDLERI(oe2) + NETLIB_HANDLERI(addr) + { + if (!m_ARQ()) { - m_enable_hi = m_OE2(); - uint8_t o = m_enable_hi ? m_latched_rom : 0; - for (std::size_t i=4; i<8; i++) - { - m_O.set_tristate(!m_enable_hi, NLTIME_FROM_NS(600), NLTIME_FROM_NS(600)); - m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(600)); - } + const auto addr = m_A(); + m_latched_rom = m_ROM[addr]; } - - NETLIB_HANDLERI(addr) + uint8_t o = (m_enable_hi || m_enable_lo) ? m_latched_rom : 0; + for (std::size_t i=0; i<4; i++) { - if (!m_ARQ()) - { - const auto addr = m_A(); - m_latched_rom = m_ROM[addr]; - } - uint8_t o = (m_enable_hi || m_enable_lo) ? m_latched_rom : 0; - for (std::size_t i=0; i<4; i++) - { - m_O.set_tristate(!m_enable_lo, NLTIME_FROM_NS(600), NLTIME_FROM_NS(600)); - m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(600)); - } - for (std::size_t i=4; i<8; i++) - { - m_O.set_tristate(!m_enable_hi, NLTIME_FROM_NS(600), NLTIME_FROM_NS(600)); - m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(600)); - } + m_O.set_tristate(!m_enable_lo, NLTIME_FROM_NS(600), NLTIME_FROM_NS(600)); + m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(600)); } - - state_var<bool> m_enable_lo; - state_var<bool> m_enable_hi; - state_var<uint8_t> m_latched_rom; - object_array_t<logic_input_t, 11> m_A; - logic_input_t m_ARQ; - logic_input_t m_OE1; - logic_input_t m_OE2; - object_array_t<tristate_output_t, 8> m_O; - - param_rom_t<uint8_t, 11, 8> m_ROM; - nld_power_pins m_power_pins; - }; - - NETLIB_OBJECT(mcm14524_rom) - { - NETLIB_CONSTRUCTOR_MODEL(mcm14524_rom, "CD4XXX") - , m_enabled(*this, "m_enabled", true) - , m_latched_rom(*this, "m_latched_rom", 0) - , m_A(*this, 1, "A{}", NETLIB_DELEGATE(addr)) - , m_CLK(*this, "CLK", NETLIB_DELEGATE(addr)) - , m_clk_old(*this, "m_clk_old", true) - , m_EN(*this, "EN", NETLIB_DELEGATE(en)) - , m_B(*this, 1, "B{}", 0) - , m_ROM(*this, "ROM") - , m_taccc(*this, "m_taccc", netlist_time::from_nsec(1350)) - , m_taccen(*this, "m_taccen", netlist_time::from_nsec(245)) - , m_power_pins(*this, NETLIB_DELEGATE(vdd_vss)) + for (std::size_t i=4; i<8; i++) { + m_O.set_tristate(!m_enable_hi, NLTIME_FROM_NS(600), NLTIME_FROM_NS(600)); + m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(600)); } + } + + state_var<bool> m_enable_lo; + state_var<bool> m_enable_hi; + state_var<uint8_t> m_latched_rom; + object_array_t<logic_input_t, 11> m_A; + logic_input_t m_ARQ; + logic_input_t m_OE1; + logic_input_t m_OE2; + object_array_t<tristate_output_t, 8> m_O; + + param_rom_t<uint8_t, 11, 8> m_ROM; + nld_power_pins m_power_pins; + }; + + NETLIB_OBJECT(mcm14524_rom) + { + NETLIB_CONSTRUCTOR_MODEL(mcm14524_rom, "CD4XXX") + , m_enabled(*this, "m_enabled", true) + , m_latched_rom(*this, "m_latched_rom", 0) + , m_A(*this, 1, "A{}", NETLIB_DELEGATE(addr)) + , m_CLK(*this, "CLK", NETLIB_DELEGATE(addr)) + , m_clk_old(*this, "m_clk_old", true) + , m_EN(*this, "EN", NETLIB_DELEGATE(en)) + , m_B(*this, 1, "B{}", 0) + , m_ROM(*this, "ROM") + , m_taccc(*this, "m_taccc", netlist_time::from_nsec(1350)) + , m_taccen(*this, "m_taccen", netlist_time::from_nsec(245)) + , m_power_pins(*this, NETLIB_DELEGATE(vdd_vss)) + { + } - private: - NETLIB_HANDLERI(en) + private: + NETLIB_HANDLERI(en) + { + m_enabled = m_EN(); + uint8_t o = m_enabled ? m_latched_rom : 0; // outputs are forced to 0 by enable going low; this chip does not have tri-state outputs! + for (std::size_t i=0; i<4; i++) { - m_enabled = m_EN(); - uint8_t o = m_enabled ? m_latched_rom : 0; // outputs are forced to 0 by enable going low; this chip does not have tri-state outputs! - for (std::size_t i=0; i<4; i++) - { - m_B[i].push((o >> i) & 1, m_taccen); - } + m_B[i].push((o >> i) & 1, m_taccen); } + } - NETLIB_HANDLERI(addr) + NETLIB_HANDLERI(addr) + { + if (!m_CLK() && m_clk_old) // latch on falling edge { - if (!m_CLK() && m_clk_old) // latch on falling edge - { - const auto addr = m_A(); - m_latched_rom = m_ROM[addr]; - } - m_clk_old = m_CLK(); - uint8_t o = m_enabled ? m_latched_rom : 0; // outputs are forced to 0 by enable going low; this chip does not have tri-state outputs! - for (std::size_t i=0; i<4; i++) - { - m_B[i].push((o >> i) & 1, m_taccc); - } + const auto addr = m_A(); + m_latched_rom = m_ROM[addr]; } - - NETLIB_HANDLERI(vdd_vss) + m_clk_old = m_CLK(); + uint8_t o = m_enabled ? m_latched_rom : 0; // outputs are forced to 0 by enable going low; this chip does not have tri-state outputs! + for (std::size_t i=0; i<4; i++) { - auto d = m_power_pins.VCC()() - m_power_pins.GND()(); - if (d > 0.1) // avoid unrealistic values - { - m_taccc = netlist_time::from_nsec(gsl::narrow_cast<unsigned>(7615.5 / d - 181)); - m_taccen = netlist_time::from_nsec(gsl::narrow_cast<unsigned>(1292.5 / d - 14.6)); - } + m_B[i].push((o >> i) & 1, m_taccc); } + } - state_var<bool> m_enabled; - state_var<uint8_t> m_latched_rom; - object_array_t<logic_input_t, 8> m_A; - logic_input_t m_CLK; - state_var<bool> m_clk_old; - logic_input_t m_EN; - object_array_t<tristate_output_t, 4> m_B; - param_rom_t<uint8_t, 8, 4> m_ROM; - state_var<netlist_time> m_taccc; // propagation time for data vs CLK - state_var<netlist_time> m_taccen; // propagation time for data vs /EN - nld_power_pins m_power_pins; - }; - - template <typename D> - NETLIB_OBJECT(generic_prom) + NETLIB_HANDLERI(vdd_vss) { - NETLIB_CONSTRUCTOR(generic_prom) - , m_enabled(*this, "m_enabled", true) - , m_TE(*this, "FORCE_TRISTATE_LOGIC", 0) - , m_A(*this, 0, "A{}", NETLIB_DELEGATE(addr)) - , m_CEQ(*this, 1, - D::chip_enable_mask::value ^ static_cast<size_t>(0xffff), pstring("CE{}"), - std::array<nldelegate, 3>{ NETLIB_DELEGATE(ce<0>), - NETLIB_DELEGATE(ce<1>), - NETLIB_DELEGATE(ce<2>)}) - , m_O(*this, D::data_name_offset::value, "O{}", m_TE()) - , m_ROM(*this, "ROM") - , m_power_pins(*this) + auto d = m_power_pins.VCC()() - m_power_pins.GND()(); + if (d > 0.1) // avoid unrealistic values { + m_taccc = netlist_time::from_nsec(gsl::narrow_cast<unsigned>(7615.5 / d - 181)); + m_taccen = netlist_time::from_nsec(gsl::narrow_cast<unsigned>(1292.5 / d - 14.6)); } + } + + state_var<bool> m_enabled; + state_var<uint8_t> m_latched_rom; + object_array_t<logic_input_t, 8> m_A; + logic_input_t m_CLK; + state_var<bool> m_clk_old; + logic_input_t m_EN; + object_array_t<tristate_output_t, 4> m_B; + param_rom_t<uint8_t, 8, 4> m_ROM; + state_var<netlist_time> m_taccc; // propagation time for data vs CLK + state_var<netlist_time> m_taccen; // propagation time for data vs /EN + nld_power_pins m_power_pins; + }; + + template <typename D> + NETLIB_OBJECT(generic_prom) + { + NETLIB_CONSTRUCTOR(generic_prom) + , m_enabled(*this, "m_enabled", true) + , m_TE(*this, "FORCE_TRISTATE_LOGIC", 0) + , m_A(*this, 0, "A{}", NETLIB_DELEGATE(addr)) + , m_CEQ(*this, 1, + D::chip_enable_mask::value ^ static_cast<size_t>(0xffff), pstring("CE{}"), + std::array<nldelegate, 3>{ NETLIB_DELEGATE(ce<0>), + NETLIB_DELEGATE(ce<1>), + NETLIB_DELEGATE(ce<2>)}) + , m_O(*this, D::data_name_offset::value, "O{}", m_TE()) + , m_ROM(*this, "ROM") + , m_power_pins(*this) + { + } - using data_type = typename plib::least_type_for_bits<D::data_width::value>::type; + using data_type = typename plib::least_type_for_bits<D::data_width::value>::type; - private: + private: - template <std::size_t N> - NETLIB_HANDLERI(ce) + template <std::size_t N> + NETLIB_HANDLERI(ce) + { + using cet = typename D::chip_enable_time; + m_enabled = (m_CEQ() == D::chip_enable_mask::value); + switch (D::output_id::value) { - using cet = typename D::chip_enable_time; - m_enabled = (m_CEQ() == D::chip_enable_mask::value); - switch (D::output_id::value) - { - case 0: // logic - { - m_O.push(m_ROM[m_A()], D::access_time::value()); - } - break; - case 1: // tristate - { - m_O.set_tristate(!m_enabled, cet::value(N), cet::value(N)); - m_O.push(m_ROM[m_A()], D::access_time::value()); - } - break; - default: // 2, open collector - { - const auto delay = m_enabled ? D::access_time::value() : cet::value(N); - const data_type o = m_enabled ? m_ROM[m_A()] : - (1 << D::data_width::value) - 1; - m_O.push(o, delay); - } - break; - } - + case 0: // logic + { + m_O.push(m_ROM[m_A()], D::access_time::value()); + } + break; + case 1: // tristate + { + m_O.set_tristate(!m_enabled, cet::value(N), cet::value(N)); + m_O.push(m_ROM[m_A()], D::access_time::value()); + } + break; + default: // 2, open collector + { + const auto delay = m_enabled ? D::access_time::value() : cet::value(N); + const data_type o = m_enabled ? m_ROM[m_A()] : + (1 << D::data_width::value) - 1; + m_O.push(o, delay); + } + break; } - NETLIB_HANDLERI(addr) + } + + NETLIB_HANDLERI(addr) + { + if (m_enabled) { - if (m_enabled) - { - m_O.push(m_ROM[m_A()], D::access_time::value()); - } + m_O.push(m_ROM[m_A()], D::access_time::value()); } + } - state_var<bool> m_enabled; - param_logic_t m_TE; - object_array_t<logic_input_t, D::address_width::value> m_A; - object_array_t<logic_input_t, D::chip_enable_inputs::value> m_CEQ; - object_array_t<typename D::output_type, D::data_width::value> m_O; + state_var<bool> m_enabled; + param_logic_t m_TE; + object_array_t<logic_input_t, D::address_width::value> m_A; + object_array_t<logic_input_t, D::chip_enable_inputs::value> m_CEQ; + object_array_t<typename D::output_type, D::data_width::value> m_O; - param_rom_t<uint8_t, D::address_width::value, D::data_width::value> m_ROM; - nld_power_pins m_power_pins; - }; + param_rom_t<uint8_t, D::address_width::value, D::data_width::value> m_ROM; + nld_power_pins m_power_pins; + }; - struct desc_82S126 : public desc_base - { - using address_width = desc_const<8>; - using data_width = desc_const<4>; - using data_name_offset = desc_const<1>; // O1, O2, .. - using chip_enable_inputs = desc_const<2>; - // MATCH_MASK : all 0 ==> all bits inverted - using chip_enable_mask = desc_const<0x00>; + struct desc_82S126 : public desc_base + { + using address_width = desc_const<8>; + using data_width = desc_const<4>; + using data_name_offset = desc_const<1>; // O1, O2, .. + using chip_enable_inputs = desc_const<2>; + // MATCH_MASK : all 0 ==> all bits inverted + using chip_enable_mask = desc_const<0x00>; - using chip_enable_time = times_ns2<25, 25>; - using access_time = time_ns<40>; + using chip_enable_time = times_ns2<25, 25>; + using access_time = time_ns<40>; - using output_type = tristate_output_t; - using output_id = desc_const<1>; // 0: logic, 1: tristate, 2: open collector - }; + using output_type = tristate_output_t; + using output_id = desc_const<1>; // 0: logic, 1: tristate, 2: open collector + }; - struct desc_74S287 : public desc_82S126 - { - using data_name_offset = desc_const<0>; // O0, O1, ... according to National Semiconductor datasheet - using chip_enable_time = times_ns2<15, 15>; - using access_time = time_ns<35>; - }; + struct desc_74S287 : public desc_82S126 + { + using data_name_offset = desc_const<0>; // O0, O1, ... according to National Semiconductor datasheet + using chip_enable_time = times_ns2<15, 15>; + using access_time = time_ns<35>; + }; - struct desc_82S123 : public desc_base - { - // FIXME: tristate outputs, add 82S23 (open collector) - using address_width = desc_const<5>; - using data_width = desc_const<8>; - using data_name_offset = desc_const<0>; // O0, O1, .. - using chip_enable_inputs = desc_const<1>; - // MATCH_MASK : all 0 ==> all bits inverted - using chip_enable_mask = desc_const<0x00>; - - using chip_enable_time = times_ns1<35>; - using access_time = time_ns<45>; - - using output_type = tristate_output_t; - using output_id = desc_const<1>; // 0: logic, 1: tristate, 2: open collector - }; - - struct desc_2716 : public desc_base - { - // FIXME: tristate outputs - using address_width = desc_const<11>; - using data_width = desc_const<8>; - using data_name_offset = desc_const<0>; // O0, O1, .. + struct desc_82S123 : public desc_base + { + // FIXME: tristate outputs, add 82S23 (open collector) + using address_width = desc_const<5>; + using data_width = desc_const<8>; + using data_name_offset = desc_const<0>; // O0, O1, .. + using chip_enable_inputs = desc_const<1>; + // MATCH_MASK : all 0 ==> all bits inverted + using chip_enable_mask = desc_const<0x00>; + + using chip_enable_time = times_ns1<35>; + using access_time = time_ns<45>; + + using output_type = tristate_output_t; + using output_id = desc_const<1>; // 0: logic, 1: tristate, 2: open collector + }; + + struct desc_2716 : public desc_base + { + // FIXME: tristate outputs + using address_width = desc_const<11>; + using data_width = desc_const<8>; + using data_name_offset = desc_const<0>; // O0, O1, .. - using chip_enable_inputs = desc_const<2>; - // MATCH_MASK : all 0 ==> all bits inverted - using chip_enable_mask = desc_const<0x00>; + using chip_enable_inputs = desc_const<2>; + // MATCH_MASK : all 0 ==> all bits inverted + using chip_enable_mask = desc_const<0x00>; - using chip_enable_time = times_ns2<450, 100>; //CE, OE - using access_time = time_ns<450>; + using chip_enable_time = times_ns2<450, 100>; //CE, OE + using access_time = time_ns<450>; - using output_type = tristate_output_t; - using output_id = desc_const<1>; // 0: logic, 1: tristate, 2: open collector - }; + using output_type = tristate_output_t; + using output_id = desc_const<1>; // 0: logic, 1: tristate, 2: open collector + }; using NETLIB_NAME(82S123) = NETLIB_NAME(generic_prom)<desc_82S123>; // 256 bits, 32x8, used as 256x4 using NETLIB_NAME(82S126) = NETLIB_NAME(generic_prom)<desc_82S126>; // 1024 bits, 32x32, used as 256x4 @@ -304,5 +302,4 @@ namespace netlist NETLIB_DEVICE_IMPL(MK28000, "PROM_MK28000", "+OE1,+OE2,+ARQ,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10,+A11,@VCC,@GND") NETLIB_DEVICE_IMPL(MCM14524, "ROM_MCM14524", "+EN,+CLK,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,@VCC,@GND") - } //namespace devices -} // namespace netlist +} // namespace netlist::devices |