diff --git a/sim/compiled_sim.c b/sim/compiled_sim.c index 3a2eb51..09b28bd 100644 --- a/sim/compiled_sim.c +++ b/sim/compiled_sim.c @@ -12,6 +12,9 @@ struct Gate { int** port_net_in_queue; struct Net** port_nets_c; int objref; + int logic_function; + int data_size; + int* data; }; struct Net { int* state; @@ -23,16 +26,35 @@ struct Net { int id; }; - -void sim_set_data(struct Net** net_queue, int* num_net_queue, struct Gate** gate_queue, int* num_gate_queue, int* current_tick, int queue_max); -void sim_update_nets(); - struct Net** net_queue; int* num_net_queue; struct Gate** gate_queue; int* num_gate_queue; int* current_tick; -int queue_max; +static const int queue_max = 65536; + +typedef void(*GateFunc)(struct Gate*); +int sim_gate_get_port(struct Gate* gate, int port); +void sim_gate_set_port(struct Gate* gate, int port, int val); +int sim_gate_get_data(struct Gate* gate, int addr); +void sim_gate_set_data(struct Gate* gate, int addr, int val); +#define GATEFUNCID(name) GateFunc_##name##_F +#define GATEFUNC(name) void GATEFUNCID(name)(struct Gate* gate) +#define setport(i, v) sim_gate_set_port(gate, i, v) +#define getport(i) sim_gate_get_port(gate, i) +#define setdata(i, v) sim_gate_set_data(gate, i, v) +#define getdata(i) sim_gate_get_data(gate, i) + +#include "compiled_sim_gates.c" + +#undef setport +#undef getport + +void sim_set_data(struct Net** net_queue, int* num_net_queue, struct Gate** gate_queue, int* num_gate_queue, int* current_tick, int queue_max); +void sim_update_nets(); +void sim_update_gates(); + +//// void sim_set_data(struct Net** net_queue_in, int* num_net_queue_in, struct Gate** gate_queue_in, int* num_gate_queue_in, int* current_tick_in, int queue_max_in) { net_queue = net_queue_in; @@ -40,7 +62,7 @@ void sim_set_data(struct Net** net_queue_in, int* num_net_queue_in, struct Gate* gate_queue = gate_queue_in; num_gate_queue = num_gate_queue_in; current_tick = current_tick_in; - queue_max = queue_max_in; + //queue_max = queue_max_in; } void sim_update_net(struct Net* net); @@ -54,14 +76,39 @@ void sim_update_nets() { *num_net_queue = 0; } +void sim_update_gate(struct Gate* gate); +void sim_dequeue_gate(int i) { + gate_queue[i] = gate_queue[*num_gate_queue-1]; + gate_queue[*num_gate_queue-1] = 0; + (*num_gate_queue)--; +} +void sim_update_gates() { + for(int i=0; i<*num_gate_queue; i++) { + struct Gate* gate = gate_queue[i]; + if(gate->logic_function != 0) { + sim_dequeue_gate(i); + sim_logic_functions[gate->logic_function](gate); + i--; + } + } +} + //// void sim_queue_gate(struct Gate* gate) { - assert(*num_gate_queue < queue_max); - gate_queue[*num_gate_queue++] = gate; + assert(*num_gate_queue < queue_max - 1); + gate_queue[(*num_gate_queue)++] = gate; *(gate->in_queue) = 1; } +void sim_queue_net(struct Net* net) { + assert(*num_net_queue < queue_max - 1); + net_queue[(*num_net_queue)++] = net; + *(net->in_queue) = 1; +} + +//// + void sim_update_net(struct Net* net) { int state = *(net->state_num) > 0; if(state != *(net->state)) { @@ -76,3 +123,29 @@ void sim_update_net(struct Net* net) { } } } + +//// + +int sim_gate_get_port(struct Gate* gate, int port) { + return *(gate->port_net_state[port]); +} +void sim_gate_set_port(struct Gate* gate, int port, int state) { + if(state != gate->port_states[port]) { + *(gate->port_net_state_num[port]) += state - gate->port_states[port]; + gate->port_states[port] = state; + + if( + ( (*(gate->port_net_state_num[port]) > 0) != *(gate->port_net_state[port]) ) && + ( !*(gate->port_net_in_queue[port]) ) + ) { + sim_queue_net(gate->port_nets_c[port]); + } + } +} + +int sim_gate_get_data(struct Gate* gate, int addr) { + return gate->data[addr]; +} +void sim_gate_set_data(struct Gate* gate, int addr, int val) { + gate->data[addr] = val; +} diff --git a/sim/compiled_sim.dll b/sim/compiled_sim.dll index 1df7ad1..0f5eb7f 100644 Binary files a/sim/compiled_sim.dll and b/sim/compiled_sim.dll differ diff --git a/sim/compiled_sim_gates.c b/sim/compiled_sim_gates.c new file mode 100644 index 0000000..f7a7213 --- /dev/null +++ b/sim/compiled_sim_gates.c @@ -0,0 +1,21 @@ + +GATEFUNC(Diode) { + setport(2, getport(1)); +} +GATEFUNC(Not) { + setport(2, !getport(1)); +} + +//// + +enum GateFuncs { + GateFunc_None, + GateFunc_Diode, + GateFunc_Not, +}; + +GateFunc sim_logic_functions[] = { + 0, + GATEFUNCID(Diode), + GATEFUNCID(Not), +}; diff --git a/sim/gate.lua b/sim/gate.lua index 56a8537..0d9e609 100644 --- a/sim/gate.lua +++ b/sim/gate.lua @@ -13,6 +13,9 @@ ffi.cdef [[ int** port_net_in_queue; struct Net** port_nets_c; int objref; + int logic_function; + int data_size; + int* data; }; ]] @@ -34,6 +37,10 @@ function Gate.new(objref, definition) } gate.in_queue[0] = 0 + if definition.data_size_c > 0 then + gate.data_c = ffi.new("int["..(definition.data_size_c).."]") + end + gate.c = ffi.new("struct Gate") gate.c.in_queue = gate.in_queue gate.c.port_states = gate.port_states @@ -42,6 +49,9 @@ function Gate.new(objref, definition) gate.c.port_net_in_queue = gate.port_net_in_queue gate.c.port_nets_c = gate.port_nets_c gate.c.objref = gate.objref + gate.c.logic_function = definition.logic_function_c + gate.c.data_size = definition.data_size_c + gate.c.data = gate.data_c return gate end diff --git a/sim/gatedef.lua b/sim/gatedef.lua index 9c4cf21..d654ce2 100644 --- a/sim/gatedef.lua +++ b/sim/gatedef.lua @@ -13,9 +13,6 @@ function GateDefinition.new(objref, name, description, init, logic, input, globa input = collapseescape(input) global = collapseescape(global) description = collapseescape(description) - --code = collapseescape(code) - - --local compiled_size, compiled_code = Simulation.compile_code(nil, code) local def = { objref = objref, @@ -24,8 +21,8 @@ function GateDefinition.new(objref, name, description, init, logic, input, globa ports = ports or {}, num_in_ports = 0, num_out_ports = 0, - --compiled_program_code = compiled_code, - --compiled_program_size = compiled_size, + data_size_c = 0, -- todo + logic_function_c = 0, -- todo } local initfunc = loadstring(tostring(init)) diff --git a/sim/network.lua b/sim/network.lua index 2732921..ecfad58 100644 --- a/sim/network.lua +++ b/sim/network.lua @@ -73,7 +73,6 @@ function network_update() local logic = data[i+5] local input = data[i+6] local global = data[i+7] - --local code = data[i+8] local numports = tonumber(data[i+8]) local ports = {} diff --git a/sim/simulation.lua b/sim/simulation.lua index 466003a..57f9b06 100644 --- a/sim/simulation.lua +++ b/sim/simulation.lua @@ -6,6 +6,7 @@ ffi.cdef [[ struct Net; void sim_set_data(struct Net** net_queue, int* num_net_queue, struct Gate** gate_queue, int* num_gate_queue, int* current_tick, int queue_max); void sim_update_nets(); + void sim_update_gates(); ]] local csim = ffi.load("compiled_sim.dll") @@ -350,14 +351,6 @@ end -- Logic Critical function Simulation.ticklogic(sim) - -- Now implemented in C - --for i = 0, sim.num_groupqueue[0]-1 do - -- local cnet = sim.groupqueue[i] - -- Group.update_c(cnet, sim.current_tick[0]) - -- cnet.in_queue[0] = 0 - -- sim.groupqueue[i] = nil - --end - --sim.num_groupqueue[0] = 0 csim.sim_update_nets() if sim.tickqueue[sim.current_tick[0]] ~= nil then @@ -369,6 +362,7 @@ function Simulation.ticklogic(sim) sim.tickqueue[sim.current_tick[0]] = nil end + csim.sim_update_gates() -- handle any leftover gates, those without c logic functions for i = 0, sim.num_gatequeue[0]-1 do local cgate = sim.gatequeue[i] local gate = Simulation.gate_from_cgate(sim, cgate)