summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nld_roms.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nld_roms.cpp')
-rw-r--r--src/lib/netlist/devices/nld_roms.cpp461
1 files changed, 232 insertions, 229 deletions
diff --git a/src/lib/netlist/devices/nld_roms.cpp b/src/lib/netlist/devices/nld_roms.cpp
index e2e4ba4eb77..a9d52850dba 100644
--- a/src/lib/netlist/devices/nld_roms.cpp
+++ b/src/lib/netlist/devices/nld_roms.cpp
@@ -1,4 +1,4 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
/*
* 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,279 @@ 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_TE(*this, "FORCE_TRISTATE_LOGIC", 0)
+ , 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{}", m_TE())
+ , 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));
}
+ }
+
+ param_logic_t m_TE;
+ 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{}"),
+ // Causes a expected primary expression before { with gcc9
+ //std::array<nl_delegate, 3>{NETLIB_DELEGATE(ce<0>),
+ // NETLIB_DELEGATE(ce<1>),
+ // NETLIB_DELEGATE(ce<2>)})
+ std::array<nl_delegate, 3>{nl_delegate(& NETLIB_NAME(generic_prom) :: ce<0>, this),
+ nl_delegate(& NETLIB_NAME(generic_prom) :: ce<1>, this),
+ nl_delegate(& NETLIB_NAME(generic_prom) :: ce<2>, this)})
+ , 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 +308,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