local ffi = FFI or require("ffi") Gate = {} ffi.cdef [[ struct OutPort { struct Net* net; int state; }; struct Gate { int in_queue; struct OutPort ports[0]; }; ]] function Gate.new(objref, definition) local gate = { -- Logic Critical c = nil, logic = definition.logic, ports = {}, port_nets = {}, objref = objref, definition = definition, } local cdata = ffi.new("char["..(ffi.sizeof("struct Gate") + ffi.sizeof("struct OutPort")*(#definition.ports+1)).."]") gate.c = ffi.cast("struct Gate*", cdata) gate.c.in_queue = 0 return gate end -- Logic Critical function Gate.getportstate(gate, index) return gate.c.ports[index].state end -- Logic Critical function Gate.setportstate(gate, index, state) if state ~= gate.c.ports[index].state then local group = gate.port_nets[index] group.state_num = group.state_num - gate.c.ports[index].state + state gate.c.ports[index].state = state if ((group.state_num>0) ~= (group.state==1)) and (group.in_queue==0) then Simulation.queuegroup(GSim, group) end end end -- Logic Critical function Gate.logic(gate) gate.logic(gate) end function Gate.preinit(gate) end function Gate.initdata(gate) gate.data = {} end function Gate.getdata(gate) return gate.data end function Gate.getportisrising(gate, index) return Port.isrising(gate.ports[index]) end function Gate.getportisfalling(gate, index) return Port.isfalling(gate.ports[index]) end function Gate.cb(gate, ...) Simulation.queuecallback(GSim, gate, ...) end function Gate.queue(gate, delay) Simulation.queuegatelater(GSim, gate, delay) end function Gate.gettick(gate) return GSim.current_tick end function Gate.getdefinition(gate) return gate.definition end -- Logic functions function Gate.init(gate) Gate.getdefinition(gate).init(gate) end function Gate.input(gate, argv) Gate.getdefinition(gate).input(gate, argv) end