trunk/src/emu/netlist/nl_base.c
| r26109 | r26110 | |
| 23 | 23 | { |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | | ATTR_COLD void netlist_base_t::set_mainclock_dev(NETLIB_NAME(netdev_mainclock) *dev) |
| 26 | ATTR_COLD void netlist_base_t::set_mainclock_dev(NETLIB_NAME(mainclock) *dev) |
| 27 | 27 | { |
| 28 | 28 | m_mainclock = dev; |
| 29 | 29 | } |
| r26109 | r26110 | |
| 91 | 91 | atime = 0; |
| 92 | 92 | } |
| 93 | 93 | } else { |
| 94 | | net_net_t &mcQ = m_mainclock->m_Q.net(); |
| 94 | netlist_net_t &mcQ = m_mainclock->m_Q.net(); |
| 95 | 95 | const netlist_time inc = m_mainclock->m_inc; |
| 96 | 96 | |
| 97 | 97 | while (atime > 0) |
| r26109 | r26110 | |
| 102 | 102 | { |
| 103 | 103 | update_time(mcQ.time(), atime); |
| 104 | 104 | |
| 105 | | NETLIB_NAME(netdev_mainclock)::mc_update(mcQ, time() + inc); |
| 105 | NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc); |
| 106 | 106 | |
| 107 | 107 | } |
| 108 | 108 | const queue_t::entry_t e = m_queue.pop(); |
| r26109 | r26110 | |
| 114 | 114 | } else { |
| 115 | 115 | update_time(mcQ.time(), atime); |
| 116 | 116 | |
| 117 | | NETLIB_NAME(netdev_mainclock)::mc_update(mcQ, time() + inc); |
| 117 | NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc); |
| 118 | 118 | } |
| 119 | 119 | if (FATAL_ERROR_AFTER_NS) |
| 120 | 120 | if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS)) |
| r26109 | r26110 | |
| 142 | 142 | // ---------------------------------------------------------------------------------------- |
| 143 | 143 | |
| 144 | 144 | netlist_core_device_t::netlist_core_device_t() |
| 145 | | : net_object_t(DEVICE) |
| 145 | : netlist_object_t(DEVICE, ALL) |
| 146 | 146 | { |
| 147 | 147 | } |
| 148 | 148 | |
| r26109 | r26110 | |
| 171 | 171 | // net_device_t |
| 172 | 172 | // ---------------------------------------------------------------------------------------- |
| 173 | 173 | |
| 174 | | ATTR_HOT ATTR_ALIGN const netlist_sig_t netlist_core_device_t::INPLOGIC_PASSIVE(logic_input_t &inp) |
| 174 | ATTR_HOT ATTR_ALIGN const netlist_sig_t netlist_core_device_t::INPLOGIC_PASSIVE(netlist_logic_input_t &inp) |
| 175 | 175 | { |
| 176 | | if (inp.state() == net_input_t::INP_STATE_PASSIVE) |
| 176 | if (inp.state() == netlist_input_t::INP_STATE_PASSIVE) |
| 177 | 177 | { |
| 178 | 178 | inp.activate(); |
| 179 | 179 | const netlist_sig_t ret = inp.Q(); |
| r26109 | r26110 | |
| 185 | 185 | |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | | net_device_t::net_device_t() |
| 188 | netlist_device_t::netlist_device_t() |
| 189 | 189 | : netlist_core_device_t(), |
| 190 | | m_inputs(20), |
| 190 | m_terminals(20), |
| 191 | 191 | m_setup(NULL), |
| 192 | 192 | m_variable_input_count(false) |
| 193 | 193 | { |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | | net_device_t::~net_device_t() |
| 196 | netlist_device_t::~netlist_device_t() |
| 197 | 197 | { |
| 198 | 198 | //printf("~net_device_t\n"); |
| 199 | 199 | } |
| 200 | 200 | |
| 201 | | ATTR_COLD void net_device_t::init(netlist_setup_t &setup, const astring &name) |
| 201 | ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const astring &name) |
| 202 | 202 | { |
| 203 | 203 | netlist_core_device_t::init(setup, name); |
| 204 | 204 | m_setup = &setup; |
| r26109 | r26110 | |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | 208 | |
| 209 | | ATTR_COLD void net_device_t::register_sub(netlist_core_device_t &dev, const astring &name) |
| 209 | ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const astring &name) |
| 210 | 210 | { |
| 211 | 211 | dev.init(*m_setup, name); |
| 212 | 212 | } |
| 213 | 213 | |
| 214 | | void net_device_t::register_output(netlist_core_device_t &dev, const astring &name, net_output_t &port) |
| 214 | void netlist_device_t::register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &port) |
| 215 | 215 | { |
| 216 | 216 | m_setup->register_output(*this, dev, name, port); |
| 217 | 217 | } |
| 218 | 218 | |
| 219 | | void net_device_t::register_output(const astring &name, net_output_t &port) |
| 219 | void netlist_device_t::register_output(const astring &name, netlist_output_t &port) |
| 220 | 220 | { |
| 221 | 221 | m_setup->register_output(*this,*this,name, port); |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | | void net_device_t::register_input(netlist_core_device_t &dev, const astring &name, net_input_t &inp, net_input_t::net_input_state type) |
| 224 | void netlist_device_t::register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type) |
| 225 | 225 | { |
| 226 | 226 | m_setup->register_input(*this, dev, name, inp, type); |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | | void net_device_t::register_input(const astring &name, net_input_t &inp, net_input_t::net_input_state type) |
| 229 | void netlist_device_t::register_input(const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type) |
| 230 | 230 | { |
| 231 | 231 | register_input(*this, name, inp, type); |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | | void net_device_t::register_link_internal(netlist_core_device_t &dev, net_input_t &in, net_output_t &out, net_input_t::net_input_state aState) |
| 234 | void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState) |
| 235 | 235 | { |
| 236 | 236 | in.init_input(dev, aState); |
| 237 | 237 | out.init_terminal(dev); |
| r26109 | r26110 | |
| 239 | 239 | out.net().register_con(in); |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | | void net_device_t::register_link_internal(net_input_t &in, net_output_t &out, net_input_t::net_input_state aState) |
| 242 | void netlist_device_t::register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState) |
| 243 | 243 | { |
| 244 | 244 | register_link_internal(*this, in, out, aState); |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | | void net_device_t::register_param(netlist_core_device_t &dev, const astring &name, net_param_t ¶m, double initialVal) |
| 247 | void netlist_device_t::register_param(netlist_core_device_t &dev, const astring &name, netlist_param_t ¶m, double initialVal) |
| 248 | 248 | { |
| 249 | 249 | param.set_netdev(dev); |
| 250 | 250 | param.initial(initialVal); |
| 251 | 251 | m_setup->register_param(name, ¶m); |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | | void net_device_t::register_param(const astring &name, net_param_t ¶m, double initialVal) |
| 254 | void netlist_device_t::register_param(const astring &name, netlist_param_t ¶m, double initialVal) |
| 255 | 255 | { |
| 256 | 256 | register_param(*this,name, param, initialVal); |
| 257 | 257 | } |
| r26109 | r26110 | |
| 260 | 260 | // net_net_t |
| 261 | 261 | // ---------------------------------------------------------------------------------------- |
| 262 | 262 | |
| 263 | | ATTR_COLD net_net_t::net_net_t(const int atype) |
| 264 | | : net_object_t(atype) |
| 265 | | #if USE_LINKED_LIST |
| 263 | ATTR_COLD netlist_net_t::netlist_net_t(const type_t atype, const family_t afamily) |
| 264 | : netlist_object_t(atype, afamily) |
| 266 | 265 | , m_head(NULL) |
| 267 | | #endif |
| 268 | 266 | , m_num_cons(0) |
| 269 | 267 | , m_time(netlist_time::zero) |
| 270 | 268 | , m_active(0) |
| 271 | 269 | , m_in_queue(2) |
| 272 | | , m_raildev(NULL) |
| 270 | , m_railterminal(NULL) |
| 273 | 271 | { |
| 274 | 272 | m_cur.Q = 0; |
| 275 | 273 | m_new.Q = 0; |
| 276 | 274 | m_last.Q = 0; |
| 277 | 275 | }; |
| 278 | 276 | |
| 279 | | ATTR_COLD void net_net_t::register_con(net_input_t &input) |
| 277 | ATTR_COLD void netlist_net_t::register_con(netlist_terminal_t &terminal) |
| 280 | 278 | { |
| 281 | | input.set_net(*this); |
| 282 | | #if USE_LINKED_LIST |
| 279 | terminal.set_net(*this); |
| 283 | 280 | if (m_head == NULL) |
| 284 | | m_head = &input; |
| 281 | m_head = &terminal; |
| 285 | 282 | else |
| 286 | 283 | { |
| 287 | | input.m_next = m_head; |
| 288 | | m_head = &input; |
| 284 | terminal.m_update_list_next = m_head; |
| 285 | m_head = &terminal; |
| 289 | 286 | } |
| 290 | | #else |
| 291 | | if (m_num_cons >= OUTPUT_MAX_CONNECTIONS) |
| 292 | | fatalerror("Connections exceeded for %s\n", netdev()->name().cstr()); |
| 293 | | |
| 294 | | #if 0 |
| 295 | | int i; |
| 296 | | /* keep similar devices together */ |
| 297 | | for (i = 0; i < m_num_cons; i++) |
| 298 | | if (m_cons[i]->netdev() == input.netdev()) |
| 299 | | break; |
| 300 | | |
| 301 | | for (int j = m_num_cons; j > i; j--) |
| 302 | | m_cons[j] = m_cons[j - 1]; |
| 303 | | |
| 304 | | m_cons[i] = &input; |
| 305 | | #else |
| 306 | | m_cons[m_num_cons] = &input; |
| 307 | | #endif |
| 308 | | #endif |
| 309 | 287 | m_num_cons++; |
| 310 | | if (input.state() != net_input_t::INP_STATE_PASSIVE) |
| 288 | |
| 289 | if (terminal.state() != netlist_input_t::INP_STATE_PASSIVE) |
| 311 | 290 | m_active++; |
| 312 | 291 | } |
| 313 | 292 | |
| 314 | | ATTR_HOT inline void net_net_t::update_dev(const net_input_t *inp, const UINT32 mask) |
| 293 | ATTR_HOT inline void netlist_net_t::update_dev(const netlist_terminal_t *inp, const UINT32 mask) |
| 315 | 294 | { |
| 316 | 295 | if ((inp->state() & mask) != 0) |
| 317 | 296 | { |
| 318 | | ATTR_UNUSED netlist_core_device_t *netdev = inp->netdev(); |
| 319 | | begin_timing(netdev->total_time); |
| 320 | | inc_stat(netdev->stat_count); |
| 321 | | netdev->update_dev(); |
| 322 | | end_timing(netdev()->total_time); |
| 297 | netlist_core_device_t &netdev = inp->netdev(); |
| 298 | begin_timing(netdev.total_time); |
| 299 | inc_stat(netdev.stat_count); |
| 300 | netdev.update_dev(); |
| 301 | end_timing(netdev().total_time); |
| 323 | 302 | } |
| 324 | 303 | } |
| 325 | 304 | |
| 326 | | ATTR_HOT inline void net_net_t::update_devs() |
| 305 | ATTR_HOT inline void netlist_net_t::update_devs() |
| 327 | 306 | { |
| 328 | 307 | assert(m_num_cons != 0); |
| 329 | 308 | |
| r26109 | r26110 | |
| 333 | 312 | |
| 334 | 313 | const UINT32 mask = masks[ (m_last.Q << 1) | m_cur.Q ]; |
| 335 | 314 | |
| 336 | | #if USE_LINKED_LIST |
| 337 | | net_input_t *p = m_head; |
| 315 | netlist_terminal_t *p = m_head; |
| 338 | 316 | switch (m_num_cons) |
| 339 | 317 | { |
| 340 | 318 | case 2: |
| 341 | 319 | update_dev(p, mask); |
| 342 | | p = p->m_next; |
| 320 | p = p->m_update_list_next; |
| 343 | 321 | case 1: |
| 344 | 322 | update_dev(p, mask); |
| 345 | 323 | break; |
| r26109 | r26110 | |
| 347 | 325 | do |
| 348 | 326 | { |
| 349 | 327 | update_dev(p, mask); |
| 350 | | p = p->m_next; |
| 328 | p = p->m_update_list_next; |
| 351 | 329 | } while (p != NULL); |
| 352 | 330 | break; |
| 353 | 331 | } |
| 354 | | |
| 355 | | #else |
| 356 | | switch (m_num_cons) |
| 357 | | { |
| 358 | | case 2: |
| 359 | | update_dev(m_cons[1], mask); |
| 360 | | case 1: |
| 361 | | update_dev(m_cons[0], mask); |
| 362 | | break; |
| 363 | | default: |
| 364 | | { |
| 365 | | for (int i=0; i < m_num_cons; i++) |
| 366 | | update_dev(m_cons[i], mask); |
| 367 | | } |
| 368 | | break; |
| 369 | | } |
| 370 | | #endif |
| 371 | 332 | m_last = m_cur; |
| 372 | 333 | } |
| 373 | 334 | |
| 374 | 335 | // ---------------------------------------------------------------------------------------- |
| 375 | | // net_terminal_t |
| 336 | // netlist_terminal_t |
| 376 | 337 | // ---------------------------------------------------------------------------------------- |
| 377 | 338 | |
| 378 | | ATTR_COLD void net_terminal_t::init_terminal(netlist_core_device_t &dev) |
| 339 | ATTR_COLD void netlist_terminal_t::init_terminal(netlist_core_device_t &dev) |
| 379 | 340 | { |
| 380 | 341 | m_netdev = &dev; |
| 381 | | init_object(*dev.netlist()); |
| 342 | init_object(dev.netlist()); |
| 382 | 343 | } |
| 383 | 344 | |
| 384 | 345 | // ---------------------------------------------------------------------------------------- |
| 385 | 346 | // net_input_t |
| 386 | 347 | // ---------------------------------------------------------------------------------------- |
| 387 | 348 | |
| 388 | | ATTR_COLD void net_input_t::init_input(netlist_core_device_t &dev, net_input_state astate) |
| 349 | ATTR_COLD void netlist_input_t::init_input(netlist_core_device_t &dev, net_input_state astate) |
| 389 | 350 | { |
| 390 | 351 | init_terminal(dev); |
| 391 | | m_state = astate; |
| 352 | set_state(astate); |
| 392 | 353 | } |
| 393 | 354 | |
| 394 | 355 | // ---------------------------------------------------------------------------------------- |
| 395 | 356 | // net_output_t |
| 396 | 357 | // ---------------------------------------------------------------------------------------- |
| 397 | 358 | |
| 398 | | net_output_t::net_output_t(int atype) |
| 399 | | : net_terminal_t(atype) |
| 359 | netlist_output_t::netlist_output_t(const type_t atype, const family_t afamily) |
| 360 | : netlist_terminal_t(atype, afamily) |
| 400 | 361 | , m_low_V(0.0) |
| 401 | 362 | , m_high_V(0.0) |
| 402 | | , m_my_net(NET_DIGITAL) |
| 363 | , m_my_net(NET, afamily) |
| 403 | 364 | { |
| 404 | 365 | //m_net = new net_net_t(NET_DIGITAL); |
| 405 | 366 | this->set_net(m_my_net); |
| 406 | 367 | } |
| 407 | 368 | |
| 408 | | ATTR_COLD void net_output_t::init_terminal(netlist_core_device_t &dev) |
| 369 | ATTR_COLD void netlist_output_t::init_terminal(netlist_core_device_t &dev) |
| 409 | 370 | { |
| 410 | | net_terminal_t::init_terminal(dev); |
| 411 | | net().init_object(*dev.netlist()); |
| 412 | | net().register_raildev(dev); |
| 371 | netlist_terminal_t::init_terminal(dev); |
| 372 | net().init_object(dev.netlist()); |
| 373 | net().register_railterminal(*this); |
| 413 | 374 | } |
| 414 | 375 | |
| 415 | | ATTR_COLD void logic_output_t::initial(const netlist_sig_t val) |
| 376 | ATTR_COLD void netlist_logic_output_t::initial(const netlist_sig_t val) |
| 416 | 377 | { |
| 417 | 378 | net().m_cur.Q = val; |
| 418 | 379 | net().m_new.Q = val; |
| 419 | 380 | net().m_last.Q = !val; |
| 420 | 381 | } |
| 421 | 382 | |
| 422 | | ATTR_COLD logic_output_t::logic_output_t() |
| 423 | | : net_output_t(OUTPUT | SIGNAL_DIGITAL) |
| 383 | ATTR_COLD netlist_logic_output_t::netlist_logic_output_t() |
| 384 | : netlist_output_t(OUTPUT, LOGIC) |
| 424 | 385 | { |
| 425 | 386 | // Default to TTL |
| 426 | 387 | m_low_V = 0.1; // these depend on sinked/sourced current. Values should be suitable for typical applications. |
| 427 | 388 | m_high_V = 4.8; |
| 428 | 389 | } |
| 429 | 390 | |
| 430 | | ATTR_COLD void logic_output_t::set_levels(const double low, const double high) |
| 391 | ATTR_COLD void netlist_logic_output_t::set_levels(const double low, const double high) |
| 431 | 392 | { |
| 432 | 393 | m_low_V = low; |
| 433 | 394 | m_high_V = high; |
| r26109 | r26110 | |
| 435 | 396 | |
| 436 | 397 | |
| 437 | 398 | // ---------------------------------------------------------------------------------------- |
| 438 | | // netdev_mainclock |
| 399 | // mainclock |
| 439 | 400 | // ---------------------------------------------------------------------------------------- |
| 440 | 401 | |
| 441 | | ATTR_HOT inline void NETLIB_NAME(netdev_mainclock)::mc_update(net_net_t &net, const netlist_time curtime) |
| 402 | ATTR_HOT inline void NETLIB_NAME(mainclock)::mc_update(netlist_net_t &net, const netlist_time curtime) |
| 442 | 403 | { |
| 443 | 404 | net.m_new.Q = !net.m_new.Q; |
| 444 | 405 | net.set_time(curtime); |
| 445 | 406 | net.update_devs(); |
| 446 | 407 | } |
| 447 | 408 | |
| 448 | | ATTR_COLD NETLIB_START(netdev_mainclock) |
| 409 | ATTR_COLD NETLIB_START(mainclock) |
| 449 | 410 | { |
| 450 | 411 | register_output("Q", m_Q); |
| 451 | 412 | |
| r26109 | r26110 | |
| 454 | 415 | |
| 455 | 416 | } |
| 456 | 417 | |
| 457 | | ATTR_HOT NETLIB_UPDATE_PARAM(netdev_mainclock) |
| 418 | ATTR_HOT NETLIB_UPDATE_PARAM(mainclock) |
| 458 | 419 | { |
| 459 | 420 | m_inc = netlist_time::from_hz(m_freq.Value()*2); |
| 460 | 421 | } |
| 461 | 422 | |
| 462 | | ATTR_HOT NETLIB_UPDATE(netdev_mainclock) |
| 423 | ATTR_HOT NETLIB_UPDATE(mainclock) |
| 463 | 424 | { |
| 464 | | net_net_t &net = m_Q.net(); |
| 425 | netlist_net_t &net = m_Q.net(); |
| 465 | 426 | // this is only called during setup ... |
| 466 | 427 | net.m_new.Q = !net.m_new.Q; |
| 467 | | net.set_time(netlist()->time() + m_inc); |
| 428 | net.set_time(netlist().time() + m_inc); |
| 468 | 429 | } |
trunk/src/emu/netlist/nl_base.h
| r26109 | r26110 | |
| 3 | 3 | /* |
| 4 | 4 | * nlbase.h |
| 5 | 5 | * |
| 6 | * A mixed signal circuit simulation |
| 7 | * |
| 8 | * D: Device |
| 9 | * O: Rail output (output) |
| 10 | * I: Infinite impedance input (input) |
| 11 | * T: Terminal (finite impedance) |
| 12 | * |
| 13 | * +---+ +---+ +---+ +---+ +---+ |
| 14 | * | | | | | | | | | | |
| 15 | * | D | | D | | D | | D | | D | |
| 16 | * | | | | | | | | | | |
| 17 | * +-O-+ +-I-+ +-I-+ +-T-+ +-T-+ |
| 18 | * | | | | | |
| 19 | * +-+---------+---------+---------+---------+-+ |
| 20 | * | rail net | |
| 21 | * +-------------------------------------------+ |
| 22 | * |
| 23 | * A rail net is a net which is driven by exactly one output with an (idealized) internal resistance |
| 24 | * of zero. Ideally, it can deliver infinite current. |
| 25 | * |
| 26 | * A infinite resistance input does not source or sink current. |
| 27 | * |
| 28 | * Terminals source or sink finite (but never zero) current. |
| 29 | * |
| 30 | * The system differentiates between analog and logic input and outputs and analog terminals. |
| 31 | * Analog and logic devices can not be connected to the same net. Instead, proxy devices |
| 32 | * are inserted automatically: |
| 33 | * |
| 34 | * +---+ +---+ |
| 35 | * | | | | |
| 36 | * | D1| | D2| |
| 37 | * | A | | L | |
| 38 | * +-O-+ +-I-+ |
| 39 | * | | |
| 40 | * +-+---------+---+ |
| 41 | * | rail net | |
| 42 | * +---------------+ |
| 43 | * |
| 44 | * is converted into |
| 45 | * +----------+ |
| 46 | * | | |
| 47 | * +---+ +-+-+ | +---+ |
| 48 | * | | | L | A-L | | | |
| 49 | * | D1| | D | Proxy | | D2| |
| 50 | * | A | | A | | | | |
| 51 | * +-O-+ +-I-+ | +-I-+ |
| 52 | * | | | | |
| 53 | * +-+---------+--+ +-+-----+-------+ |
| 54 | * | rail net (A) | | rail net (L) | |
| 55 | * +--------------| +---------------+ |
| 56 | * |
| 57 | * This works both analog to logic as well as logic to analog. |
| 58 | * |
| 59 | * The above is an advanced implementation of the existing discrete |
| 60 | * subsystem in MAME. Instead of relying on a fixed time-step, analog devices could |
| 61 | * either connect to fixed time-step clock or use an internal clock to update them. |
| 62 | * This would however introduce macro devices for RC, diodes and transistors again. |
| 63 | * |
| 64 | * ==================================================================================== |
| 65 | * FIXME: Terminals are not yet implemented. |
| 66 | * |
| 67 | * Instead, the following approach in case of a pure terminal/input network is taken: |
| 68 | * |
| 69 | * +---+ +---+ +---+ +---+ +---+ |
| 70 | * | | | | | | | | | | |
| 71 | * | D | | D | | D | | D | | D | |
| 72 | * | | | | | | | | | | |
| 73 | * +-T-+ +-I-+ +-I-+ +-T-+ +-T-+ |
| 74 | * | | | | | |
| 75 | * '+' | | '-' '-' |
| 76 | * +-+---------+---------+---------+---------+-+ |
| 77 | * | Calculated net | |
| 78 | * +-------------------------------------------+ |
| 79 | * |
| 80 | * SPICE uses the following basic two terminal device: |
| 81 | * |
| 82 | * (k) |
| 83 | * +-----T-----+ |
| 84 | * | | | |
| 85 | * | +--+--+ | |
| 86 | * | | | | |
| 87 | * | R | | |
| 88 | * | R | | |
| 89 | * | R I | |
| 90 | * | | I | Device n |
| 91 | * | V+ I | |
| 92 | * | V | | |
| 93 | * | V- | | |
| 94 | * | | | | |
| 95 | * | +--+--+ | |
| 96 | * | | | |
| 97 | * +-----T-----+ |
| 98 | * (l) |
| 99 | * |
| 100 | * This is a resistance in series to a voltage source and paralleled by a current source. |
| 101 | * This is suitable to model voltage sources, current sources, resistors, capacitors, |
| 102 | * inductances and diodes. |
| 103 | * |
| 104 | * I(n,l) = - I(n,k) = ( V(k) - V - V(l) ) * (1/R(n)) + I(n) |
| 105 | * |
| 106 | * Now, the sum of all currents for a given net must be 0: |
| 107 | * |
| 108 | * Sum(n,I(n,l)) = 0 = sum(n, ( V(k) - V(n) - V(l) ) * (1/R(n)) + I(n) ) |
| 109 | * |
| 110 | * With G(n) = 1 / R(n) and sum(n, G(n)) = Gtot and k=k(n) |
| 111 | * |
| 112 | * 0 = - V(l) * Gtot + sum(n, (V(k(n)) - V(n)) * G(n) + I(n)) |
| 113 | * |
| 114 | * and with l=l(n) and fixed k |
| 115 | * |
| 116 | * 0 = -V(k) * Gtot + sum(n, ( V(l(n) + V(n) ) * G(n) - I(n)) |
| 117 | * |
| 118 | * These equations represent a linear Matrix equation (with more math). |
| 119 | * |
| 120 | * In the context of this exercise, in a first step, we will not solve it. Instead, |
| 121 | * we calculate the net voltage V(l) by using a mirror of the above device on each terminal. |
| 122 | * |
| 123 | * Each terminal thus has three properties: |
| 124 | * |
| 125 | * a) Resistance |
| 126 | * b) Voltage source |
| 127 | * c) Current source/sink |
| 128 | * |
| 129 | * Going forward, approach can be extended to use a linear equation solver. |
| 130 | * |
| 131 | * The formal representation of the circuit will stay the same, thus scales. |
| 132 | * |
| 6 | 133 | */ |
| 7 | 134 | |
| 8 | 135 | #ifndef NLBASE_H_ |
| r26109 | r26110 | |
| 44 | 171 | #define NETLIB_FUNC_VOID(_chip, _name, _params) ATTR_HOT ATTR_ALIGN inline void NETLIB_NAME(_chip) :: _name _params |
| 45 | 172 | |
| 46 | 173 | #define NETLIB_DEVICE(_name, _priv) \ |
| 47 | | class NETLIB_NAME(_name) : public net_device_t \ |
| 174 | class NETLIB_NAME(_name) : public netlist_device_t \ |
| 48 | 175 | { \ |
| 49 | 176 | public: \ |
| 50 | 177 | NETLIB_NAME(_name) () \ |
| 51 | | : net_device_t() { } \ |
| 178 | : netlist_device_t() { } \ |
| 52 | 179 | protected: \ |
| 53 | 180 | ATTR_HOT void update(); \ |
| 54 | 181 | ATTR_HOT void start(); \ |
| r26109 | r26110 | |
| 68 | 195 | } |
| 69 | 196 | |
| 70 | 197 | #define NETLIB_DEVICE_WITH_PARAMS(_name, _priv) \ |
| 71 | | class NETLIB_NAME(_name) : public net_device_t \ |
| 198 | class NETLIB_NAME(_name) : public netlist_device_t \ |
| 72 | 199 | { \ |
| 73 | 200 | public: \ |
| 74 | 201 | NETLIB_NAME(_name) () \ |
| 75 | | : net_device_t() { } \ |
| 202 | : netlist_device_t() { } \ |
| 76 | 203 | ATTR_HOT void update_param(); \ |
| 77 | 204 | ATTR_HOT void update(); \ |
| 78 | 205 | ATTR_HOT void start(); \ |
| r26109 | r26110 | |
| 84 | 211 | // forward definitions |
| 85 | 212 | // ---------------------------------------------------------------------------------------- |
| 86 | 213 | |
| 87 | | class net_net_t; |
| 88 | | class net_output_t; |
| 89 | | class net_param_t; |
| 214 | class netlist_net_t; |
| 215 | class netlist_output_t; |
| 216 | class netlist_param_t; |
| 90 | 217 | class netlist_setup_t; |
| 91 | 218 | class netlist_base_t; |
| 92 | 219 | |
| r26109 | r26110 | |
| 95 | 222 | // net_object_t |
| 96 | 223 | // ---------------------------------------------------------------------------------------- |
| 97 | 224 | |
| 98 | | class net_object_t |
| 225 | class netlist_object_t |
| 99 | 226 | { |
| 100 | 227 | public: |
| 101 | 228 | enum type_t { |
| 102 | | INPUT = 0, |
| 103 | | OUTPUT = 1, |
| 104 | | DEVICE = 2, |
| 105 | | PARAM = 3, |
| 106 | | TERMINAL = 4, |
| 107 | | NET_ANALOG = 5, |
| 108 | | NET_DIGITAL = 6, |
| 109 | | TYPE_MASK = 0x0f, |
| 110 | | SIGNAL_DIGITAL = 0x00, |
| 111 | | SIGNAL_ANALOG = 0x10, |
| 112 | | SIGNAL_MASK = 0x10, |
| 229 | TERMINAL = 0, |
| 230 | INPUT = 1, |
| 231 | OUTPUT = 2, |
| 232 | DEVICE = 3, |
| 233 | PARAM = 4, |
| 234 | NET = 5 |
| 113 | 235 | }; |
| 236 | enum family_t { |
| 237 | LOGIC = 1, |
| 238 | ANALOG = 2, |
| 239 | CURRENT = 3, |
| 240 | ALL = 4 // <== devices usually fall into this category |
| 241 | }; |
| 114 | 242 | |
| 115 | | net_object_t(const int atype) |
| 116 | | : m_objtype(atype) {} |
| 243 | ATTR_COLD netlist_object_t(const type_t atype, const family_t afamily) |
| 244 | : m_objtype(atype) |
| 245 | , m_family(afamily) |
| 246 | , m_netlist(NULL) |
| 247 | {} |
| 117 | 248 | |
| 118 | | virtual ~net_object_t() {} |
| 249 | virtual ~netlist_object_t() {} |
| 119 | 250 | |
| 120 | 251 | ATTR_COLD void init_object(netlist_base_t &nl) |
| 121 | 252 | { |
| 122 | 253 | m_netlist = &nl; |
| 123 | 254 | } |
| 124 | 255 | |
| 125 | | ATTR_HOT inline int object_type() const { return m_objtype; } |
| 126 | | ATTR_HOT inline int object_type(const UINT32 mask) const { return m_objtype & mask; } |
| 256 | ATTR_HOT inline const type_t object_type() const { return m_objtype; } |
| 257 | ATTR_HOT inline const family_t family() const { return m_family; } |
| 127 | 258 | |
| 128 | | ATTR_HOT inline netlist_base_t * RESTRICT netlist() { return m_netlist; } |
| 129 | | ATTR_HOT inline const netlist_base_t * RESTRICT netlist() const { return m_netlist; } |
| 259 | ATTR_HOT inline const bool isType(const type_t atype) const { return (m_objtype == atype); } |
| 260 | ATTR_HOT inline const bool isFamily(const family_t afamily) const { return (m_family == afamily); } |
| 130 | 261 | |
| 262 | ATTR_HOT inline netlist_base_t & RESTRICT netlist() { return *m_netlist; } |
| 263 | ATTR_HOT inline const netlist_base_t & RESTRICT netlist() const { return *m_netlist; } |
| 264 | |
| 131 | 265 | private: |
| 132 | | const int m_objtype; |
| 266 | const type_t m_objtype; |
| 267 | const family_t m_family; |
| 133 | 268 | netlist_base_t * RESTRICT m_netlist; |
| 134 | 269 | }; |
| 135 | 270 | |
| r26109 | r26110 | |
| 137 | 272 | // net_terminal_t |
| 138 | 273 | // ---------------------------------------------------------------------------------------- |
| 139 | 274 | |
| 140 | | class net_terminal_t : public net_object_t |
| 275 | class netlist_terminal_t : public netlist_object_t |
| 141 | 276 | { |
| 142 | 277 | public: |
| 143 | 278 | |
| 144 | | net_terminal_t(const int atype) |
| 145 | | : net_object_t(atype) |
| 279 | /* needed here ... */ |
| 280 | |
| 281 | enum net_input_state { |
| 282 | INP_STATE_PASSIVE = 0, |
| 283 | INP_STATE_ACTIVE = 1, |
| 284 | INP_STATE_HL = 2, |
| 285 | INP_STATE_LH = 4, |
| 286 | }; |
| 287 | |
| 288 | ATTR_COLD netlist_terminal_t(const type_t atype, const family_t afamily) |
| 289 | : netlist_object_t(atype, afamily) |
| 290 | , m_update_list_next(NULL) |
| 146 | 291 | , m_netdev(NULL) |
| 147 | 292 | , m_net(NULL) |
| 293 | , m_state(INP_STATE_ACTIVE) |
| 148 | 294 | {} |
| 149 | 295 | |
| 150 | 296 | ATTR_COLD virtual void init_terminal(netlist_core_device_t &dev); |
| 151 | 297 | |
| 152 | | ATTR_COLD void set_net(net_net_t &anet) { m_net = &anet; } |
| 298 | ATTR_COLD void set_net(netlist_net_t &anet) { m_net = &anet; } |
| 153 | 299 | |
| 154 | | ATTR_HOT inline const net_net_t & RESTRICT net() const { return *m_net;} |
| 155 | | ATTR_HOT inline net_net_t & RESTRICT net() { return *m_net;} |
| 300 | ATTR_HOT inline const netlist_net_t & RESTRICT net() const { return *m_net;} |
| 301 | ATTR_HOT inline netlist_net_t & RESTRICT net() { return *m_net;} |
| 156 | 302 | |
| 157 | | ATTR_HOT inline netlist_core_device_t * RESTRICT netdev() const { return m_netdev; } |
| 303 | ATTR_HOT inline const bool is_state(const net_input_state astate) const { return (m_state == astate); } |
| 304 | ATTR_HOT inline const net_input_state state() const { return m_state; } |
| 305 | ATTR_HOT inline void set_state(const net_input_state astate) { m_state = astate; } |
| 158 | 306 | |
| 307 | ATTR_HOT inline netlist_core_device_t & RESTRICT netdev() const { return *m_netdev; } |
| 308 | |
| 309 | netlist_terminal_t *m_update_list_next; |
| 310 | |
| 159 | 311 | private: |
| 160 | 312 | netlist_core_device_t * RESTRICT m_netdev; |
| 161 | | net_net_t * RESTRICT m_net; |
| 313 | netlist_net_t * RESTRICT m_net; |
| 314 | net_input_state m_state; |
| 162 | 315 | }; |
| 163 | 316 | |
| 164 | 317 | |
| 165 | 318 | // ---------------------------------------------------------------------------------------- |
| 166 | | // net_input_t |
| 319 | // netlist_input_t |
| 167 | 320 | // ---------------------------------------------------------------------------------------- |
| 168 | 321 | |
| 169 | | class net_input_t : public net_terminal_t |
| 322 | class netlist_input_t : public netlist_terminal_t |
| 170 | 323 | { |
| 171 | 324 | public: |
| 172 | 325 | |
| 173 | | enum net_input_state { |
| 174 | | INP_STATE_PASSIVE = 0, |
| 175 | | INP_STATE_ACTIVE = 1, |
| 176 | | INP_STATE_HL = 2, |
| 177 | | INP_STATE_LH = 4, |
| 178 | | }; |
| 179 | 326 | |
| 180 | | ATTR_COLD net_input_t(const int atype) |
| 181 | | : net_terminal_t(atype) |
| 327 | ATTR_COLD netlist_input_t(const type_t atype, const family_t afamily) |
| 328 | : netlist_terminal_t(atype, afamily) |
| 182 | 329 | , m_low_thresh_V(0) |
| 183 | 330 | , m_high_thresh_V(0) |
| 184 | | #if USE_LINKED_LIST |
| 185 | | , m_next(NULL) |
| 186 | | #endif |
| 187 | | , m_state(INP_STATE_ACTIVE) |
| 188 | 331 | {} |
| 189 | 332 | |
| 190 | 333 | ATTR_COLD void init_input(netlist_core_device_t &dev, net_input_state astate = INP_STATE_ACTIVE); |
| 191 | 334 | |
| 192 | | ATTR_HOT inline const bool is_state(const net_input_state astate) const { return (m_state == astate); } |
| 193 | | ATTR_HOT inline const net_input_state state() const { return m_state; } |
| 194 | | |
| 195 | 335 | ATTR_HOT inline void inactivate(); |
| 196 | 336 | ATTR_HOT inline void activate(); |
| 197 | 337 | ATTR_HOT inline void activate_hl(); |
| r26109 | r26110 | |
| 200 | 340 | double m_low_thresh_V; |
| 201 | 341 | double m_high_thresh_V; |
| 202 | 342 | |
| 203 | | #if USE_LINKED_LIST |
| 204 | | net_input_t *m_next; |
| 205 | | #endif |
| 206 | | |
| 207 | 343 | private: |
| 208 | | net_input_state m_state; |
| 209 | 344 | }; |
| 210 | 345 | |
| 211 | 346 | // ---------------------------------------------------------------------------------------- |
| 212 | | // logic_input_t |
| 347 | // netlist_logic_input_t |
| 213 | 348 | // ---------------------------------------------------------------------------------------- |
| 214 | 349 | |
| 215 | | class logic_input_t : public net_input_t |
| 350 | class netlist_logic_input_t : public netlist_input_t |
| 216 | 351 | { |
| 217 | 352 | public: |
| 218 | | logic_input_t() |
| 219 | | : net_input_t(INPUT | SIGNAL_DIGITAL) |
| 353 | netlist_logic_input_t() |
| 354 | : netlist_input_t(INPUT, LOGIC) |
| 220 | 355 | { |
| 221 | 356 | // default to TTL |
| 222 | 357 | m_low_thresh_V = 0.8; |
| r26109 | r26110 | |
| 234 | 369 | }; |
| 235 | 370 | |
| 236 | 371 | // ---------------------------------------------------------------------------------------- |
| 237 | | // ttl_input_t |
| 372 | // netlist_ttl_input_t |
| 238 | 373 | // ---------------------------------------------------------------------------------------- |
| 239 | 374 | |
| 240 | | class ttl_input_t : public logic_input_t |
| 375 | class netlist_ttl_input_t : public netlist_logic_input_t |
| 241 | 376 | { |
| 242 | 377 | public: |
| 243 | | ttl_input_t() |
| 244 | | : logic_input_t() { set_thresholds(0.8 , 2.0); } |
| 378 | netlist_ttl_input_t() |
| 379 | : netlist_logic_input_t() { set_thresholds(0.8 , 2.0); } |
| 245 | 380 | }; |
| 246 | 381 | |
| 247 | | class analog_input_t : public net_input_t |
| 382 | // ---------------------------------------------------------------------------------------- |
| 383 | // netlist_analog_input_t |
| 384 | // ---------------------------------------------------------------------------------------- |
| 385 | |
| 386 | class netlist_analog_input_t : public netlist_input_t |
| 248 | 387 | { |
| 249 | 388 | public: |
| 250 | | analog_input_t() |
| 251 | | : net_input_t(INPUT | SIGNAL_ANALOG) { } |
| 389 | netlist_analog_input_t() |
| 390 | : netlist_input_t(INPUT, ANALOG) { } |
| 252 | 391 | |
| 253 | 392 | ATTR_HOT inline const bool is_highz() const; |
| 254 | 393 | ATTR_HOT inline const double Q_Analog() const; |
| r26109 | r26110 | |
| 260 | 399 | // net_net_t |
| 261 | 400 | // ---------------------------------------------------------------------------------------- |
| 262 | 401 | |
| 263 | | class net_net_t : public net_object_t |
| 402 | class netlist_net_t : public netlist_object_t |
| 264 | 403 | { |
| 265 | 404 | public: |
| 266 | 405 | |
| 267 | | friend class NETLIB_NAME(netdev_mainclock); |
| 268 | | friend class net_output_t; |
| 269 | | friend class net_input_t; |
| 270 | | friend class logic_output_t; |
| 271 | | friend class analog_output_t; |
| 272 | | friend class logic_input_t; |
| 273 | | friend class analog_input_t; |
| 406 | friend class NETLIB_NAME(mainclock); |
| 407 | friend class netlist_output_t; |
| 408 | friend class netlist_input_t; |
| 409 | friend class netlist_logic_output_t; |
| 410 | friend class netlist_analog_output_t; |
| 411 | friend class netlist_logic_input_t; |
| 412 | friend class netlist_analog_input_t; |
| 274 | 413 | |
| 275 | 414 | // FIXME: union does not work |
| 276 | 415 | typedef struct |
| r26109 | r26110 | |
| 279 | 418 | double Analog; |
| 280 | 419 | } hybrid_t; |
| 281 | 420 | |
| 282 | | ATTR_COLD net_net_t(const int atype); |
| 421 | ATTR_COLD netlist_net_t(const type_t atype, const family_t afamily); |
| 283 | 422 | |
| 284 | | ATTR_COLD void register_con(net_input_t &inp); |
| 285 | | ATTR_COLD void register_raildev(netlist_core_device_t &mr) |
| 423 | ATTR_COLD void register_con(netlist_terminal_t &terminal); |
| 424 | ATTR_COLD void register_railterminal(netlist_terminal_t &mr) |
| 286 | 425 | { |
| 287 | | assert(m_raildev == NULL); |
| 288 | | m_raildev = &mr; |
| 426 | assert(m_railterminal == NULL); |
| 427 | m_railterminal = &mr; |
| 289 | 428 | } |
| 290 | 429 | |
| 291 | | ATTR_HOT inline bool isRailNet() { return m_raildev == NULL; } |
| 292 | | |
| 293 | 430 | /* inline not always works out */ |
| 294 | | ATTR_HOT /*inline*/ void update_devs(); |
| 431 | ATTR_HOT inline void update_devs(); |
| 295 | 432 | |
| 433 | ATTR_HOT inline const netlist_time time() const { return m_time; } |
| 434 | ATTR_HOT inline void set_time(const netlist_time ntime) { m_time = ntime; } |
| 435 | |
| 436 | ATTR_HOT inline bool isRailNet() { return !(m_railterminal == NULL); } |
| 437 | ATTR_HOT inline const netlist_terminal_t & RESTRICT railterminal() const { return *m_railterminal; } |
| 438 | ATTR_HOT inline netlist_terminal_t & RESTRICT railterminal() { return *m_railterminal; } |
| 439 | |
| 296 | 440 | /* Everything below is used by the logic subsystem */ |
| 297 | 441 | |
| 298 | 442 | ATTR_HOT inline void inc_active(); |
| 299 | 443 | ATTR_HOT inline void dec_active(); |
| 300 | 444 | |
| 301 | 445 | ATTR_HOT inline const int active_count() const { return m_active; } |
| 302 | | ATTR_HOT inline const netlist_time time() const { return m_time; } |
| 303 | | ATTR_HOT inline void set_time(const netlist_time ntime) { m_time = ntime; } |
| 304 | 446 | |
| 305 | 447 | ATTR_HOT inline const netlist_sig_t last_Q() const { return m_last.Q; } |
| 306 | 448 | ATTR_HOT inline const netlist_sig_t new_Q() const { return m_new.Q; } |
| 307 | 449 | |
| 308 | | ATTR_HOT inline const netlist_core_device_t * RESTRICT raildev() const { return m_raildev; } |
| 309 | | ATTR_HOT inline netlist_core_device_t * RESTRICT raildev() { return m_raildev; } |
| 310 | | |
| 311 | 450 | protected: |
| 312 | 451 | |
| 313 | 452 | /* prohibit use in device functions |
| r26109 | r26110 | |
| 324 | 463 | return m_cur.Analog; |
| 325 | 464 | } |
| 326 | 465 | |
| 327 | | |
| 328 | 466 | ATTR_HOT inline void push_to_queue(const netlist_time &delay); |
| 329 | 467 | |
| 330 | 468 | hybrid_t m_last; |
| 331 | 469 | hybrid_t m_cur; |
| 332 | 470 | hybrid_t m_new; |
| 333 | 471 | |
| 334 | | #if USE_LINKED_LIST |
| 335 | | net_input_t *m_head; |
| 336 | | #endif |
| 472 | netlist_terminal_t *m_head; |
| 337 | 473 | UINT32 m_num_cons; |
| 338 | 474 | |
| 339 | 475 | private: |
| 340 | | ATTR_HOT void update_dev(const net_input_t *inp, const UINT32 mask); |
| 476 | ATTR_HOT void update_dev(const netlist_terminal_t *inp, const UINT32 mask); |
| 341 | 477 | |
| 342 | 478 | netlist_time m_time; |
| 343 | 479 | INT32 m_active; |
| 344 | 480 | UINT32 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ |
| 345 | 481 | |
| 346 | | #if !USE_LINKED_LIST |
| 347 | | net_input_t * RESTRICT m_cons[OUTPUT_MAX_CONNECTIONS]; |
| 348 | | #endif |
| 349 | | netlist_core_device_t * RESTRICT m_raildev; |
| 482 | netlist_terminal_t * RESTRICT m_railterminal; |
| 350 | 483 | }; |
| 351 | 484 | |
| 352 | 485 | |
| r26109 | r26110 | |
| 354 | 487 | // net_output_t |
| 355 | 488 | // ---------------------------------------------------------------------------------------- |
| 356 | 489 | |
| 357 | | class NETLIB_NAME(netdev_mainclock); |
| 490 | class NETLIB_NAME(mainclock); |
| 358 | 491 | |
| 359 | | class net_output_t : public net_terminal_t |
| 492 | class netlist_output_t : public netlist_terminal_t |
| 360 | 493 | { |
| 361 | 494 | public: |
| 362 | 495 | |
| 363 | | net_output_t(int atype); |
| 496 | netlist_output_t(const type_t atype, const family_t afamily); |
| 364 | 497 | |
| 365 | 498 | ATTR_COLD virtual void init_terminal(netlist_core_device_t &dev); |
| 366 | 499 | |
| r26109 | r26110 | |
| 370 | 503 | protected: |
| 371 | 504 | |
| 372 | 505 | private: |
| 373 | | net_net_t m_my_net; |
| 506 | netlist_net_t m_my_net; |
| 374 | 507 | }; |
| 375 | 508 | |
| 376 | 509 | |
| 377 | | class logic_output_t : public net_output_t |
| 510 | class netlist_logic_output_t : public netlist_output_t |
| 378 | 511 | { |
| 379 | 512 | public: |
| 380 | 513 | |
| 381 | | ATTR_COLD logic_output_t(); |
| 514 | ATTR_COLD netlist_logic_output_t(); |
| 382 | 515 | |
| 383 | 516 | ATTR_COLD void initial(const netlist_sig_t val); |
| 384 | 517 | ATTR_COLD void set_levels(const double low, const double high); |
| 385 | 518 | |
| 386 | 519 | ATTR_HOT inline void set_Q(const netlist_sig_t newQ, const netlist_time &delay) |
| 387 | 520 | { |
| 388 | | net_net_t &anet = net(); |
| 521 | netlist_net_t &anet = net(); |
| 389 | 522 | |
| 390 | 523 | if (EXPECTED(newQ != anet.m_new.Q)) |
| 391 | 524 | { |
| r26109 | r26110 | |
| 396 | 529 | } |
| 397 | 530 | }; |
| 398 | 531 | |
| 399 | | class ttl_output_t : public logic_output_t |
| 532 | class netlist_ttl_output_t : public netlist_logic_output_t |
| 400 | 533 | { |
| 401 | 534 | public: |
| 402 | 535 | |
| 403 | | ttl_output_t() |
| 404 | | : logic_output_t() |
| 536 | netlist_ttl_output_t() |
| 537 | : netlist_logic_output_t() |
| 405 | 538 | { |
| 406 | 539 | set_levels(0.3, 3.4); |
| 407 | 540 | } |
| 408 | 541 | |
| 409 | 542 | }; |
| 410 | 543 | |
| 411 | | class analog_output_t : public net_output_t |
| 544 | class netlist_analog_output_t : public netlist_output_t |
| 412 | 545 | { |
| 413 | 546 | public: |
| 414 | 547 | |
| 415 | | ATTR_COLD analog_output_t() |
| 416 | | : net_output_t(OUTPUT | SIGNAL_ANALOG) |
| 548 | ATTR_COLD netlist_analog_output_t() |
| 549 | : netlist_output_t(OUTPUT, ANALOG) |
| 417 | 550 | { |
| 418 | 551 | net().m_cur.Analog = 0.0; |
| 419 | 552 | net().m_new.Analog = 0.0; |
| r26109 | r26110 | |
| 440 | 573 | // net_device_t |
| 441 | 574 | // ---------------------------------------------------------------------------------------- |
| 442 | 575 | |
| 443 | | class netlist_core_device_t : public net_object_t |
| 576 | class netlist_core_device_t : public netlist_object_t |
| 444 | 577 | { |
| 445 | 578 | public: |
| 446 | 579 | |
| r26109 | r26110 | |
| 467 | 600 | #endif |
| 468 | 601 | } |
| 469 | 602 | |
| 470 | | ATTR_HOT const netlist_sig_t INPLOGIC_PASSIVE(logic_input_t &inp); |
| 603 | ATTR_HOT const netlist_sig_t INPLOGIC_PASSIVE(netlist_logic_input_t &inp); |
| 471 | 604 | |
| 472 | | ATTR_HOT inline const netlist_sig_t INPLOGIC(const logic_input_t &inp) const |
| 605 | ATTR_HOT inline const netlist_sig_t INPLOGIC(const netlist_logic_input_t &inp) const |
| 473 | 606 | { |
| 474 | | assert(inp.state() != net_input_t::INP_STATE_PASSIVE); |
| 607 | assert(inp.state() != netlist_input_t::INP_STATE_PASSIVE); |
| 475 | 608 | return inp.Q(); |
| 476 | 609 | } |
| 477 | 610 | |
| 478 | | ATTR_HOT inline void OUTLOGIC(logic_output_t &out, const netlist_sig_t val, const netlist_time &delay) |
| 611 | ATTR_HOT inline void OUTLOGIC(netlist_logic_output_t &out, const netlist_sig_t val, const netlist_time &delay) |
| 479 | 612 | { |
| 480 | 613 | out.set_Q(val, delay); |
| 481 | 614 | } |
| 482 | 615 | |
| 483 | | ATTR_HOT inline bool INP_HL(const logic_input_t &inp) const |
| 616 | ATTR_HOT inline bool INP_HL(const netlist_logic_input_t &inp) const |
| 484 | 617 | { |
| 485 | 618 | return ((inp.last_Q() & !inp.Q()) == 1); |
| 486 | 619 | } |
| 487 | 620 | |
| 488 | | ATTR_HOT inline bool INP_LH(const logic_input_t &inp) const |
| 621 | ATTR_HOT inline bool INP_LH(const netlist_logic_input_t &inp) const |
| 489 | 622 | { |
| 490 | 623 | return ((!inp.last_Q() & inp.Q()) == 1); |
| 491 | 624 | } |
| 492 | 625 | |
| 493 | | ATTR_HOT inline const double INPANALOG(const analog_input_t &inp) const { return inp.Q_Analog(); } |
| 626 | ATTR_HOT inline const double INPANALOG(const netlist_analog_input_t &inp) const { return inp.Q_Analog(); } |
| 494 | 627 | |
| 495 | | ATTR_HOT inline void OUTANALOG(analog_output_t &out, const double val, const netlist_time &delay) |
| 628 | ATTR_HOT inline void OUTANALOG(netlist_analog_output_t &out, const double val, const netlist_time &delay) |
| 496 | 629 | { |
| 497 | 630 | out.set_Q(val, delay); |
| 498 | 631 | } |
| r26109 | r26110 | |
| 519 | 652 | }; |
| 520 | 653 | |
| 521 | 654 | |
| 522 | | class net_device_t : public netlist_core_device_t |
| 655 | class netlist_device_t : public netlist_core_device_t |
| 523 | 656 | { |
| 524 | 657 | public: |
| 525 | 658 | |
| 526 | | ATTR_COLD net_device_t(); |
| 659 | ATTR_COLD netlist_device_t(); |
| 527 | 660 | |
| 528 | | virtual ~net_device_t(); |
| 661 | virtual ~netlist_device_t(); |
| 529 | 662 | |
| 530 | 663 | ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name); |
| 531 | 664 | |
| r26109 | r26110 | |
| 535 | 668 | |
| 536 | 669 | ATTR_COLD void register_sub(netlist_core_device_t &dev, const astring &name); |
| 537 | 670 | |
| 538 | | ATTR_COLD void register_output(const astring &name, net_output_t &out); |
| 539 | | ATTR_COLD void register_output(netlist_core_device_t &dev, const astring &name, net_output_t &out); |
| 671 | ATTR_COLD void register_output(const astring &name, netlist_output_t &out); |
| 672 | ATTR_COLD void register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &out); |
| 540 | 673 | |
| 541 | | ATTR_COLD void register_input(const astring &name, net_input_t &in, net_input_t::net_input_state state = net_input_t::INP_STATE_ACTIVE); |
| 542 | | ATTR_COLD void register_input(netlist_core_device_t &dev, const astring &name, net_input_t &in, net_input_t::net_input_state state = net_input_t::INP_STATE_ACTIVE); |
| 674 | ATTR_COLD void register_input(const astring &name, netlist_input_t &in, netlist_input_t::net_input_state state = netlist_input_t::INP_STATE_ACTIVE); |
| 675 | ATTR_COLD void register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &in, netlist_input_t::net_input_state state = netlist_input_t::INP_STATE_ACTIVE); |
| 543 | 676 | |
| 544 | | ATTR_COLD void register_link_internal(net_input_t &in, net_output_t &out, net_input_t::net_input_state aState); |
| 545 | | ATTR_COLD void register_link_internal(netlist_core_device_t &dev, net_input_t &in, net_output_t &out, net_input_t::net_input_state aState); |
| 677 | ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState); |
| 678 | ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState); |
| 546 | 679 | |
| 547 | | netlist_list_t<astring> m_inputs; |
| 680 | /* driving logic outputs don't count in here */ |
| 681 | netlist_list_t<astring> m_terminals; |
| 548 | 682 | |
| 549 | 683 | protected: |
| 550 | 684 | |
| 551 | 685 | virtual void update() { } |
| 552 | 686 | virtual void start() { } |
| 553 | 687 | |
| 554 | | ATTR_COLD void register_param(const astring &sname, net_param_t ¶m, const double initialVal = 0.0); |
| 555 | | ATTR_COLD void register_param(netlist_core_device_t &dev, const astring &sname, net_param_t ¶m, const double initialVal = 0.0); |
| 688 | ATTR_COLD void register_param(const astring &sname, netlist_param_t ¶m, const double initialVal = 0.0); |
| 689 | ATTR_COLD void register_param(netlist_core_device_t &dev, const astring &sname, netlist_param_t ¶m, const double initialVal = 0.0); |
| 556 | 690 | |
| 557 | 691 | netlist_setup_t *m_setup; |
| 558 | 692 | bool m_variable_input_count; |
| r26109 | r26110 | |
| 560 | 694 | private: |
| 561 | 695 | }; |
| 562 | 696 | |
| 563 | | class net_param_t |
| 697 | class netlist_param_t : public netlist_object_t |
| 564 | 698 | { |
| 565 | 699 | public: |
| 566 | | net_param_t() |
| 567 | | : m_param(0.0) |
| 700 | netlist_param_t() |
| 701 | : netlist_object_t(PARAM, ANALOG) |
| 702 | , m_param(0.0) |
| 568 | 703 | , m_netdev(NULL) |
| 569 | 704 | { } |
| 570 | 705 | |
| r26109 | r26110 | |
| 586 | 721 | }; |
| 587 | 722 | |
| 588 | 723 | |
| 589 | | |
| 590 | | class netdev_mainclock; |
| 591 | | |
| 592 | 724 | // ---------------------------------------------------------------------------------------- |
| 593 | 725 | // netlist_base_t |
| 594 | 726 | // ---------------------------------------------------------------------------------------- |
| r26109 | r26110 | |
| 597 | 729 | { |
| 598 | 730 | public: |
| 599 | 731 | |
| 600 | | typedef netlist_timed_queue1<net_net_t, netlist_time, 512> queue_t; |
| 732 | typedef netlist_timed_queue1<netlist_net_t, netlist_time, 512> queue_t; |
| 601 | 733 | |
| 602 | 734 | netlist_base_t(); |
| 603 | 735 | virtual ~netlist_base_t(); |
| 604 | 736 | |
| 605 | 737 | void set_clock_freq(UINT64 clockfreq); |
| 606 | 738 | |
| 607 | | ATTR_HOT inline void push_to_queue(net_net_t &out, const netlist_time &attime) |
| 739 | ATTR_HOT inline void push_to_queue(netlist_net_t &out, const netlist_time &attime) |
| 608 | 740 | { |
| 609 | 741 | m_queue.push(queue_t::entry_t(attime, out)); |
| 610 | 742 | } |
| r26109 | r26110 | |
| 613 | 745 | |
| 614 | 746 | ATTR_HOT inline const netlist_time &time() const { return m_time_ps; } |
| 615 | 747 | |
| 616 | | ATTR_COLD void set_mainclock_dev(NETLIB_NAME(netdev_mainclock) *dev); |
| 748 | ATTR_COLD void set_mainclock_dev(NETLIB_NAME(mainclock) *dev); |
| 617 | 749 | |
| 618 | 750 | ATTR_COLD void reset(); |
| 619 | 751 | |
| r26109 | r26110 | |
| 627 | 759 | int m_perf_inp_active; |
| 628 | 760 | |
| 629 | 761 | private: |
| 630 | | NETLIB_NAME(netdev_mainclock) *m_mainclock; |
| 762 | NETLIB_NAME(mainclock) *m_mainclock; |
| 631 | 763 | netlist_time m_time_ps; |
| 632 | 764 | UINT32 m_rem; |
| 633 | 765 | UINT32 m_div; |
| r26109 | r26110 | |
| 641 | 773 | // netdev_a_to_d |
| 642 | 774 | // ---------------------------------------------------------------------------------------- |
| 643 | 775 | |
| 644 | | class netdev_a_to_d_proxy : public net_device_t |
| 776 | class nld_a_to_d_proxy : public netlist_device_t |
| 645 | 777 | { |
| 646 | 778 | public: |
| 647 | | netdev_a_to_d_proxy(net_input_t &in_proxied) |
| 648 | | : net_device_t() |
| 779 | nld_a_to_d_proxy(netlist_input_t &in_proxied) |
| 780 | : netlist_device_t() |
| 649 | 781 | { |
| 650 | 782 | assert(in_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL); |
| 651 | 783 | m_I.m_high_thresh_V = in_proxied.m_high_thresh_V; |
| 652 | 784 | m_I.m_low_thresh_V = in_proxied.m_low_thresh_V; |
| 653 | 785 | } |
| 654 | 786 | |
| 655 | | virtual ~netdev_a_to_d_proxy() {} |
| 787 | virtual ~nld_a_to_d_proxy() {} |
| 656 | 788 | |
| 657 | | analog_input_t m_I; |
| 658 | | ttl_output_t m_Q; |
| 789 | netlist_analog_input_t m_I; |
| 790 | netlist_ttl_output_t m_Q; |
| 659 | 791 | |
| 660 | 792 | protected: |
| 661 | 793 | void start() |
| r26109 | r26110 | |
| 680 | 812 | // netdev_d_to_a |
| 681 | 813 | // ---------------------------------------------------------------------------------------- |
| 682 | 814 | |
| 683 | | class netdev_d_to_a_proxy : public net_device_t |
| 815 | class nld_d_to_a_proxy : public netlist_device_t |
| 684 | 816 | { |
| 685 | 817 | public: |
| 686 | | netdev_d_to_a_proxy(net_output_t &out_proxied) |
| 687 | | : net_device_t() |
| 818 | nld_d_to_a_proxy(netlist_output_t &out_proxied) |
| 819 | : netlist_device_t() |
| 688 | 820 | { |
| 689 | 821 | assert(out_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL); |
| 690 | 822 | m_low_V = out_proxied.m_low_V; |
| 691 | 823 | m_high_V = out_proxied.m_high_V; |
| 692 | 824 | } |
| 693 | 825 | |
| 694 | | virtual ~netdev_d_to_a_proxy() {} |
| 826 | virtual ~nld_d_to_a_proxy() {} |
| 695 | 827 | |
| 696 | | ttl_input_t m_I; |
| 697 | | analog_output_t m_Q; |
| 828 | netlist_ttl_input_t m_I; |
| 829 | netlist_analog_output_t m_Q; |
| 698 | 830 | |
| 699 | 831 | protected: |
| 700 | 832 | void start() |
| r26109 | r26110 | |
| 719 | 851 | // Inline implementations |
| 720 | 852 | // ---------------------------------------------------------------------------------------- |
| 721 | 853 | |
| 722 | | ATTR_HOT inline void net_input_t::inactivate() |
| 854 | ATTR_HOT inline void netlist_input_t::inactivate() |
| 723 | 855 | { |
| 724 | | if (m_state != INP_STATE_PASSIVE) |
| 856 | if (!is_state(INP_STATE_PASSIVE)) |
| 725 | 857 | { |
| 726 | | m_state = INP_STATE_PASSIVE; |
| 858 | set_state(INP_STATE_PASSIVE); |
| 727 | 859 | net().dec_active(); |
| 728 | 860 | } |
| 729 | 861 | } |
| 730 | 862 | |
| 731 | | ATTR_HOT inline void net_input_t::activate() |
| 863 | ATTR_HOT inline void netlist_input_t::activate() |
| 732 | 864 | { |
| 733 | | if (m_state == INP_STATE_PASSIVE) |
| 865 | if (is_state(INP_STATE_PASSIVE)) |
| 734 | 866 | { |
| 735 | 867 | net().inc_active(); |
| 736 | | m_state = INP_STATE_ACTIVE; |
| 868 | set_state(INP_STATE_ACTIVE); |
| 737 | 869 | } |
| 738 | 870 | } |
| 739 | 871 | |
| 740 | | ATTR_HOT inline void net_input_t::activate_hl() |
| 872 | ATTR_HOT inline void netlist_input_t::activate_hl() |
| 741 | 873 | { |
| 742 | | if (m_state == INP_STATE_PASSIVE) |
| 874 | if (is_state(INP_STATE_PASSIVE)) |
| 743 | 875 | { |
| 744 | 876 | net().inc_active(); |
| 745 | | m_state = INP_STATE_HL; |
| 877 | set_state(INP_STATE_HL); |
| 746 | 878 | } |
| 747 | 879 | } |
| 748 | 880 | |
| 749 | | ATTR_HOT inline void net_input_t::activate_lh() |
| 881 | ATTR_HOT inline void netlist_input_t::activate_lh() |
| 750 | 882 | { |
| 751 | | if (m_state == INP_STATE_PASSIVE) |
| 883 | if (is_state(INP_STATE_PASSIVE)) |
| 752 | 884 | { |
| 753 | 885 | net().inc_active(); |
| 754 | | m_state = INP_STATE_LH; |
| 886 | set_state(INP_STATE_LH); |
| 755 | 887 | } |
| 756 | 888 | } |
| 757 | 889 | |
| 758 | 890 | |
| 759 | | ATTR_HOT inline void net_net_t::push_to_queue(const netlist_time &delay) |
| 891 | ATTR_HOT inline void netlist_net_t::push_to_queue(const netlist_time &delay) |
| 760 | 892 | { |
| 761 | 893 | // if (m_in_queue == 1) return; FIXME: check this at some time |
| 762 | | m_time = netlist()->time() + delay; |
| 894 | m_time = netlist().time() + delay; |
| 763 | 895 | m_in_queue = (m_active > 0) ? 1 : 0; /* queued ? */ |
| 764 | 896 | if (m_in_queue) |
| 765 | 897 | { |
| 766 | 898 | //m_in_queue = 1; /* pending */ |
| 767 | | netlist()->push_to_queue(*this, m_time); |
| 899 | netlist().push_to_queue(*this, m_time); |
| 768 | 900 | } |
| 769 | 901 | } |
| 770 | 902 | |
| 771 | | ATTR_HOT inline void net_net_t::inc_active() |
| 903 | ATTR_HOT inline void netlist_net_t::inc_active() |
| 772 | 904 | { |
| 773 | 905 | m_active++; |
| 774 | 906 | |
| 775 | | #if USE_DEACTIVE_DEVICE |
| 776 | | if (m_active == 1 && m_in_queue > 0) |
| 777 | | { |
| 778 | | m_last = m_cur; |
| 779 | | raildev()->inc_active(); |
| 780 | | m_cur = m_new; |
| 781 | | } |
| 782 | | #endif |
| 907 | if (USE_DEACTIVE_DEVICE) |
| 908 | if (m_active == 1 && m_in_queue > 0) |
| 909 | { |
| 910 | m_last = m_cur; |
| 911 | railterminal().netdev().inc_active(); |
| 912 | m_cur = m_new; |
| 913 | } |
| 783 | 914 | |
| 784 | 915 | if (EXPECTED(m_active == 1 && m_in_queue == 0)) |
| 785 | 916 | { |
| 786 | | if (EXPECTED(m_time > netlist()->time())) |
| 917 | if (EXPECTED(m_time > netlist().time())) |
| 787 | 918 | { |
| 788 | 919 | m_in_queue = 1; /* pending */ |
| 789 | | netlist()->push_to_queue(*this, m_time); |
| 920 | netlist().push_to_queue(*this, m_time); |
| 790 | 921 | } |
| 791 | 922 | else |
| 792 | 923 | { |
| r26109 | r26110 | |
| 796 | 927 | } |
| 797 | 928 | } |
| 798 | 929 | |
| 799 | | ATTR_HOT inline void net_net_t::dec_active() |
| 930 | ATTR_HOT inline void netlist_net_t::dec_active() |
| 800 | 931 | { |
| 801 | 932 | m_active--; |
| 802 | | #if (USE_DEACTIVE_DEVICE) |
| 803 | | if (m_active == 0) |
| 804 | | raildev()->dec_active(); |
| 805 | | #endif |
| 933 | if (USE_DEACTIVE_DEVICE) |
| 934 | if (m_active == 0) |
| 935 | railterminal().netdev().dec_active(); |
| 936 | |
| 806 | 937 | } |
| 807 | 938 | |
| 808 | | ATTR_HOT inline const netlist_sig_t logic_input_t::Q() const |
| 939 | ATTR_HOT inline const netlist_sig_t netlist_logic_input_t::Q() const |
| 809 | 940 | { |
| 810 | 941 | return net().Q(); |
| 811 | 942 | } |
| 812 | 943 | |
| 813 | | ATTR_HOT inline const netlist_sig_t logic_input_t::last_Q() const |
| 944 | ATTR_HOT inline const netlist_sig_t netlist_logic_input_t::last_Q() const |
| 814 | 945 | { |
| 815 | 946 | return net().last_Q(); |
| 816 | 947 | } |
| 817 | 948 | |
| 818 | | ATTR_HOT inline const double analog_input_t::Q_Analog() const |
| 949 | ATTR_HOT inline const double netlist_analog_input_t::Q_Analog() const |
| 819 | 950 | { |
| 820 | 951 | return net().Q_Analog(); |
| 821 | 952 | } |
| 822 | 953 | |
| 823 | | ATTR_HOT inline const bool analog_input_t::is_highz() const |
| 954 | ATTR_HOT inline const bool netlist_analog_input_t::is_highz() const |
| 824 | 955 | { |
| 825 | 956 | return (net().Q_Analog() == NETLIST_HIGHIMP_V); |
| 826 | 957 | } |
| r26109 | r26110 | |
| 838 | 969 | |
| 839 | 970 | virtual ~net_device_t_base_factory() {} |
| 840 | 971 | |
| 841 | | virtual net_device_t *Create() const = 0; |
| 972 | virtual netlist_device_t *Create() const = 0; |
| 842 | 973 | |
| 843 | 974 | const astring &name() const { return m_name; } |
| 844 | 975 | const astring &classname() const { return m_classname; } |
| r26109 | r26110 | |
| 854 | 985 | net_device_t_factory(const astring &name, const astring &classname) |
| 855 | 986 | : net_device_t_base_factory(name, classname) { } |
| 856 | 987 | |
| 857 | | net_device_t *Create() const |
| 988 | netlist_device_t *Create() const |
| 858 | 989 | { |
| 859 | | net_device_t *r = new C(); |
| 990 | netlist_device_t *r = new C(); |
| 860 | 991 | //r->init(setup, name); |
| 861 | 992 | return r; |
| 862 | 993 | } |
| 863 | 994 | }; |
| 864 | 995 | |
| 865 | | net_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup, const astring &icname); |
| 866 | | net_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup, const astring &icname); |
| 996 | netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup, const astring &icname); |
| 997 | netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup, const astring &icname); |
| 867 | 998 | |
| 868 | 999 | |
| 869 | 1000 | #endif /* NLBASE_H_ */ |
trunk/src/emu/netlist/nl_setup.c
| r26109 | r26110 | |
| 46 | 46 | m_terminals.reset(); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | | net_device_t *netlist_setup_t::register_dev(net_device_t *dev) |
| 49 | netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev) |
| 50 | 50 | { |
| 51 | 51 | if (!(m_devices.add(dev->name(), dev, false)==TMERR_NONE)) |
| 52 | 52 | fatalerror("Error adding %s to device list\n", dev->name().cstr()); |
| r26109 | r26110 | |
| 71 | 71 | |
| 72 | 72 | void netlist_setup_t::remove_dev(const astring &name) |
| 73 | 73 | { |
| 74 | | net_device_t *dev = m_devices.find(name); |
| 74 | netlist_device_t *dev = m_devices.find(name); |
| 75 | 75 | astring temp = name; |
| 76 | 76 | if (dev == NULL) |
| 77 | 77 | fatalerror("Device %s does not exist\n", name.cstr()); |
| r26109 | r26110 | |
| 87 | 87 | |
| 88 | 88 | void netlist_setup_t::register_callback(const astring &devname, netlist_output_delegate delegate) |
| 89 | 89 | { |
| 90 | | NETLIB_NAME(netdev_analog_callback) *dev = (NETLIB_NAME(netdev_analog_callback) *) m_devices.find(devname); |
| 90 | NETLIB_NAME(analog_callback) *dev = (NETLIB_NAME(analog_callback) *) m_devices.find(devname); |
| 91 | 91 | if (dev == NULL) |
| 92 | 92 | fatalerror("did not find device %s\n", devname.cstr()); |
| 93 | 93 | dev->register_callback(delegate); |
| r26109 | r26110 | |
| 99 | 99 | fatalerror("Error adding alias %s to alias list\n", alias.cstr()); |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | | void netlist_setup_t::register_output(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, net_output_t &out) |
| 102 | void netlist_setup_t::register_output(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_output_t &out) |
| 103 | 103 | { |
| 104 | | NL_VERBOSE_OUT(("out %s\n", name.cstr())); |
| 104 | NL_VERBOSE_OUT(("output %s\n", name.cstr())); |
| 105 | 105 | astring temp = dev.name(); |
| 106 | 106 | temp.cat("."); |
| 107 | 107 | temp.cat(name); |
| 108 | 108 | out.init_terminal(upd_dev); |
| 109 | 109 | if (!(m_terminals.add(temp, &out, false)==TMERR_NONE)) |
| 110 | | fatalerror("Error adding output %s to output list\n", name.cstr()); |
| 110 | fatalerror("Error adding output %s to terminal list\n", name.cstr()); |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | | void netlist_setup_t::register_input(net_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, net_input_t &inp, net_input_t::net_input_state type) |
| 113 | void netlist_setup_t::register_input(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type) |
| 114 | 114 | { |
| 115 | 115 | NL_VERBOSE_OUT(("input %s\n", name.cstr())); |
| 116 | 116 | astring temp = dev.name(); |
| 117 | 117 | temp.cat("."); |
| 118 | 118 | temp.cat(name); |
| 119 | 119 | inp.init_input(upd_dev, type); |
| 120 | | dev.m_inputs.add(temp); |
| 120 | /* add to list of terminals so logic devices are supported in parser */ |
| 121 | dev.m_terminals.add(temp); |
| 121 | 122 | if (!(m_terminals.add(temp, &inp, false) == TMERR_NONE)) |
| 122 | | fatalerror("Error adding input %s to input list\n", name.cstr()); |
| 123 | fatalerror("Error adding input %s to terminal list\n", name.cstr()); |
| 123 | 124 | } |
| 124 | 125 | |
| 125 | 126 | void netlist_setup_t::register_link(const astring &sin, const astring &sout) |
| r26109 | r26110 | |
| 131 | 132 | } |
| 132 | 133 | |
| 133 | 134 | |
| 134 | | void netlist_setup_t::register_param(const astring &name, net_param_t *param) |
| 135 | void netlist_setup_t::register_param(const astring &name, netlist_param_t *param) |
| 135 | 136 | { |
| 136 | 137 | astring temp = param->netdev().name(); |
| 137 | 138 | temp.cat("."); |
| r26109 | r26110 | |
| 149 | 150 | return name; |
| 150 | 151 | } |
| 151 | 152 | |
| 152 | | net_output_t *netlist_setup_t::find_output_exact(const astring &outname_in) |
| 153 | netlist_output_t *netlist_setup_t::find_output_exact(const astring &outname_in) |
| 153 | 154 | { |
| 154 | | net_terminal_t *term = m_terminals.find(outname_in); |
| 155 | | return dynamic_cast<net_output_t *>(term); |
| 155 | netlist_terminal_t *term = m_terminals.find(outname_in); |
| 156 | return dynamic_cast<netlist_output_t *>(term); |
| 156 | 157 | } |
| 157 | 158 | |
| 158 | | net_output_t &netlist_setup_t::find_output(const astring &outname_in) |
| 159 | netlist_output_t &netlist_setup_t::find_output(const astring &outname_in) |
| 159 | 160 | { |
| 160 | 161 | const astring &outname = resolve_alias(outname_in); |
| 161 | | net_output_t *ret; |
| 162 | netlist_output_t *ret; |
| 162 | 163 | |
| 163 | 164 | ret = find_output_exact(outname); |
| 164 | 165 | /* look for default */ |
| r26109 | r26110 | |
| 175 | 176 | return *ret; |
| 176 | 177 | } |
| 177 | 178 | |
| 178 | | net_param_t &netlist_setup_t::find_param(const astring ¶m_in) |
| 179 | netlist_param_t &netlist_setup_t::find_param(const astring ¶m_in) |
| 179 | 180 | { |
| 180 | 181 | const astring &outname = resolve_alias(param_in); |
| 181 | | net_param_t *ret; |
| 182 | netlist_param_t *ret; |
| 182 | 183 | |
| 183 | 184 | ret = m_params.find(outname); |
| 184 | 185 | if (ret == NULL) |
| r26109 | r26110 | |
| 195 | 196 | { |
| 196 | 197 | const astring *sout = entry->object(); |
| 197 | 198 | astring sin = entry->tag(); |
| 198 | | net_input_t *in = dynamic_cast<net_input_t *>(m_terminals.find(sin)); |
| 199 | netlist_input_t *in = dynamic_cast<netlist_input_t *>(m_terminals.find(sin)); |
| 199 | 200 | |
| 200 | 201 | if (in == NULL) |
| 201 | 202 | fatalerror("Unable to find %s\n", sin.cstr()); |
| 202 | 203 | |
| 203 | | net_output_t &out = find_output(sout->cstr()); |
| 204 | | if (out.object_type(net_output_t::SIGNAL_MASK) == net_output_t::SIGNAL_ANALOG |
| 205 | | && in->object_type(net_output_t::SIGNAL_MASK) == net_output_t::SIGNAL_DIGITAL) |
| 204 | netlist_output_t &out = find_output(sout->cstr()); |
| 205 | if (out.isFamily(netlist_terminal_t::ANALOG) && in->isFamily(netlist_terminal_t::LOGIC)) |
| 206 | 206 | { |
| 207 | | netdev_a_to_d_proxy *proxy = new netdev_a_to_d_proxy(*in); |
| 207 | nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(*in); |
| 208 | 208 | astring x = ""; |
| 209 | 209 | x.printf("proxy_ad_%d", proxy_cnt++); |
| 210 | 210 | |
| r26109 | r26110 | |
| 215 | 215 | out.net().register_con(proxy->m_I); |
| 216 | 216 | |
| 217 | 217 | } |
| 218 | | else if (out.object_type(net_output_t::SIGNAL_MASK) == net_output_t::SIGNAL_DIGITAL |
| 219 | | && in->object_type(net_output_t::SIGNAL_MASK) == net_output_t::SIGNAL_ANALOG) |
| 218 | else if (out.isFamily(netlist_terminal_t::LOGIC) && in->isFamily(netlist_terminal_t::ANALOG)) |
| 220 | 219 | { |
| 221 | 220 | //printf("here 1\n"); |
| 222 | | netdev_d_to_a_proxy *proxy = new netdev_d_to_a_proxy(out); |
| 221 | nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out); |
| 223 | 222 | astring x = ""; |
| 224 | 223 | x.printf("proxy_da_%d", proxy_cnt++); |
| 225 | 224 | proxy->init(*this, x.cstr()); |
| r26109 | r26110 | |
| 237 | 236 | /* find the main clock ... */ |
| 238 | 237 | for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry)) |
| 239 | 238 | { |
| 240 | | net_device_t *dev = entry->object(); |
| 241 | | if (dynamic_cast<NETLIB_NAME(netdev_mainclock)*>(dev) != NULL) |
| 239 | netlist_device_t *dev = entry->object(); |
| 240 | if (dynamic_cast<NETLIB_NAME(mainclock)*>(dev) != NULL) |
| 242 | 241 | { |
| 243 | | m_netlist.set_mainclock_dev(dynamic_cast<NETLIB_NAME(netdev_mainclock)*>(dev)); |
| 242 | m_netlist.set_mainclock_dev(dynamic_cast<NETLIB_NAME(mainclock)*>(dev)); |
| 244 | 243 | } |
| 245 | 244 | } |
| 246 | 245 | |
| 247 | 246 | /* print all outputs */ |
| 248 | 247 | for (tagmap_terminal_t::entry_t *entry = m_terminals.first(); entry != NULL; entry = m_terminals.next(entry)) |
| 249 | 248 | { |
| 250 | | ATTR_UNUSED net_output_t *out = dynamic_cast<net_output_t *>(entry->object()); |
| 249 | ATTR_UNUSED netlist_output_t *out = dynamic_cast<netlist_output_t *>(entry->object()); |
| 251 | 250 | //if (out != NULL) |
| 252 | 251 | //VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr())); |
| 253 | 252 | } |
| r26109 | r26110 | |
| 265 | 264 | |
| 266 | 265 | for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry)) |
| 267 | 266 | { |
| 268 | | net_device_t *dev = entry->object(); |
| 267 | netlist_device_t *dev = entry->object(); |
| 269 | 268 | dev->update_dev(); |
| 270 | 269 | } |
| 271 | 270 | } |
trunk/src/emu/netlist/devices/net_lib.c
| r26109 | r26110 | |
| 50 | 50 | #include "net_lib.h" |
| 51 | 51 | #include "nld_system.h" |
| 52 | 52 | |
| 53 | | NETLIB_START(netdev_logic_input) |
| 53 | NETLIB_START(logic_input) |
| 54 | 54 | { |
| 55 | 55 | register_output("Q", m_Q); |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | | NETLIB_UPDATE(netdev_logic_input) |
| 58 | NETLIB_UPDATE(logic_input) |
| 59 | 59 | { |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | | NETLIB_START(netdev_analog_input) |
| 62 | NETLIB_START(analog_input) |
| 63 | 63 | { |
| 64 | 64 | register_output("Q", m_Q); |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | | NETLIB_UPDATE(netdev_analog_input) |
| 67 | NETLIB_UPDATE(analog_input) |
| 68 | 68 | { |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | | NETLIB_START(netdev_log) |
| 71 | NETLIB_START(log) |
| 72 | 72 | { |
| 73 | 73 | register_input("I", m_I); |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | | NETLIB_UPDATE(netdev_log) |
| 76 | NETLIB_UPDATE(log) |
| 77 | 77 | { |
| 78 | | printf("%s: %d %d\n", name().cstr(), (UINT32) (netlist()->time().as_raw() / 1000000), INPLOGIC(m_I)); |
| 78 | printf("%s: %d %d\n", name().cstr(), (UINT32) (netlist().time().as_raw() / 1000000), INPLOGIC(m_I)); |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | | NETLIB_START(netdev_clock) |
| 81 | NETLIB_START(clock) |
| 82 | 82 | { |
| 83 | 83 | register_output("Q", m_Q); |
| 84 | 84 | //register_input("FB", m_feedback); |
| r26109 | r26110 | |
| 86 | 86 | register_param("FREQ", m_freq, 7159000.0 * 5); |
| 87 | 87 | m_inc = netlist_time::from_hz(m_freq.Value()*2); |
| 88 | 88 | |
| 89 | | register_link_internal(m_feedback, m_Q, net_input_t::INP_STATE_ACTIVE); |
| 89 | register_link_internal(m_feedback, m_Q, netlist_input_t::INP_STATE_ACTIVE); |
| 90 | 90 | |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | | NETLIB_UPDATE_PARAM(netdev_clock) |
| 93 | NETLIB_UPDATE_PARAM(clock) |
| 94 | 94 | { |
| 95 | 95 | m_inc = netlist_time::from_hz(m_freq.Value()*2); |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | | NETLIB_UPDATE(netdev_clock) |
| 98 | NETLIB_UPDATE(clock) |
| 99 | 99 | { |
| 100 | 100 | //m_Q.setToNoCheck(!m_Q.new_Q(), m_inc ); |
| 101 | 101 | OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc ); |
| r26109 | r26110 | |
| 217 | 217 | register_param("VL", m_VL, 0.0 *5.0); |
| 218 | 218 | |
| 219 | 219 | m_THRESHOLD_OUT.init_terminal(*this); |
| 220 | | register_link_internal(m_THRESHOLD, m_THRESHOLD_OUT, net_input_t::INP_STATE_ACTIVE); |
| 220 | register_link_internal(m_THRESHOLD, m_THRESHOLD_OUT, netlist_input_t::INP_STATE_ACTIVE); |
| 221 | 221 | |
| 222 | 222 | m_Q.initial(5.0 * 0.4); |
| 223 | 223 | m_last = false; |
| r26109 | r26110 | |
| 503 | 503 | NETLIB_START(nic7474) |
| 504 | 504 | { |
| 505 | 505 | register_sub(sub, "sub"); |
| 506 | | register_input(sub, "CLK", sub.m_clk, net_input_t::INP_STATE_LH); |
| 506 | register_input(sub, "CLK", sub.m_clk, netlist_input_t::INP_STATE_LH); |
| 507 | 507 | register_input("D", m_D); |
| 508 | 508 | register_input("CLRQ", m_clrQ); |
| 509 | 509 | register_input("PREQ", m_preQ); |
| r26109 | r26110 | |
| 614 | 614 | register_sub(C, "C"); |
| 615 | 615 | register_sub(D, "D"); |
| 616 | 616 | |
| 617 | | register_input(A, "CLKA", A.m_I, net_input_t::INP_STATE_HL); |
| 618 | | register_input(B, "CLKB", B.m_I, net_input_t::INP_STATE_HL); |
| 617 | register_input(A, "CLKA", A.m_I, netlist_input_t::INP_STATE_HL); |
| 618 | register_input(B, "CLKB", B.m_I, netlist_input_t::INP_STATE_HL); |
| 619 | 619 | register_input("R1", m_R1); |
| 620 | 620 | register_input("R2", m_R2); |
| 621 | 621 | |
| r26109 | r26110 | |
| 625 | 625 | register_output(D, "QD", D.m_Q); |
| 626 | 626 | |
| 627 | 627 | //B.register_link_internal(B.m_I, A.m_Q); |
| 628 | | register_link_internal(C, C.m_I, B.m_Q, net_input_t::INP_STATE_HL); |
| 629 | | register_link_internal(D, D.m_I, C.m_Q, net_input_t::INP_STATE_HL); |
| 628 | register_link_internal(C, C.m_I, B.m_Q, netlist_input_t::INP_STATE_HL); |
| 629 | register_link_internal(D, D.m_I, C.m_Q, netlist_input_t::INP_STATE_HL); |
| 630 | 630 | |
| 631 | 631 | } |
| 632 | 632 | |
| r26109 | r26110 | |
| 665 | 665 | { |
| 666 | 666 | m_cnt = 0; |
| 667 | 667 | |
| 668 | | register_input("CLKA", m_CLK, net_input_t::INP_STATE_HL); |
| 669 | | register_input("CLKB", m_CLKB, net_input_t::INP_STATE_HL); |
| 668 | register_input("CLKA", m_CLK, netlist_input_t::INP_STATE_HL); |
| 669 | register_input("CLKB", m_CLKB, netlist_input_t::INP_STATE_HL); |
| 670 | 670 | register_input("R1", m_R1); |
| 671 | 671 | register_input("R2", m_R2); |
| 672 | 672 | |
| r26109 | r26110 | |
| 745 | 745 | { |
| 746 | 746 | register_sub(sub, "sub"); |
| 747 | 747 | |
| 748 | | register_input(sub, "CLK", sub.m_clk, net_input_t::INP_STATE_HL); |
| 748 | register_input(sub, "CLK", sub.m_clk, netlist_input_t::INP_STATE_HL); |
| 749 | 749 | register_input("J", m_J); |
| 750 | 750 | register_input("K", m_K); |
| 751 | 751 | register_input("CLRQ", m_clrQ); |
| r26109 | r26110 | |
| 855 | 855 | sub.m_loadq = 1; |
| 856 | 856 | sub.m_ent = 1; |
| 857 | 857 | |
| 858 | | register_input(sub, "CLK", sub.m_clk, net_input_t::INP_STATE_LH); |
| 858 | register_input(sub, "CLK", sub.m_clk, netlist_input_t::INP_STATE_LH); |
| 859 | 859 | |
| 860 | 860 | register_input("ENP", m_ENP); |
| 861 | 861 | register_input("ENT", m_ENT); |
| 862 | 862 | register_input("CLRQ", m_CLRQ); |
| 863 | 863 | register_input("LOADQ", m_LOADQ); |
| 864 | 864 | |
| 865 | | register_input(sub, "A", sub.m_A, net_input_t::INP_STATE_PASSIVE); |
| 866 | | register_input(sub, "B", sub.m_B, net_input_t::INP_STATE_PASSIVE); |
| 867 | | register_input(sub, "C", sub.m_C, net_input_t::INP_STATE_PASSIVE); |
| 868 | | register_input(sub, "D", sub.m_D, net_input_t::INP_STATE_PASSIVE); |
| 865 | register_input(sub, "A", sub.m_A, netlist_input_t::INP_STATE_PASSIVE); |
| 866 | register_input(sub, "B", sub.m_B, netlist_input_t::INP_STATE_PASSIVE); |
| 867 | register_input(sub, "C", sub.m_C, netlist_input_t::INP_STATE_PASSIVE); |
| 868 | register_input(sub, "D", sub.m_D, netlist_input_t::INP_STATE_PASSIVE); |
| 869 | 869 | |
| 870 | 870 | register_output(sub, "QA", sub.m_QA); |
| 871 | 871 | register_output(sub, "QB", sub.m_QB); |
| r26109 | r26110 | |
| 972 | 972 | |
| 973 | 973 | static const net_device_t_base_factory *netregistry[] = |
| 974 | 974 | { |
| 975 | | ENTRY(netdev_ttl_const, NETDEV_TTL_CONST) |
| 976 | | ENTRY(netdev_analog_const, NETDEV_ANALOG_CONST) |
| 977 | | ENTRY(netdev_logic_input, NETDEV_LOGIC_INPUT) |
| 978 | | ENTRY(netdev_analog_input, NETDEV_ANALOG_INPUT) |
| 979 | | ENTRY(netdev_log, NETDEV_LOG) |
| 980 | | ENTRY(netdev_clock, NETDEV_CLOCK) |
| 981 | | ENTRY(netdev_mainclock, NETDEV_MAINCLOCK) |
| 982 | | ENTRY(netdev_analog_callback,NETDEV_CALLBACK) |
| 975 | ENTRY(ttl_const, NETDEV_TTL_CONST) |
| 976 | ENTRY(analog_const, NETDEV_ANALOG_CONST) |
| 977 | ENTRY(logic_input, NETDEV_LOGIC_INPUT) |
| 978 | ENTRY(analog_input, NETDEV_ANALOG_INPUT) |
| 979 | ENTRY(log, NETDEV_LOG) |
| 980 | ENTRY(clock, NETDEV_CLOCK) |
| 981 | ENTRY(mainclock, NETDEV_MAINCLOCK) |
| 982 | ENTRY(analog_callback, NETDEV_CALLBACK) |
| 983 | 983 | ENTRY(nicMultiSwitch, NETDEV_SWITCH2) |
| 984 | 984 | ENTRY(nicRSFF, NETDEV_RSFF) |
| 985 | 985 | ENTRY(nicMixer8, NETDEV_MIXER) |
| r26109 | r26110 | |
| 1006 | 1006 | NULL |
| 1007 | 1007 | }; |
| 1008 | 1008 | |
| 1009 | | net_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup, const astring &icname) |
| 1009 | netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup, const astring &icname) |
| 1010 | 1010 | { |
| 1011 | 1011 | const net_device_t_base_factory **p = &netregistry[0]; |
| 1012 | 1012 | while (*p != NULL) |
| 1013 | 1013 | { |
| 1014 | 1014 | if (strcmp((*p)->classname(), classname) == 0) |
| 1015 | 1015 | { |
| 1016 | | net_device_t *ret = (*p)->Create(); |
| 1016 | netlist_device_t *ret = (*p)->Create(); |
| 1017 | 1017 | ret->init(setup, icname); |
| 1018 | 1018 | return ret; |
| 1019 | 1019 | } |
| r26109 | r26110 | |
| 1023 | 1023 | return NULL; // appease code analysis |
| 1024 | 1024 | } |
| 1025 | 1025 | |
| 1026 | | net_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup, const astring &icname) |
| 1026 | netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup, const astring &icname) |
| 1027 | 1027 | { |
| 1028 | 1028 | const net_device_t_base_factory **p = &netregistry[0]; |
| 1029 | 1029 | while (*p != NULL) |
| 1030 | 1030 | { |
| 1031 | 1031 | if (strcmp((*p)->name(), name) == 0) |
| 1032 | 1032 | { |
| 1033 | | net_device_t *ret = (*p)->Create(); |
| 1033 | netlist_device_t *ret = (*p)->Create(); |
| 1034 | 1034 | ret->init(setup, icname); |
| 1035 | 1035 | return ret; |
| 1036 | 1036 | } |
trunk/src/emu/netlist/devices/net_lib.h
| r26109 | r26110 | |
| 69 | 69 | // ---------------------------------------------------------------------------------------- |
| 70 | 70 | |
| 71 | 71 | #define NETDEV_MAINCLOCK(_name) \ |
| 72 | | NET_REGISTER_DEV(netdev_mainclock, _name) |
| 72 | NET_REGISTER_DEV(mainclock, _name) |
| 73 | 73 | #define NETDEV_CLOCK(_name) \ |
| 74 | | NET_REGISTER_DEV(netdev_clock, _name) |
| 74 | NET_REGISTER_DEV(clock, _name) |
| 75 | 75 | #define NETDEV_LOGIC_INPUT(_name) \ |
| 76 | | NET_REGISTER_DEV(netdev_logic_input, _name) |
| 76 | NET_REGISTER_DEV(logic_input, _name) |
| 77 | 77 | #define NETDEV_ANALOG_INPUT(_name) \ |
| 78 | | NET_REGISTER_DEV(netdev_analog_input, _name) |
| 78 | NET_REGISTER_DEV(analog_input, _name) |
| 79 | 79 | #define NETDEV_CALLBACK(_name, _IN) \ |
| 80 | | NET_REGISTER_DEV(netdev_analog_callback, _name) \ |
| 80 | NET_REGISTER_DEV(analog_callback, _name) \ |
| 81 | 81 | NET_CONNECT(_name, IN, _IN) |
| 82 | 82 | #define NETDEV_SWITCH2(_name, _i1, _i2) \ |
| 83 | 83 | NET_REGISTER_DEV(nicMultiSwitch, _name) \ |
| 84 | 84 | NET_CONNECT(_name, i1, _i1) \ |
| 85 | 85 | NET_CONNECT(_name, i2, _i2) |
| 86 | 86 | #define NETDEV_DELAY_RISE(_name, _CLK, _D) \ |
| 87 | | NET_REGISTER_DEV(netdev_delay_lh, _name) \ |
| 87 | NET_REGISTER_DEV(delay_lh, _name) \ |
| 88 | 88 | NET_CONNECT(_name, CLK, _CLK) \ |
| 89 | 89 | NET_CONNECT(_name, D, _D) |
| 90 | 90 | #define NETDEV_RSFF(_name, _S, _R) \ |
| r26109 | r26110 | |
| 93 | 93 | NET_CONNECT(_name, R, _R) |
| 94 | 94 | |
| 95 | 95 | #define NETDEV_LOG(_name, _I) \ |
| 96 | | NET_REGISTER_DEV(netdev_log, _name) \ |
| 96 | NET_REGISTER_DEV(log, _name) \ |
| 97 | 97 | NET_CONNECT(_name, I, _I) |
| 98 | 98 | |
| 99 | 99 | |
| r26109 | r26110 | |
| 223 | 223 | // Special support devices ... |
| 224 | 224 | // ---------------------------------------------------------------------------------------- |
| 225 | 225 | |
| 226 | | NETLIB_DEVICE(netdev_logic_input, |
| 227 | | ttl_output_t m_Q; |
| 226 | NETLIB_DEVICE(logic_input, |
| 227 | netlist_ttl_output_t m_Q; |
| 228 | 228 | ); |
| 229 | 229 | |
| 230 | | NETLIB_DEVICE(netdev_analog_input, |
| 231 | | analog_output_t m_Q; |
| 230 | NETLIB_DEVICE(analog_input, |
| 231 | netlist_analog_output_t m_Q; |
| 232 | 232 | ); |
| 233 | 233 | |
| 234 | | NETLIB_DEVICE(netdev_log, |
| 235 | | ttl_input_t m_I; |
| 234 | NETLIB_DEVICE(log, |
| 235 | netlist_ttl_input_t m_I; |
| 236 | 236 | ); |
| 237 | 237 | |
| 238 | 238 | |
| r26109 | r26110 | |
| 241 | 241 | // ---------------------------------------------------------------------------------------- |
| 242 | 242 | |
| 243 | 243 | |
| 244 | | NETLIB_DEVICE_WITH_PARAMS(netdev_clock, |
| 245 | | ttl_input_t m_feedback; |
| 246 | | ttl_output_t m_Q; |
| 244 | NETLIB_DEVICE_WITH_PARAMS(clock, |
| 245 | netlist_ttl_input_t m_feedback; |
| 246 | netlist_ttl_output_t m_Q; |
| 247 | 247 | |
| 248 | | net_param_t m_freq; |
| 248 | netlist_param_t m_freq; |
| 249 | 249 | netlist_time m_inc; |
| 250 | 250 | ); |
| 251 | 251 | |
| 252 | 252 | NETLIB_DEVICE_WITH_PARAMS(nicMultiSwitch, |
| 253 | | analog_input_t m_I[8]; |
| 253 | netlist_analog_input_t m_I[8]; |
| 254 | 254 | |
| 255 | | analog_output_t m_Q; |
| 256 | | analog_output_t m_low; |
| 255 | netlist_analog_output_t m_Q; |
| 256 | netlist_analog_output_t m_low; |
| 257 | 257 | |
| 258 | | net_param_t m_POS; |
| 258 | netlist_param_t m_POS; |
| 259 | 259 | |
| 260 | 260 | int m_position; |
| 261 | 261 | ); |
| 262 | 262 | |
| 263 | 263 | NETLIB_DEVICE(nicRSFF, |
| 264 | | ttl_input_t m_S; |
| 265 | | ttl_input_t m_R; |
| 264 | netlist_ttl_input_t m_S; |
| 265 | netlist_ttl_input_t m_R; |
| 266 | 266 | |
| 267 | | ttl_output_t m_Q; |
| 268 | | ttl_output_t m_QQ; |
| 267 | netlist_ttl_output_t m_Q; |
| 268 | netlist_ttl_output_t m_QQ; |
| 269 | 269 | ); |
| 270 | 270 | |
| 271 | 271 | NETLIB_DEVICE_WITH_PARAMS(nicMixer8, |
| 272 | | analog_input_t m_I[8]; |
| 272 | netlist_analog_input_t m_I[8]; |
| 273 | 273 | |
| 274 | | analog_output_t m_Q; |
| 275 | | analog_output_t m_low; |
| 274 | netlist_analog_output_t m_Q; |
| 275 | netlist_analog_output_t m_low; |
| 276 | 276 | |
| 277 | | net_param_t m_R[8]; |
| 277 | netlist_param_t m_R[8]; |
| 278 | 278 | |
| 279 | 279 | double m_w[8]; |
| 280 | 280 | ); |
| r26109 | r26110 | |
| 287 | 287 | |
| 288 | 288 | //ATTR_HOT void timer_cb(INT32 timer_id); |
| 289 | 289 | |
| 290 | | analog_input_t m_trigger; |
| 291 | | analog_input_t m_CV; |
| 292 | | analog_input_t m_THRESHOLD; /* internal */ |
| 290 | netlist_analog_input_t m_trigger; |
| 291 | netlist_analog_input_t m_CV; |
| 292 | netlist_analog_input_t m_THRESHOLD; /* internal */ |
| 293 | 293 | |
| 294 | 294 | bool m_last; |
| 295 | 295 | |
| 296 | | analog_output_t m_Q; |
| 297 | | analog_output_t m_THRESHOLD_OUT; /* internal */ |
| 296 | netlist_analog_output_t m_Q; |
| 297 | netlist_analog_output_t m_THRESHOLD_OUT; /* internal */ |
| 298 | 298 | |
| 299 | 299 | //netlist_base_timer_t *m_timer; |
| 300 | | net_param_t m_R; |
| 301 | | net_param_t m_C; |
| 302 | | net_param_t m_VS; |
| 303 | | net_param_t m_VL; |
| 300 | netlist_param_t m_R; |
| 301 | netlist_param_t m_C; |
| 302 | netlist_param_t m_VS; |
| 303 | netlist_param_t m_VL; |
| 304 | 304 | ); |
| 305 | 305 | |
| 306 | 306 | NETLIB_SIGNAL(nic7430, 8, 0, 0); |
| 307 | 307 | |
| 308 | 308 | NETLIB_DEVICE(nic7404, |
| 309 | | ttl_input_t m_I; |
| 310 | | ttl_output_t m_Q; |
| 309 | netlist_ttl_input_t m_I; |
| 310 | netlist_ttl_output_t m_Q; |
| 311 | 311 | ); |
| 312 | 312 | |
| 313 | 313 | NETLIB_DEVICE(nic7450, |
| 314 | | ttl_input_t m_I0; |
| 315 | | ttl_input_t m_I1; |
| 316 | | ttl_input_t m_I2; |
| 317 | | ttl_input_t m_I3; |
| 318 | | ttl_output_t m_Q; |
| 314 | netlist_ttl_input_t m_I0; |
| 315 | netlist_ttl_input_t m_I1; |
| 316 | netlist_ttl_input_t m_I2; |
| 317 | netlist_ttl_input_t m_I3; |
| 318 | netlist_ttl_output_t m_Q; |
| 319 | 319 | ); |
| 320 | 320 | |
| 321 | 321 | NETLIB_SUBDEVICE(nic7474sub, |
| 322 | | ttl_input_t m_clk; |
| 322 | netlist_ttl_input_t m_clk; |
| 323 | 323 | |
| 324 | 324 | UINT8 m_nextD; |
| 325 | | ttl_output_t m_Q; |
| 326 | | ttl_output_t m_QQ; |
| 325 | netlist_ttl_output_t m_Q; |
| 326 | netlist_ttl_output_t m_QQ; |
| 327 | 327 | |
| 328 | 328 | ATTR_HOT inline void newstate(const UINT8 state); |
| 329 | 329 | ); |
| r26109 | r26110 | |
| 331 | 331 | NETLIB_DEVICE(nic7474, |
| 332 | 332 | NETLIB_NAME(nic7474sub) sub; |
| 333 | 333 | |
| 334 | | ttl_input_t m_D; |
| 335 | | ttl_input_t m_clrQ; |
| 336 | | ttl_input_t m_preQ; |
| 334 | netlist_ttl_input_t m_D; |
| 335 | netlist_ttl_input_t m_clrQ; |
| 336 | netlist_ttl_input_t m_preQ; |
| 337 | 337 | ); |
| 338 | 338 | |
| 339 | 339 | NETLIB_DEVICE(nic7486, |
| 340 | | ttl_input_t m_I0; |
| 341 | | ttl_input_t m_I1; |
| 342 | | ttl_output_t m_Q; |
| 340 | netlist_ttl_input_t m_I0; |
| 341 | netlist_ttl_input_t m_I1; |
| 342 | netlist_ttl_output_t m_Q; |
| 343 | 343 | ); |
| 344 | 344 | |
| 345 | 345 | /* 74107 does latch data during high ! |
| r26109 | r26110 | |
| 348 | 348 | |
| 349 | 349 | |
| 350 | 350 | NETLIB_SUBDEVICE(nic74107Asub, |
| 351 | | ttl_input_t m_clk; |
| 351 | netlist_ttl_input_t m_clk; |
| 352 | 352 | |
| 353 | | ttl_output_t m_Q; |
| 354 | | ttl_output_t m_QQ; |
| 353 | netlist_ttl_output_t m_Q; |
| 354 | netlist_ttl_output_t m_QQ; |
| 355 | 355 | |
| 356 | 356 | netlist_sig_t m_Q1; |
| 357 | 357 | netlist_sig_t m_Q2; |
| r26109 | r26110 | |
| 364 | 364 | NETLIB_DEVICE(nic74107A, |
| 365 | 365 | NETLIB_NAME(nic74107Asub) sub; |
| 366 | 366 | |
| 367 | | ttl_input_t m_J; |
| 368 | | ttl_input_t m_K; |
| 369 | | ttl_input_t m_clrQ; |
| 367 | netlist_ttl_input_t m_J; |
| 368 | netlist_ttl_input_t m_K; |
| 369 | netlist_ttl_input_t m_clrQ; |
| 370 | 370 | |
| 371 | 371 | ); |
| 372 | 372 | |
| r26109 | r26110 | |
| 380 | 380 | |
| 381 | 381 | |
| 382 | 382 | NETLIB_SUBDEVICE(nic7493ff, |
| 383 | | ttl_input_t m_I; |
| 384 | | ttl_output_t m_Q; |
| 383 | netlist_ttl_input_t m_I; |
| 384 | netlist_ttl_output_t m_Q; |
| 385 | 385 | |
| 386 | 386 | UINT8 m_reset; |
| 387 | 387 | ); |
| 388 | 388 | |
| 389 | 389 | #if !USE_OLD7493 |
| 390 | 390 | NETLIB_DEVICE(nic7493, |
| 391 | | ttl_input_t m_R1; |
| 392 | | ttl_input_t m_R2; |
| 391 | netlist_ttl_input_t m_R1; |
| 392 | netlist_ttl_input_t m_R2; |
| 393 | 393 | |
| 394 | 394 | NETLIB_NAME(nic7493ff) A; |
| 395 | 395 | NETLIB_NAME(nic7493ff) B; |
| r26109 | r26110 | |
| 399 | 399 | |
| 400 | 400 | #else |
| 401 | 401 | NETLIB_DEVICE(nic7493, |
| 402 | | ttl_input_t m_CLK; |
| 403 | | ttl_input_t m_CLKB; /* dummy ! */ |
| 404 | | ttl_input_t m_R1; |
| 405 | | ttl_input_t m_R2; |
| 402 | netlist_ttl_input_t m_CLK; |
| 403 | netlist_ttl_input_t m_CLKB; /* dummy ! */ |
| 404 | netlist_ttl_input_t m_R1; |
| 405 | netlist_ttl_input_t m_R2; |
| 406 | 406 | |
| 407 | | ttl_output_t m_QA; |
| 408 | | ttl_output_t m_QB; |
| 409 | | ttl_output_t m_QC; |
| 410 | | ttl_output_t m_QD; |
| 407 | netlist_ttl_output_t m_QA; |
| 408 | netlist_ttl_output_t m_QB; |
| 409 | netlist_ttl_output_t m_QC; |
| 410 | netlist_ttl_output_t m_QD; |
| 411 | 411 | |
| 412 | 412 | UINT8 m_cnt; |
| 413 | 413 | ATTR_HOT void update_outputs(); |
| r26109 | r26110 | |
| 417 | 417 | NETLIB_DEVICE(nic7490, |
| 418 | 418 | ATTR_HOT void update_outputs(); |
| 419 | 419 | |
| 420 | | ttl_input_t m_R1; |
| 421 | | ttl_input_t m_R2; |
| 422 | | ttl_input_t m_R91; |
| 423 | | ttl_input_t m_R92; |
| 424 | | ttl_input_t m_clk; |
| 420 | netlist_ttl_input_t m_R1; |
| 421 | netlist_ttl_input_t m_R2; |
| 422 | netlist_ttl_input_t m_R91; |
| 423 | netlist_ttl_input_t m_R92; |
| 424 | netlist_ttl_input_t m_clk; |
| 425 | 425 | |
| 426 | 426 | UINT8 m_cnt; |
| 427 | 427 | |
| 428 | | ttl_output_t m_Q[4]; |
| 428 | netlist_ttl_output_t m_Q[4]; |
| 429 | 429 | ); |
| 430 | 430 | |
| 431 | 431 | /* ripple-carry counter on low-high clock transition */ |
| r26109 | r26110 | |
| 434 | 434 | ATTR_HOT void update_outputs_all(); |
| 435 | 435 | ATTR_HOT void update_outputs(); |
| 436 | 436 | |
| 437 | | ttl_input_t m_clk; |
| 437 | netlist_ttl_input_t m_clk; |
| 438 | 438 | |
| 439 | | ttl_input_t m_A; |
| 440 | | ttl_input_t m_B; |
| 441 | | ttl_input_t m_C; |
| 442 | | ttl_input_t m_D; |
| 439 | netlist_ttl_input_t m_A; |
| 440 | netlist_ttl_input_t m_B; |
| 441 | netlist_ttl_input_t m_C; |
| 442 | netlist_ttl_input_t m_D; |
| 443 | 443 | |
| 444 | 444 | UINT8 m_cnt; |
| 445 | 445 | netlist_sig_t m_loadq; |
| 446 | 446 | netlist_sig_t m_ent; |
| 447 | 447 | |
| 448 | | ttl_output_t m_QA; |
| 449 | | ttl_output_t m_QB; |
| 450 | | ttl_output_t m_QC; |
| 451 | | ttl_output_t m_QD; |
| 452 | | ttl_output_t m_RC; |
| 448 | netlist_ttl_output_t m_QA; |
| 449 | netlist_ttl_output_t m_QB; |
| 450 | netlist_ttl_output_t m_QC; |
| 451 | netlist_ttl_output_t m_QD; |
| 452 | netlist_ttl_output_t m_RC; |
| 453 | 453 | ); |
| 454 | 454 | |
| 455 | 455 | NETLIB_DEVICE(nic9316, |
| 456 | 456 | NETLIB_NAME(nic9316_sub) sub; |
| 457 | | ttl_input_t m_ENP; |
| 458 | | ttl_input_t m_ENT; |
| 459 | | ttl_input_t m_CLRQ; |
| 460 | | ttl_input_t m_LOADQ; |
| 457 | netlist_ttl_input_t m_ENP; |
| 458 | netlist_ttl_input_t m_ENT; |
| 459 | netlist_ttl_input_t m_CLRQ; |
| 460 | netlist_ttl_input_t m_LOADQ; |
| 461 | 461 | ); |
| 462 | 462 | |
| 463 | 463 | NETLIB_DEVICE(nic7483, |
| 464 | | ttl_input_t m_CI; |
| 465 | | ttl_input_t m_A1; |
| 466 | | ttl_input_t m_A2; |
| 467 | | ttl_input_t m_A3; |
| 468 | | ttl_input_t m_A4; |
| 469 | | ttl_input_t m_B1; |
| 470 | | ttl_input_t m_B2; |
| 471 | | ttl_input_t m_B3; |
| 472 | | ttl_input_t m_B4; |
| 473 | | ttl_input_t m_clk; |
| 464 | netlist_ttl_input_t m_CI; |
| 465 | netlist_ttl_input_t m_A1; |
| 466 | netlist_ttl_input_t m_A2; |
| 467 | netlist_ttl_input_t m_A3; |
| 468 | netlist_ttl_input_t m_A4; |
| 469 | netlist_ttl_input_t m_B1; |
| 470 | netlist_ttl_input_t m_B2; |
| 471 | netlist_ttl_input_t m_B3; |
| 472 | netlist_ttl_input_t m_B4; |
| 473 | netlist_ttl_input_t m_clk; |
| 474 | 474 | |
| 475 | 475 | UINT8 m_lastr; |
| 476 | 476 | |
| 477 | | ttl_output_t m_SA; |
| 478 | | ttl_output_t m_SB; |
| 479 | | ttl_output_t m_SC; |
| 480 | | ttl_output_t m_SD; |
| 481 | | ttl_output_t m_CO; |
| 477 | netlist_ttl_output_t m_SA; |
| 478 | netlist_ttl_output_t m_SB; |
| 479 | netlist_ttl_output_t m_SC; |
| 480 | netlist_ttl_output_t m_SD; |
| 481 | netlist_ttl_output_t m_CO; |
| 482 | 482 | |
| 483 | 483 | ); |
| 484 | 484 | |
| 485 | 485 | /* one half of a nic74153 */ |
| 486 | 486 | |
| 487 | 487 | NETLIB_DEVICE(nic74153, |
| 488 | | ttl_input_t m_I[4]; |
| 489 | | ttl_input_t m_A; |
| 490 | | ttl_input_t m_B; |
| 491 | | ttl_input_t m_GA; |
| 488 | netlist_ttl_input_t m_I[4]; |
| 489 | netlist_ttl_input_t m_A; |
| 490 | netlist_ttl_input_t m_B; |
| 491 | netlist_ttl_input_t m_GA; |
| 492 | 492 | |
| 493 | | ttl_output_t m_AY; |
| 493 | netlist_ttl_output_t m_AY; |
| 494 | 494 | ); |
| 495 | 495 | |
| 496 | 496 | NETLIB_SUBDEVICE(nic7448_sub, |
| 497 | 497 | ATTR_HOT void update_outputs(UINT8 v); |
| 498 | 498 | static const UINT8 tab7448[16][7]; |
| 499 | 499 | |
| 500 | | ttl_input_t m_A0; |
| 501 | | ttl_input_t m_A1; |
| 502 | | ttl_input_t m_A2; |
| 503 | | ttl_input_t m_A3; |
| 504 | | ttl_input_t m_RBIQ; |
| 500 | netlist_ttl_input_t m_A0; |
| 501 | netlist_ttl_input_t m_A1; |
| 502 | netlist_ttl_input_t m_A2; |
| 503 | netlist_ttl_input_t m_A3; |
| 504 | netlist_ttl_input_t m_RBIQ; |
| 505 | 505 | |
| 506 | 506 | UINT8 m_state; |
| 507 | 507 | |
| 508 | | ttl_output_t m_a; |
| 509 | | ttl_output_t m_b; |
| 510 | | ttl_output_t m_c; |
| 511 | | ttl_output_t m_d; |
| 512 | | ttl_output_t m_e; |
| 513 | | ttl_output_t m_f; |
| 514 | | ttl_output_t m_g; |
| 508 | netlist_ttl_output_t m_a; |
| 509 | netlist_ttl_output_t m_b; |
| 510 | netlist_ttl_output_t m_c; |
| 511 | netlist_ttl_output_t m_d; |
| 512 | netlist_ttl_output_t m_e; |
| 513 | netlist_ttl_output_t m_f; |
| 514 | netlist_ttl_output_t m_g; |
| 515 | 515 | ); |
| 516 | 516 | |
| 517 | 517 | NETLIB_DEVICE(nic7448, |
| 518 | 518 | |
| 519 | 519 | NETLIB_NAME(nic7448_sub) sub; |
| 520 | 520 | |
| 521 | | ttl_input_t m_LTQ; |
| 522 | | ttl_input_t m_BIQ; |
| 521 | netlist_ttl_input_t m_LTQ; |
| 522 | netlist_ttl_input_t m_BIQ; |
| 523 | 523 | ); |
| 524 | 524 | |
| 525 | 525 | #endif |