add c gate sim
This commit is contained in:
parent
1d465b09f7
commit
02bfb84cb5
@ -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;
|
||||
}
|
||||
|
Binary file not shown.
21
sim/compiled_sim_gates.c
Normal file
21
sim/compiled_sim_gates.c
Normal file
@ -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),
|
||||
};
|
10
sim/gate.lua
10
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
|
||||
|
@ -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))
|
||||
|
@ -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 = {}
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user