Compare commits

..

78 Commits

Author SHA1 Message Date
Redo
68562d4d66 add math gates, fix 32-bit shifters 2025-02-19 10:15:56 -07:00
Redo
a571ac5f3c add dump to gitignore 2022-11-19 15:48:06 -06:00
Redo
10462e5a6e add ram bricks 2022-11-15 13:52:24 -06:00
Redo
5ae87d926c add basic gates c func 2022-11-15 11:46:09 -06:00
Redo
ef99073b23 fix adder cout 2022-11-15 11:37:37 -06:00
Redo
10b25b3da8 debug prints 2022-11-15 11:33:25 -06:00
Redo
063f6c0d02 add adders to c func 2022-11-14 14:32:32 -06:00
Redo
c9a42b15e2 debug verification in gatedef transmit 2022-11-14 14:32:17 -06:00
Redo
293ed331bd add adders to c func 2022-11-14 14:30:12 -06:00
Redo
5ddbb464d5 fix getword/setword 2022-11-14 13:48:18 -06:00
Redo
7b168dd25b fix 1x rom names 2022-11-14 13:45:35 -06:00
Redo
ff20fdb2d6 add mux, demux, rom 2022-11-14 13:43:24 -06:00
Redo
8ccf6db9b8 fix ref to c data info 2022-11-14 12:49:07 -06:00
Redo
d3ecd34b26 add bus bricks to c logic 2022-11-14 12:48:05 -06:00
Redo
1787444b72 fix bug and remove prints 2022-11-14 11:54:54 -06:00
Redo
042503d87d debug 2022-11-14 11:52:12 -06:00
Redo
4bd4283929 add debug prints to c logic 2022-11-14 11:48:39 -06:00
Redo
a2df8dbf96 add debug prints to c logic 2022-11-14 11:45:03 -06:00
Redo
8c16498ec6 fix 2022-11-13 22:51:12 -06:00
Redo
f5b9e12076 fix 2022-11-13 22:49:31 -06:00
Redo
4465621b44 fix require in includes 2022-11-13 22:45:56 -06:00
Redo
bcebfed077 remove c logic and data from network, more work on compiled gate funcs 2022-11-13 22:43:36 -06:00
Redo
1eba4bb2fa replace dllexport with linux-compatibleE 2022-11-09 13:25:20 -06:00
Redo
2389252698 use const where appropriate 2022-11-09 13:22:06 -06:00
Redo
75299209b8 add c func and data 2022-11-05 13:01:07 -06:00
Redo
f347d1f17d fix ffi absent in gatedef 2022-11-05 12:35:40 -06:00
Redo
4d874d4f7f add native linux compile sh 2022-11-05 12:34:30 -06:00
Redo
a6cc4bbea8 add os detection for lib loading 2022-11-05 12:27:47 -06:00
Redo
7829193f1f add linux compiled sim 2022-11-05 12:25:53 -06:00
Redo
f18b3fae5f use global socket 2022-11-05 12:22:57 -06:00
Redo
bbb6afd684 use path for sim dll 2022-11-05 12:20:38 -06:00
Redo
e294641558 add libcompiled_sim 2022-11-05 02:16:20 -06:00
Redo
ec5714bfc4 make socket and ffi nonlocal 2022-11-05 02:12:45 -06:00
Redo
02bfb84cb5 add c gate sim 2022-11-05 02:11:48 -06:00
Redo
1d465b09f7 compile sim with ofast 2022-11-05 00:41:38 -06:00
Redo
c73fea8cca make net updates c 2022-11-04 23:23:44 -06:00
Redo
17edf2a782 make current tick c 2022-11-04 23:07:43 -06:00
Redo
cbfc8fd42e fix queue types 2022-11-04 22:58:26 -06:00
Redo
2cf3040aa2 make queues c arrays 2022-11-04 22:57:28 -06:00
Redo
e35d0aa5f5 fix queue 0 index 2022-11-04 19:04:30 -06:00
Redo
a83f4f8f8e make queues 0 indexed 2022-11-04 19:03:19 -06:00
Redo
2376154957 make gate update use net c structT 2022-11-04 18:51:18 -06:00
Redo
4b69ea3055 make net tqueue use c structs 2022-11-04 18:48:13 -06:00
Redo
4f2b9f4e6d make gate queue use c structs 2022-11-04 18:43:50 -06:00
Redo
5e0d779600 fix cgate ref 2022-11-04 18:36:11 -06:00
Redo
e8208b2f34 use c structs around queues 2022-11-04 18:35:15 -06:00
Redo
9744345219 fix sim ref in net update 2022-11-04 18:07:17 -06:00
Redo
7d0dcc53a2 make net update use c structT 2022-11-04 18:06:36 -06:00
Redo
bb66be2083 remove group fx queue 2 2022-11-04 18:03:54 -06:00
Redo
ddccf0171f remove fx queue 2022-11-04 18:00:40 -06:00
Redo
0f35ee4d36 fix net c struct ref 2022-11-04 17:40:14 -06:00
Redo
0cb1ef5540 undo c struct queues 2022-11-04 17:22:51 -06:00
Redo
898726af35 fix off by one segfault 2022-11-04 17:13:27 -06:00
Redo
eb05504252 add num gates to net struct 2022-11-04 17:08:05 -06:00
Redo
85aabd8dcf make sim queues use c objs 2022-11-04 17:06:57 -06:00
Redo
658bcc6ad8 add gate/net pointer lists 2022-11-04 16:29:11 -06:00
Redo
5aa11f9e43 make gates use net state pointers 2022-11-04 15:50:45 -06:00
Redo
caa9ed5de3 make net states pointers - fix 2022-11-04 15:40:32 -06:00
Redo
9e0c196b63 make net states pointers 2022-11-04 15:39:08 -06:00
Redo
20b05812df fix typo 2022-11-04 15:33:06 -06:00
Redo
f1b909279c make in_queue int tptre 2022-11-04 15:32:30 -06:00
Redo
7823e413ee fix gate get port state 2022-11-04 15:11:59 -06:00
Redo
b1c5eb1479 remove gate ffi struct 2022-11-04 15:06:50 -06:00
Redo
a9ac30920e fix typo 2022-11-04 15:06:01 -06:00
Redo
a9056df54d remove gate ffi struct 2022-11-04 15:04:49 -06:00
Redo
5438de0adf fix gate struct sizing 2022-11-04 13:21:41 -06:00
Redo
7e19e20caf remove unused call from gate init 2022-11-04 13:16:30 -06:00
Redo
d95447b55d remove code field from gatedef 2022-11-04 13:15:55 -06:00
Redo
7b0dcb8fd7 remove code field from gatedef 2022-11-04 13:15:24 -06:00
Redo
0ac3f3e495 fix errors 2022-11-04 13:14:05 -06:00
Redo
cdbf3ed089 make gates use cdata for critical logic 2022-11-04 13:10:10 -06:00
Redo
07b3decc45 remove debug luaijt arg 2022-10-05 15:44:23 -06:00
Redo0
bcc39d9f20 make input queue stack again 2021-07-24 15:35:00 -05:00
Redo0
7109dd70a2 add rainbow wires 2021-06-07 15:38:25 -05:00
Redo0
bfa1190cfe mark logic critical sections in tables 2021-06-05 19:38:45 -05:00
Redo0
00dc81948d fix bugs with queue inlining; inline gate queue as well 2021-06-05 19:25:09 -05:00
Redo0
d3d03ce9a7 stop clearing queue arrays 2021-06-05 19:02:28 -05:00
Redo0
19d2e36fd6 more optimizations: move port states into gates, inline net queue checks 2021-06-05 18:41:50 -05:00
21 changed files with 22369 additions and 259 deletions

3
.gitignore vendored
View File

@ -1 +1,4 @@
savedata/*
*.so
sim/dump.txt
UploadBackend.bat

View File

@ -1,8 +1,10 @@
@echo off
cd /d I:\Data\games\blockland\mods\lualogic\lua-logic
set savefolder=savedata
if not exist %savefolder% mkdir %savefolder%
set saveloc=%cd%\%savefolder%\
cd "sim"
luajit -jp "main.lua" %saveloc%
rem luajit -jp "main.lua" %saveloc%
luajit "main.lua" %saveloc%
pause

View File

@ -1,49 +0,0 @@
local ffi = FFI or require("ffi")
Simulation = Simulation or {}
ffi.cdef[[
]]
function Simulation.compile(sim)
-- assemble a list of all nets
local all_nets = {}
local all_nets_t = {}
for k, wire in pairs(sim.wires) do
local net = Wire.getgroup(wire)
all_nets_t[net] = net
end
local num_nets = 0
for net_id, net in pairs(all_nets_t) do
table.insert(all_nets, net)
end
-- assemble a list of all gates
local all_gates = {}
for k, gate in pairs(sim.gates) do
table.insert(all_gates, gate)
end
-- construct each gate into an array
-- construct array of all nets
local c_nets = ffi.new("struct Net["..(#all_nets).."]")
for net_idx, net in ipairs(all_nets) do
local c_net = ffi.new("struct Net", #net.gates_update)
for gate_idx, gate in ipairs(net.gates_update) do
end
c_nets[net_idx] = c_net
end
end
function Simulation.decompile(sim)
end
function Simulation.tick_compiled(sim)
end

2
sim/compiled_sim.bat Normal file
View File

@ -0,0 +1,2 @@
gcc compiled_sim.c -o compiled_sim.dll -shared -Wall -Werror -Ofast && objdump -d compiled_sim.dll > dump.txt
pause

View File

@ -1,7 +1,184 @@
void sim_init(int num_gates, int num_nets);
void sim_add_gate();
void sim_add_net();
void sim_tick();
void sim_get_net_state(int objref);
void sim_get_port_state(int objref, int index);
//#include <assert.h>
struct Net;
struct Gate;
struct Gate {
int* in_queue;
int* port_states;
int** port_net_state;
int** port_net_state_num;
int** port_net_in_queue;
struct Net** port_nets_c;
int objref;
int logic_function;
int data_size;
int* data;
};
struct Net {
int* state;
int* state_num;
int* in_queue;
int* update_tick;
int* num_gates_update;
struct Gate** gates_update_c;
int id;
};
#define FAST static inline
#define DLL __attribute__((visibility("default")))
#define GATEFUNCTYPE
typedef void(*GateFunc)(const struct Gate* const gate);
struct Net** net_queue;
int* num_net_queue;
struct Gate** gate_queue;
int* num_gate_queue;
int* current_tick;
//static const int queue_max = 65536;
extern GateFunc sim_logic_functions[];
DLL 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);
DLL void sim_update_nets();
DLL void sim_update_gates();
////
DLL 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;
num_net_queue = num_net_queue_in;
gate_queue = gate_queue_in;
num_gate_queue = num_gate_queue_in;
current_tick = current_tick_in;
//queue_max = queue_max_in;
}
FAST void sim_update_net(const struct Net* const net);
DLL void sim_update_nets() {
for(int i=0; i<*num_net_queue; i++) {
struct Net* net = net_queue[i];
sim_update_net(net);
*(net->in_queue) = 0;
net_queue[i] = 0;
}
*num_net_queue = 0;
}
FAST void sim_dequeue_gate(const int i) {
gate_queue[i] = gate_queue[*num_gate_queue-1];
gate_queue[*num_gate_queue-1] = 0;
(*num_gate_queue)--;
}
DLL 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);
*(gate->in_queue) = 0;
sim_logic_functions[gate->logic_function](gate);
i--;
}
}
}
////
FAST void sim_queue_gate(const struct Gate* const gate) {
//assert(*num_gate_queue < queue_max - 1);
*(gate->in_queue) = 1;
gate_queue[(*num_gate_queue)++] = (struct Gate*)gate;
}
FAST void sim_queue_net(const struct Net* const net) {
//assert(*num_net_queue < queue_max - 1);
*(net->in_queue) = 1;
net_queue[(*num_net_queue)++] = (struct Net*)net;
}
////
FAST void sim_update_net(const struct Net* const net) {
int state = *(net->state_num) > 0;
if(state != *(net->state)) {
*(net->state) = state;
*(net->update_tick) = *current_tick;
for(int i=0; i<*(net->num_gates_update); i++) {
struct Gate* gate = net->gates_update_c[i];
if(!*(gate->in_queue)) {
sim_queue_gate(gate);
}
}
}
}
////
FAST int sim_gate_get_port(const struct Gate* const gate, const int port) {
return *(gate->port_net_state[port]);
}
FAST int sim_gate_get_port_rising(const struct Gate* const gate, const int port) {
return ( *(gate->port_net_state[port])) && ((*(gate->port_nets_c[port]->update_tick) == *current_tick));
}
FAST int sim_gate_get_port_falling(const struct Gate* const gate, const int port) {
return (!*(gate->port_net_state[port])) && ((*(gate->port_nets_c[port]->update_tick) == *current_tick));
}
FAST void sim_gate_set_port(const struct Gate* const gate, const int port, const 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]);
}
}
}
FAST int sim_gate_get_data(const struct Gate* const gate, const int addr) {
//assert(addr>=0 && addr<gate->data_size);
return gate->data[addr];
}
FAST void sim_gate_set_data(const struct Gate* const gate, const int addr, const int val) {
//assert(addr>=0 && addr<gate->data_size);
gate->data[addr] = val;
}
FAST unsigned int sim_gate_get_word(const struct Gate* const gate, const int size, const int idx) {
int val = 0;
for(int i=0; i<size; i++) {
val += sim_gate_get_port(gate, idx+i) << i;
}
return val;
}
FAST void sim_gate_set_word(const struct Gate* const gate, const int size, const int idx, const unsigned int val) {
for(int i=0; i<size; i++) {
sim_gate_set_port(gate, idx+i, (val>>i) & 1);
}
}
FAST void sim_gate_set_word_64(const struct Gate* const gate, const int size, const int idx, const unsigned long long val) {
for(int i=0; i<size; i++) {
sim_gate_set_port(gate, idx+i, (val>>(unsigned long long)i) & 1ull);
}
}
////
#define GATEFUNCID(name) GateFunc_##name##_F
#define GATEFUNC(name) static GATEFUNCTYPE void GATEFUNCID(name)(const struct Gate* const 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)
#define getportrising(i) sim_gate_get_port_rising(gate, i)
#define getportfalling(i) sim_gate_get_port_falling(gate, i)
#define copyword(size, iin, iout) for(int i=0;i<size;i++) { setport(iout+i, getport(iin+i)); }
#define getword(size, idx) sim_gate_get_word(gate, size, idx)
#define clearword(size, idx) for(int i=0;i<size;i++) { setport(idx+i, 0); }
#define setword(size, idx, val) sim_gate_set_word(gate, size, idx, val)
#define setword64(size, idx, val) sim_gate_set_word_64(gate, size, idx, val)
#include "compiled_sim_gates.c"

BIN
sim/compiled_sim.dll Normal file

Binary file not shown.

1
sim/compiled_sim.sh Normal file
View File

@ -0,0 +1 @@
gcc compiled_sim.c -o compiled_sim.so -shared -Wall -Werror -Ofast -fPIC

BIN
sim/compiled_sim.so Normal file

Binary file not shown.

584
sim/compiled_sim_gates.c Normal file
View File

@ -0,0 +1,584 @@
// Auto-generated by gencfuncs.lua
enum GateFuncs {
GateFunc_None,
GateFunc_Diode,
GateFunc_Not,
GateFunc_Enabler1,
GateFunc_Enabler2,
GateFunc_Enabler3,
GateFunc_Enabler4,
GateFunc_Enabler5,
GateFunc_Enabler6,
GateFunc_Enabler7,
GateFunc_Enabler8,
GateFunc_Enabler9,
GateFunc_Enabler10,
GateFunc_Enabler11,
GateFunc_Enabler12,
GateFunc_Enabler13,
GateFunc_Enabler14,
GateFunc_Enabler15,
GateFunc_Enabler16,
GateFunc_Enabler24,
GateFunc_Enabler32,
GateFunc_Enabler48,
GateFunc_Enabler64,
GateFunc_Buffer1,
GateFunc_Buffer2,
GateFunc_Buffer3,
GateFunc_Buffer4,
GateFunc_Buffer5,
GateFunc_Buffer6,
GateFunc_Buffer7,
GateFunc_Buffer8,
GateFunc_Buffer9,
GateFunc_Buffer10,
GateFunc_Buffer11,
GateFunc_Buffer12,
GateFunc_Buffer13,
GateFunc_Buffer14,
GateFunc_Buffer15,
GateFunc_Buffer16,
GateFunc_Buffer24,
GateFunc_Buffer32,
GateFunc_Buffer48,
GateFunc_Buffer64,
GateFunc_DFF1,
GateFunc_DFF2,
GateFunc_DFF3,
GateFunc_DFF4,
GateFunc_DFF5,
GateFunc_DFF6,
GateFunc_DFF7,
GateFunc_DFF8,
GateFunc_DFF9,
GateFunc_DFF10,
GateFunc_DFF11,
GateFunc_DFF12,
GateFunc_DFF13,
GateFunc_DFF14,
GateFunc_DFF15,
GateFunc_DFF16,
GateFunc_DFF24,
GateFunc_DFF32,
GateFunc_DFF48,
GateFunc_DFF64,
GateFunc_Mux1,
GateFunc_Mux2,
GateFunc_Mux3,
GateFunc_Mux4,
GateFunc_Mux5,
GateFunc_Mux6,
GateFunc_Mux7,
GateFunc_Mux8,
GateFunc_Demux1,
GateFunc_Demux2,
GateFunc_Demux3,
GateFunc_Demux4,
GateFunc_Demux5,
GateFunc_Demux6,
GateFunc_Demux7,
GateFunc_Demux8,
GateFunc_Adder2,
GateFunc_Adder4,
GateFunc_Adder8,
GateFunc_Adder16,
GateFunc_Adder32,
GateFunc_Incrementer2,
GateFunc_Incrementer4,
GateFunc_Incrementer8,
GateFunc_Incrementer16,
GateFunc_Incrementer32,
GateFunc_Multiplier2,
GateFunc_Multiplier4,
GateFunc_Multiplier8,
GateFunc_Multiplier16,
GateFunc_Multiplier32,
GateFunc_Divider2,
GateFunc_Divider4,
GateFunc_Divider8,
GateFunc_Divider16,
GateFunc_Divider32,
GateFunc_ShifterLeft2,
GateFunc_ShifterLeft4,
GateFunc_ShifterLeft8,
GateFunc_ShifterLeft16,
GateFunc_ShifterLeft32,
GateFunc_ShifterRight2,
GateFunc_ShifterRight4,
GateFunc_ShifterRight8,
GateFunc_ShifterRight16,
GateFunc_ShifterRight32,
GateFunc_And2,
GateFunc_And3,
GateFunc_And4,
GateFunc_And5,
GateFunc_And6,
GateFunc_And7,
GateFunc_And8,
GateFunc_Or2,
GateFunc_Or3,
GateFunc_Or4,
GateFunc_Or5,
GateFunc_Or6,
GateFunc_Or7,
GateFunc_Or8,
GateFunc_Xor2,
GateFunc_Xor3,
GateFunc_Xor4,
GateFunc_Xor5,
GateFunc_Xor6,
GateFunc_Xor7,
GateFunc_Xor8,
GateFunc_Nand2,
GateFunc_Nand3,
GateFunc_Nand4,
GateFunc_Nand5,
GateFunc_Nand6,
GateFunc_Nand7,
GateFunc_Nand8,
GateFunc_Nor2,
GateFunc_Nor3,
GateFunc_Nor4,
GateFunc_Nor5,
GateFunc_Nor6,
GateFunc_Nor7,
GateFunc_Nor8,
GateFunc_Xnor2,
GateFunc_Xnor3,
GateFunc_Xnor4,
GateFunc_Xnor5,
GateFunc_Xnor6,
GateFunc_Xnor7,
GateFunc_Xnor8,
GateFunc_Rom4x1,
GateFunc_Rom4x4,
GateFunc_Rom4x8,
GateFunc_Rom6x1,
GateFunc_Rom6x4,
GateFunc_Rom6x8,
GateFunc_Rom6x16,
GateFunc_Rom6x32,
GateFunc_Rom6x48,
GateFunc_Rom6x64,
GateFunc_Rom8x1,
GateFunc_Rom8x4,
GateFunc_Rom8x8,
GateFunc_Rom8x16,
GateFunc_Rom8x32,
GateFunc_Rom8x48,
GateFunc_Rom8x64,
GateFunc_Rom9x1,
GateFunc_Rom9x4,
GateFunc_Rom9x8,
GateFunc_Rom9x16,
GateFunc_Rom9x32,
GateFunc_Rom9x48,
GateFunc_Rom9x64,
GateFunc_Rom10x8,
GateFunc_Rom10x16,
GateFunc_Rom10x32,
GateFunc_Rom10x48,
GateFunc_Rom10x64,
GateFunc_Rom11x8,
GateFunc_Rom11x16,
GateFunc_Rom11x32,
GateFunc_Rom11x48,
GateFunc_Rom11x64,
GateFunc_Rom12x8,
GateFunc_Rom12x16,
GateFunc_Rom12x32,
GateFunc_Rom12x48,
GateFunc_Rom12x64,
GateFunc_Ram8x8,
GateFunc_Ram8x12,
};
GATEFUNC(Diode) { setport(2, getport(1)); }
GATEFUNC(Not) { setport(2, !getport(1)); }
GATEFUNC(Enabler1) { if(getport(3)) { copyword(1, 1, 2); } else { clearword(1, 2); } }
GATEFUNC(Enabler2) { if(getport(5)) { copyword(2, 1, 3); } else { clearword(2, 3); } }
GATEFUNC(Enabler3) { if(getport(7)) { copyword(3, 1, 4); } else { clearword(3, 4); } }
GATEFUNC(Enabler4) { if(getport(9)) { copyword(4, 1, 5); } else { clearword(4, 5); } }
GATEFUNC(Enabler5) { if(getport(11)) { copyword(5, 1, 6); } else { clearword(5, 6); } }
GATEFUNC(Enabler6) { if(getport(13)) { copyword(6, 1, 7); } else { clearword(6, 7); } }
GATEFUNC(Enabler7) { if(getport(15)) { copyword(7, 1, 8); } else { clearword(7, 8); } }
GATEFUNC(Enabler8) { if(getport(17)) { copyword(8, 1, 9); } else { clearword(8, 9); } }
GATEFUNC(Enabler9) { if(getport(19)) { copyword(9, 1, 10); } else { clearword(9, 10); } }
GATEFUNC(Enabler10) { if(getport(21)) { copyword(10, 1, 11); } else { clearword(10, 11); } }
GATEFUNC(Enabler11) { if(getport(23)) { copyword(11, 1, 12); } else { clearword(11, 12); } }
GATEFUNC(Enabler12) { if(getport(25)) { copyword(12, 1, 13); } else { clearword(12, 13); } }
GATEFUNC(Enabler13) { if(getport(27)) { copyword(13, 1, 14); } else { clearword(13, 14); } }
GATEFUNC(Enabler14) { if(getport(29)) { copyword(14, 1, 15); } else { clearword(14, 15); } }
GATEFUNC(Enabler15) { if(getport(31)) { copyword(15, 1, 16); } else { clearword(15, 16); } }
GATEFUNC(Enabler16) { if(getport(33)) { copyword(16, 1, 17); } else { clearword(16, 17); } }
GATEFUNC(Enabler24) { if(getport(49)) { copyword(24, 1, 25); } else { clearword(24, 25); } }
GATEFUNC(Enabler32) { if(getport(65)) { copyword(32, 1, 33); } else { clearword(32, 33); } }
GATEFUNC(Enabler48) { if(getport(97)) { copyword(48, 1, 49); } else { clearword(48, 49); } }
GATEFUNC(Enabler64) { if(getport(129)) { copyword(64, 1, 65); } else { clearword(64, 65); } }
GATEFUNC(Buffer1) { if(getport(3)) { copyword(1, 1, 2); } else { clearword(1, 2); } }
GATEFUNC(Buffer2) { if(getport(5)) { copyword(2, 1, 3); } else { clearword(2, 3); } }
GATEFUNC(Buffer3) { if(getport(7)) { copyword(3, 1, 4); } else { clearword(3, 4); } }
GATEFUNC(Buffer4) { if(getport(9)) { copyword(4, 1, 5); } else { clearword(4, 5); } }
GATEFUNC(Buffer5) { if(getport(11)) { copyword(5, 1, 6); } else { clearword(5, 6); } }
GATEFUNC(Buffer6) { if(getport(13)) { copyword(6, 1, 7); } else { clearword(6, 7); } }
GATEFUNC(Buffer7) { if(getport(15)) { copyword(7, 1, 8); } else { clearword(7, 8); } }
GATEFUNC(Buffer8) { if(getport(17)) { copyword(8, 1, 9); } else { clearword(8, 9); } }
GATEFUNC(Buffer9) { if(getport(19)) { copyword(9, 1, 10); } else { clearword(9, 10); } }
GATEFUNC(Buffer10) { if(getport(21)) { copyword(10, 1, 11); } else { clearword(10, 11); } }
GATEFUNC(Buffer11) { if(getport(23)) { copyword(11, 1, 12); } else { clearword(11, 12); } }
GATEFUNC(Buffer12) { if(getport(25)) { copyword(12, 1, 13); } else { clearword(12, 13); } }
GATEFUNC(Buffer13) { if(getport(27)) { copyword(13, 1, 14); } else { clearword(13, 14); } }
GATEFUNC(Buffer14) { if(getport(29)) { copyword(14, 1, 15); } else { clearword(14, 15); } }
GATEFUNC(Buffer15) { if(getport(31)) { copyword(15, 1, 16); } else { clearword(15, 16); } }
GATEFUNC(Buffer16) { if(getport(33)) { copyword(16, 1, 17); } else { clearword(16, 17); } }
GATEFUNC(Buffer24) { if(getport(49)) { copyword(24, 1, 25); } else { clearword(24, 25); } }
GATEFUNC(Buffer32) { if(getport(65)) { copyword(32, 1, 33); } else { clearword(32, 33); } }
GATEFUNC(Buffer48) { if(getport(97)) { copyword(48, 1, 49); } else { clearword(48, 49); } }
GATEFUNC(Buffer64) { if(getport(129)) { copyword(64, 1, 65); } else { clearword(64, 65); } }
GATEFUNC(DFF1) { if(getport(3)) { copyword(1, 1, 2); } }
GATEFUNC(DFF2) { if(getport(5)) { copyword(2, 1, 3); } }
GATEFUNC(DFF3) { if(getport(7)) { copyword(3, 1, 4); } }
GATEFUNC(DFF4) { if(getport(9)) { copyword(4, 1, 5); } }
GATEFUNC(DFF5) { if(getport(11)) { copyword(5, 1, 6); } }
GATEFUNC(DFF6) { if(getport(13)) { copyword(6, 1, 7); } }
GATEFUNC(DFF7) { if(getport(15)) { copyword(7, 1, 8); } }
GATEFUNC(DFF8) { if(getport(17)) { copyword(8, 1, 9); } }
GATEFUNC(DFF9) { if(getport(19)) { copyword(9, 1, 10); } }
GATEFUNC(DFF10) { if(getport(21)) { copyword(10, 1, 11); } }
GATEFUNC(DFF11) { if(getport(23)) { copyword(11, 1, 12); } }
GATEFUNC(DFF12) { if(getport(25)) { copyword(12, 1, 13); } }
GATEFUNC(DFF13) { if(getport(27)) { copyword(13, 1, 14); } }
GATEFUNC(DFF14) { if(getport(29)) { copyword(14, 1, 15); } }
GATEFUNC(DFF15) { if(getport(31)) { copyword(15, 1, 16); } }
GATEFUNC(DFF16) { if(getport(33)) { copyword(16, 1, 17); } }
GATEFUNC(DFF24) { if(getport(49)) { copyword(24, 1, 25); } }
GATEFUNC(DFF32) { if(getport(65)) { copyword(32, 1, 33); } }
GATEFUNC(DFF48) { if(getport(97)) { copyword(48, 1, 49); } }
GATEFUNC(DFF64) { if(getport(129)) { copyword(64, 1, 65); } }
GATEFUNC(Mux1) { if(getport(4)) { setport(5, getport(getword(1, 1)+2)); } else { setport(5, 0); } }
GATEFUNC(Mux2) { if(getport(7)) { setport(8, getport(getword(2, 1)+3)); } else { setport(8, 0); } }
GATEFUNC(Mux3) { if(getport(12)) { setport(13, getport(getword(3, 1)+4)); } else { setport(13, 0); } }
GATEFUNC(Mux4) { if(getport(21)) { setport(22, getport(getword(4, 1)+5)); } else { setport(22, 0); } }
GATEFUNC(Mux5) { if(getport(38)) { setport(39, getport(getword(5, 1)+6)); } else { setport(39, 0); } }
GATEFUNC(Mux6) { if(getport(71)) { setport(72, getport(getword(6, 1)+7)); } else { setport(72, 0); } }
GATEFUNC(Mux7) { if(getport(136)) { setport(137, getport(getword(7, 1)+8)); } else { setport(137, 0); } }
GATEFUNC(Mux8) { if(getport(265)) { setport(266, getport(getword(8, 1)+9)); } else { setport(266, 0); } }
GATEFUNC(Demux1) { int pa = getdata(0); if(getport(4)) { int a = getword(1, 1) + 2; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } } }
GATEFUNC(Demux2) { int pa = getdata(0); if(getport(7)) { int a = getword(2, 1) + 3; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } } }
GATEFUNC(Demux3) { int pa = getdata(0); if(getport(12)) { int a = getword(3, 1) + 4; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } } }
GATEFUNC(Demux4) { int pa = getdata(0); if(getport(21)) { int a = getword(4, 1) + 5; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } } }
GATEFUNC(Demux5) { int pa = getdata(0); if(getport(38)) { int a = getword(5, 1) + 6; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } } }
GATEFUNC(Demux6) { int pa = getdata(0); if(getport(71)) { int a = getword(6, 1) + 7; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } } }
GATEFUNC(Demux7) { int pa = getdata(0); if(getport(136)) { int a = getword(7, 1) + 8; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } } }
GATEFUNC(Demux8) { int pa = getdata(0); if(getport(265)) { int a = getword(8, 1) + 9; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } } }
GATEFUNC(Adder2) { unsigned int v = getword(2, 1) + (getword(2, 3)^(getport(9)*3)) + getport(7); setword(2, 5, v); setport(8, (v>>2) & 1); }
GATEFUNC(Adder4) { unsigned int v = getword(4, 1) + (getword(4, 5)^(getport(15)*15)) + getport(13); setword(4, 9, v); setport(14, (v>>4) & 1); }
GATEFUNC(Adder8) { unsigned int v = getword(8, 1) + (getword(8, 9)^(getport(27)*255)) + getport(25); setword(8, 17, v); setport(26, (v>>8) & 1); }
GATEFUNC(Adder16) { unsigned int v = getword(16, 1) + (getword(16, 17)^(getport(51)*65535)) + getport(49); setword(16, 33, v); setport(50, (v>>16) & 1); }
GATEFUNC(Adder32) { unsigned long long v = (unsigned long long)getword(32, 1) + (unsigned long long)(getword(32, 33)^(getport(99)*4294967295)) + (unsigned long long)getport(97); setword(32, 65, v); setport(98, (v>>32ull) & 1); }
GATEFUNC(Incrementer2) { unsigned int a = (getword(2, 1)^(getport(8)*3)) + getport(5) + (getport(6)*3); setword(2, 3, a); setport(7, (a>>2) & 1); }
GATEFUNC(Incrementer4) { unsigned int a = (getword(4, 1)^(getport(12)*15)) + getport(9) + (getport(10)*15); setword(4, 5, a); setport(11, (a>>4) & 1); }
GATEFUNC(Incrementer8) { unsigned int a = (getword(8, 1)^(getport(20)*255)) + getport(17) + (getport(18)*255); setword(8, 9, a); setport(19, (a>>8) & 1); }
GATEFUNC(Incrementer16) { unsigned int a = (getword(16, 1)^(getport(36)*65535)) + getport(33) + (getport(34)*65535); setword(16, 17, a); setport(35, (a>>16) & 1); }
GATEFUNC(Incrementer32) { unsigned long long a = (unsigned long long)(getword(32, 1)^(getport(68)*4294967295)) + (unsigned long long)getport(65) + (unsigned long long)(getport(66)*4294967295); setword(32, 33, a); setport(67, (a>>32ull) & 1); }
GATEFUNC(Multiplier2) { setword(4, 5, getword(2, 1) * getword(2, 3)); }
GATEFUNC(Multiplier4) { setword(8, 9, getword(4, 1) * getword(4, 5)); }
GATEFUNC(Multiplier8) { setword(16, 17, getword(8, 1) * getword(8, 9)); }
GATEFUNC(Multiplier16) { setword(32, 33, getword(16, 1) * getword(16, 17)); }
GATEFUNC(Multiplier32) { setword64(64, 65, (unsigned long long)getword(32, 1) * (unsigned long long)getword(32, 33)); }
GATEFUNC(Divider2) { unsigned int a = getword(2, 1); unsigned int b = getword(2, 3); setword(2, 5, b!=0 ? a/b : 0); setword(2, 7, b!=0 ? a%b : 0); }
GATEFUNC(Divider4) { unsigned int a = getword(4, 1); unsigned int b = getword(4, 5); setword(4, 9, b!=0 ? a/b : 0); setword(4, 13, b!=0 ? a%b : 0); }
GATEFUNC(Divider8) { unsigned int a = getword(8, 1); unsigned int b = getword(8, 9); setword(8, 17, b!=0 ? a/b : 0); setword(8, 25, b!=0 ? a%b : 0); }
GATEFUNC(Divider16) { unsigned int a = getword(16, 1); unsigned int b = getword(16, 17); setword(16, 33, b!=0 ? a/b : 0); setword(16, 49, b!=0 ? a%b : 0); }
GATEFUNC(Divider32) { unsigned int a = getword(32, 1); unsigned int b = getword(32, 33); setword(32, 65, b!=0 ? a/b : 0); setword(32, 97, b!=0 ? a%b : 0); }
GATEFUNC(ShifterLeft2) { int dist = getword(1, 7); setword(4, 3, ((getword(2, 1))<<dist) | (getport(8) ? (3>>(2-dist)) : 0)); }
GATEFUNC(ShifterLeft4) { int dist = getword(2, 13); setword(8, 5, ((getword(4, 1))<<dist) | (getport(15) ? (15>>(4-dist)) : 0)); }
GATEFUNC(ShifterLeft8) { int dist = getword(3, 25); setword(16, 9, ((getword(8, 1))<<dist) | (getport(28) ? (255>>(8-dist)) : 0)); }
GATEFUNC(ShifterLeft16) { int dist = getword(4, 49); setword(32, 17, ((getword(16, 1))<<dist) | (getport(53) ? (65535>>(16-dist)) : 0)); }
GATEFUNC(ShifterLeft32) { int dist = getword(5, 97); setword64(64, 33, (((unsigned long long)getword(32, 1))<<dist) | (getport(102) ? (4294967295ull>>(32-dist)) : 0ull)); }
GATEFUNC(ShifterRight2) { int dist = getword(1, 7); setword(4, 3, ((getword(2, 1))<<(2-dist)) | (getport(8) ? (3<<(4-dist)) : 0)); }
GATEFUNC(ShifterRight4) { int dist = getword(2, 13); setword(8, 5, ((getword(4, 1))<<(4-dist)) | (getport(15) ? (15<<(8-dist)) : 0)); }
GATEFUNC(ShifterRight8) { int dist = getword(3, 25); setword(16, 9, ((getword(8, 1))<<(8-dist)) | (getport(28) ? (255<<(16-dist)) : 0)); }
GATEFUNC(ShifterRight16) { int dist = getword(4, 49); setword(32, 17, ((getword(16, 1))<<(16-dist)) | (dist!=0 && getport(53) ? (65535<<(32-dist)) : 0)); }
GATEFUNC(ShifterRight32) { int dist = getword(5, 97); setword64(64, 33, (((unsigned long long)getword(32, 1))<<(32-dist)) | (dist!=0 && getport(102) ? (4294967295ull<<(64-dist)) : 0ull)); }
GATEFUNC(And2) { setport(3, (getport(1) && getport(2))); }
GATEFUNC(And3) { setport(4, (getport(1) && getport(2) && getport(3))); }
GATEFUNC(And4) { setport(5, (getport(1) && getport(2) && getport(3) && getport(4))); }
GATEFUNC(And5) { setport(6, (getport(1) && getport(2) && getport(3) && getport(4) && getport(5))); }
GATEFUNC(And6) { setport(7, (getport(1) && getport(2) && getport(3) && getport(4) && getport(5) && getport(6))); }
GATEFUNC(And7) { setport(8, (getport(1) && getport(2) && getport(3) && getport(4) && getport(5) && getport(6) && getport(7))); }
GATEFUNC(And8) { setport(9, (getport(1) && getport(2) && getport(3) && getport(4) && getport(5) && getport(6) && getport(7) && getport(8))); }
GATEFUNC(Or2) { setport(3, (getport(1) || getport(2))); }
GATEFUNC(Or3) { setport(4, (getport(1) || getport(2) || getport(3))); }
GATEFUNC(Or4) { setport(5, (getport(1) || getport(2) || getport(3) || getport(4))); }
GATEFUNC(Or5) { setport(6, (getport(1) || getport(2) || getport(3) || getport(4) || getport(5))); }
GATEFUNC(Or6) { setport(7, (getport(1) || getport(2) || getport(3) || getport(4) || getport(5) || getport(6))); }
GATEFUNC(Or7) { setport(8, (getport(1) || getport(2) || getport(3) || getport(4) || getport(5) || getport(6) || getport(7))); }
GATEFUNC(Or8) { setport(9, (getport(1) || getport(2) || getport(3) || getport(4) || getport(5) || getport(6) || getport(7) || getport(8))); }
GATEFUNC(Xor2) { setport(3, (getport(1) ^ getport(2))); }
GATEFUNC(Xor3) { setport(4, (getport(1) ^ getport(2) ^ getport(3))); }
GATEFUNC(Xor4) { setport(5, (getport(1) ^ getport(2) ^ getport(3) ^ getport(4))); }
GATEFUNC(Xor5) { setport(6, (getport(1) ^ getport(2) ^ getport(3) ^ getport(4) ^ getport(5))); }
GATEFUNC(Xor6) { setport(7, (getport(1) ^ getport(2) ^ getport(3) ^ getport(4) ^ getport(5) ^ getport(6))); }
GATEFUNC(Xor7) { setport(8, (getport(1) ^ getport(2) ^ getport(3) ^ getport(4) ^ getport(5) ^ getport(6) ^ getport(7))); }
GATEFUNC(Xor8) { setport(9, (getport(1) ^ getport(2) ^ getport(3) ^ getport(4) ^ getport(5) ^ getport(6) ^ getport(7) ^ getport(8))); }
GATEFUNC(Nand2) { setport(3, !(getport(1) && getport(2))); }
GATEFUNC(Nand3) { setport(4, !(getport(1) && getport(2) && getport(3))); }
GATEFUNC(Nand4) { setport(5, !(getport(1) && getport(2) && getport(3) && getport(4))); }
GATEFUNC(Nand5) { setport(6, !(getport(1) && getport(2) && getport(3) && getport(4) && getport(5))); }
GATEFUNC(Nand6) { setport(7, !(getport(1) && getport(2) && getport(3) && getport(4) && getport(5) && getport(6))); }
GATEFUNC(Nand7) { setport(8, !(getport(1) && getport(2) && getport(3) && getport(4) && getport(5) && getport(6) && getport(7))); }
GATEFUNC(Nand8) { setport(9, !(getport(1) && getport(2) && getport(3) && getport(4) && getport(5) && getport(6) && getport(7) && getport(8))); }
GATEFUNC(Nor2) { setport(3, !(getport(1) || getport(2))); }
GATEFUNC(Nor3) { setport(4, !(getport(1) || getport(2) || getport(3))); }
GATEFUNC(Nor4) { setport(5, !(getport(1) || getport(2) || getport(3) || getport(4))); }
GATEFUNC(Nor5) { setport(6, !(getport(1) || getport(2) || getport(3) || getport(4) || getport(5))); }
GATEFUNC(Nor6) { setport(7, !(getport(1) || getport(2) || getport(3) || getport(4) || getport(5) || getport(6))); }
GATEFUNC(Nor7) { setport(8, !(getport(1) || getport(2) || getport(3) || getport(4) || getport(5) || getport(6) || getport(7))); }
GATEFUNC(Nor8) { setport(9, !(getport(1) || getport(2) || getport(3) || getport(4) || getport(5) || getport(6) || getport(7) || getport(8))); }
GATEFUNC(Xnor2) { setport(3, !(getport(1) ^ getport(2))); }
GATEFUNC(Xnor3) { setport(4, !(getport(1) ^ getport(2) ^ getport(3))); }
GATEFUNC(Xnor4) { setport(5, !(getport(1) ^ getport(2) ^ getport(3) ^ getport(4))); }
GATEFUNC(Xnor5) { setport(6, !(getport(1) ^ getport(2) ^ getport(3) ^ getport(4) ^ getport(5))); }
GATEFUNC(Xnor6) { setport(7, !(getport(1) ^ getport(2) ^ getport(3) ^ getport(4) ^ getport(5) ^ getport(6))); }
GATEFUNC(Xnor7) { setport(8, !(getport(1) ^ getport(2) ^ getport(3) ^ getport(4) ^ getport(5) ^ getport(6) ^ getport(7))); }
GATEFUNC(Xnor8) { setport(9, !(getport(1) ^ getport(2) ^ getport(3) ^ getport(4) ^ getport(5) ^ getport(6) ^ getport(7) ^ getport(8))); }
GATEFUNC(Rom4x1) { if(getport(6)) { int a = getword(4, 1); for(int i=0; i<1; i++) { setport(5+i, getdata(a + i*16)); } } else { clearword(1, 5); } }
GATEFUNC(Rom4x4) { if(getport(9)) { int a = getword(4, 1); for(int i=0; i<4; i++) { setport(5+i, getdata(a + i*16)); } } else { clearword(4, 5); } }
GATEFUNC(Rom4x8) { if(getport(13)) { int a = getword(4, 1); for(int i=0; i<8; i++) { setport(5+i, getdata(a + i*16)); } } else { clearword(8, 5); } }
GATEFUNC(Rom6x1) { if(getport(8)) { int a = getword(6, 1); for(int i=0; i<1; i++) { setport(7+i, getdata(a + i*64)); } } else { clearword(1, 7); } }
GATEFUNC(Rom6x4) { if(getport(11)) { int a = getword(6, 1); for(int i=0; i<4; i++) { setport(7+i, getdata(a + i*64)); } } else { clearword(4, 7); } }
GATEFUNC(Rom6x8) { if(getport(15)) { int a = getword(6, 1); for(int i=0; i<8; i++) { setport(7+i, getdata(a + i*64)); } } else { clearword(8, 7); } }
GATEFUNC(Rom6x16) { if(getport(23)) { int a = getword(6, 1); for(int i=0; i<16; i++) { setport(7+i, getdata(a + i*64)); } } else { clearword(16, 7); } }
GATEFUNC(Rom6x32) { if(getport(39)) { int a = getword(6, 1); for(int i=0; i<32; i++) { setport(7+i, getdata(a + i*64)); } } else { clearword(32, 7); } }
GATEFUNC(Rom6x48) { if(getport(55)) { int a = getword(6, 1); for(int i=0; i<48; i++) { setport(7+i, getdata(a + i*64)); } } else { clearword(48, 7); } }
GATEFUNC(Rom6x64) { if(getport(71)) { int a = getword(6, 1); for(int i=0; i<64; i++) { setport(7+i, getdata(a + i*64)); } } else { clearword(64, 7); } }
GATEFUNC(Rom8x1) { if(getport(10)) { int a = getword(8, 1); for(int i=0; i<1; i++) { setport(9+i, getdata(a + i*256)); } } else { clearword(1, 9); } }
GATEFUNC(Rom8x4) { if(getport(13)) { int a = getword(8, 1); for(int i=0; i<4; i++) { setport(9+i, getdata(a + i*256)); } } else { clearword(4, 9); } }
GATEFUNC(Rom8x8) { if(getport(17)) { int a = getword(8, 1); for(int i=0; i<8; i++) { setport(9+i, getdata(a + i*256)); } } else { clearword(8, 9); } }
GATEFUNC(Rom8x16) { if(getport(25)) { int a = getword(8, 1); for(int i=0; i<16; i++) { setport(9+i, getdata(a + i*256)); } } else { clearword(16, 9); } }
GATEFUNC(Rom8x32) { if(getport(41)) { int a = getword(8, 1); for(int i=0; i<32; i++) { setport(9+i, getdata(a + i*256)); } } else { clearword(32, 9); } }
GATEFUNC(Rom8x48) { if(getport(57)) { int a = getword(8, 1); for(int i=0; i<48; i++) { setport(9+i, getdata(a + i*256)); } } else { clearword(48, 9); } }
GATEFUNC(Rom8x64) { if(getport(73)) { int a = getword(8, 1); for(int i=0; i<64; i++) { setport(9+i, getdata(a + i*256)); } } else { clearword(64, 9); } }
GATEFUNC(Rom9x1) { if(getport(11)) { int a = getword(9, 1); for(int i=0; i<1; i++) { setport(10+i, getdata(a + i*512)); } } else { clearword(1, 10); } }
GATEFUNC(Rom9x4) { if(getport(14)) { int a = getword(9, 1); for(int i=0; i<4; i++) { setport(10+i, getdata(a + i*512)); } } else { clearword(4, 10); } }
GATEFUNC(Rom9x8) { if(getport(18)) { int a = getword(9, 1); for(int i=0; i<8; i++) { setport(10+i, getdata(a + i*512)); } } else { clearword(8, 10); } }
GATEFUNC(Rom9x16) { if(getport(26)) { int a = getword(9, 1); for(int i=0; i<16; i++) { setport(10+i, getdata(a + i*512)); } } else { clearword(16, 10); } }
GATEFUNC(Rom9x32) { if(getport(42)) { int a = getword(9, 1); for(int i=0; i<32; i++) { setport(10+i, getdata(a + i*512)); } } else { clearword(32, 10); } }
GATEFUNC(Rom9x48) { if(getport(58)) { int a = getword(9, 1); for(int i=0; i<48; i++) { setport(10+i, getdata(a + i*512)); } } else { clearword(48, 10); } }
GATEFUNC(Rom9x64) { if(getport(74)) { int a = getword(9, 1); for(int i=0; i<64; i++) { setport(10+i, getdata(a + i*512)); } } else { clearword(64, 10); } }
GATEFUNC(Rom10x8) { if(getport(19)) { int a = getword(10, 1); for(int i=0; i<8; i++) { setport(11+i, getdata(a + i*1024)); } } else { clearword(8, 11); } }
GATEFUNC(Rom10x16) { if(getport(27)) { int a = getword(10, 1); for(int i=0; i<16; i++) { setport(11+i, getdata(a + i*1024)); } } else { clearword(16, 11); } }
GATEFUNC(Rom10x32) { if(getport(43)) { int a = getword(10, 1); for(int i=0; i<32; i++) { setport(11+i, getdata(a + i*1024)); } } else { clearword(32, 11); } }
GATEFUNC(Rom10x48) { if(getport(59)) { int a = getword(10, 1); for(int i=0; i<48; i++) { setport(11+i, getdata(a + i*1024)); } } else { clearword(48, 11); } }
GATEFUNC(Rom10x64) { if(getport(75)) { int a = getword(10, 1); for(int i=0; i<64; i++) { setport(11+i, getdata(a + i*1024)); } } else { clearword(64, 11); } }
GATEFUNC(Rom11x8) { if(getport(20)) { int a = getword(11, 1); for(int i=0; i<8; i++) { setport(12+i, getdata(a + i*2048)); } } else { clearword(8, 12); } }
GATEFUNC(Rom11x16) { if(getport(28)) { int a = getword(11, 1); for(int i=0; i<16; i++) { setport(12+i, getdata(a + i*2048)); } } else { clearword(16, 12); } }
GATEFUNC(Rom11x32) { if(getport(44)) { int a = getword(11, 1); for(int i=0; i<32; i++) { setport(12+i, getdata(a + i*2048)); } } else { clearword(32, 12); } }
GATEFUNC(Rom11x48) { if(getport(60)) { int a = getword(11, 1); for(int i=0; i<48; i++) { setport(12+i, getdata(a + i*2048)); } } else { clearword(48, 12); } }
GATEFUNC(Rom11x64) { if(getport(76)) { int a = getword(11, 1); for(int i=0; i<64; i++) { setport(12+i, getdata(a + i*2048)); } } else { clearword(64, 12); } }
GATEFUNC(Rom12x8) { if(getport(21)) { int a = getword(12, 1); for(int i=0; i<8; i++) { setport(13+i, getdata(a + i*4096)); } } else { clearword(8, 13); } }
GATEFUNC(Rom12x16) { if(getport(29)) { int a = getword(12, 1); for(int i=0; i<16; i++) { setport(13+i, getdata(a + i*4096)); } } else { clearword(16, 13); } }
GATEFUNC(Rom12x32) { if(getport(45)) { int a = getword(12, 1); for(int i=0; i<32; i++) { setport(13+i, getdata(a + i*4096)); } } else { clearword(32, 13); } }
GATEFUNC(Rom12x48) { if(getport(61)) { int a = getword(12, 1); for(int i=0; i<48; i++) { setport(13+i, getdata(a + i*4096)); } } else { clearword(48, 13); } }
GATEFUNC(Rom12x64) { if(getport(77)) { int a = getword(12, 1); for(int i=0; i<64; i++) { setport(13+i, getdata(a + i*4096)); } } else { clearword(64, 13); } }
GATEFUNC(Ram8x8) { if(getport(25)) { setword(8, 9, getdata(getword(8, 17))); } else { clearword(8, 9); } if(getport(26)) { setdata(getword(8, 17), getword(8, 1)); } }
GATEFUNC(Ram8x12) { if(getport(29)) { setword(8, 9, getdata(getword(12, 17))); } else { clearword(8, 9); } if(getport(30)) { setdata(getword(12, 17), getword(8, 1)); } }
GateFunc sim_logic_functions[] = {
0,
GATEFUNCID(Diode),
GATEFUNCID(Not),
GATEFUNCID(Enabler1),
GATEFUNCID(Enabler2),
GATEFUNCID(Enabler3),
GATEFUNCID(Enabler4),
GATEFUNCID(Enabler5),
GATEFUNCID(Enabler6),
GATEFUNCID(Enabler7),
GATEFUNCID(Enabler8),
GATEFUNCID(Enabler9),
GATEFUNCID(Enabler10),
GATEFUNCID(Enabler11),
GATEFUNCID(Enabler12),
GATEFUNCID(Enabler13),
GATEFUNCID(Enabler14),
GATEFUNCID(Enabler15),
GATEFUNCID(Enabler16),
GATEFUNCID(Enabler24),
GATEFUNCID(Enabler32),
GATEFUNCID(Enabler48),
GATEFUNCID(Enabler64),
GATEFUNCID(Buffer1),
GATEFUNCID(Buffer2),
GATEFUNCID(Buffer3),
GATEFUNCID(Buffer4),
GATEFUNCID(Buffer5),
GATEFUNCID(Buffer6),
GATEFUNCID(Buffer7),
GATEFUNCID(Buffer8),
GATEFUNCID(Buffer9),
GATEFUNCID(Buffer10),
GATEFUNCID(Buffer11),
GATEFUNCID(Buffer12),
GATEFUNCID(Buffer13),
GATEFUNCID(Buffer14),
GATEFUNCID(Buffer15),
GATEFUNCID(Buffer16),
GATEFUNCID(Buffer24),
GATEFUNCID(Buffer32),
GATEFUNCID(Buffer48),
GATEFUNCID(Buffer64),
GATEFUNCID(DFF1),
GATEFUNCID(DFF2),
GATEFUNCID(DFF3),
GATEFUNCID(DFF4),
GATEFUNCID(DFF5),
GATEFUNCID(DFF6),
GATEFUNCID(DFF7),
GATEFUNCID(DFF8),
GATEFUNCID(DFF9),
GATEFUNCID(DFF10),
GATEFUNCID(DFF11),
GATEFUNCID(DFF12),
GATEFUNCID(DFF13),
GATEFUNCID(DFF14),
GATEFUNCID(DFF15),
GATEFUNCID(DFF16),
GATEFUNCID(DFF24),
GATEFUNCID(DFF32),
GATEFUNCID(DFF48),
GATEFUNCID(DFF64),
GATEFUNCID(Mux1),
GATEFUNCID(Mux2),
GATEFUNCID(Mux3),
GATEFUNCID(Mux4),
GATEFUNCID(Mux5),
GATEFUNCID(Mux6),
GATEFUNCID(Mux7),
GATEFUNCID(Mux8),
GATEFUNCID(Demux1),
GATEFUNCID(Demux2),
GATEFUNCID(Demux3),
GATEFUNCID(Demux4),
GATEFUNCID(Demux5),
GATEFUNCID(Demux6),
GATEFUNCID(Demux7),
GATEFUNCID(Demux8),
GATEFUNCID(Adder2),
GATEFUNCID(Adder4),
GATEFUNCID(Adder8),
GATEFUNCID(Adder16),
GATEFUNCID(Adder32),
GATEFUNCID(Incrementer2),
GATEFUNCID(Incrementer4),
GATEFUNCID(Incrementer8),
GATEFUNCID(Incrementer16),
GATEFUNCID(Incrementer32),
GATEFUNCID(Multiplier2),
GATEFUNCID(Multiplier4),
GATEFUNCID(Multiplier8),
GATEFUNCID(Multiplier16),
GATEFUNCID(Multiplier32),
GATEFUNCID(Divider2),
GATEFUNCID(Divider4),
GATEFUNCID(Divider8),
GATEFUNCID(Divider16),
GATEFUNCID(Divider32),
GATEFUNCID(ShifterLeft2),
GATEFUNCID(ShifterLeft4),
GATEFUNCID(ShifterLeft8),
GATEFUNCID(ShifterLeft16),
GATEFUNCID(ShifterLeft32),
GATEFUNCID(ShifterRight2),
GATEFUNCID(ShifterRight4),
GATEFUNCID(ShifterRight8),
GATEFUNCID(ShifterRight16),
GATEFUNCID(ShifterRight32),
GATEFUNCID(And2),
GATEFUNCID(And3),
GATEFUNCID(And4),
GATEFUNCID(And5),
GATEFUNCID(And6),
GATEFUNCID(And7),
GATEFUNCID(And8),
GATEFUNCID(Or2),
GATEFUNCID(Or3),
GATEFUNCID(Or4),
GATEFUNCID(Or5),
GATEFUNCID(Or6),
GATEFUNCID(Or7),
GATEFUNCID(Or8),
GATEFUNCID(Xor2),
GATEFUNCID(Xor3),
GATEFUNCID(Xor4),
GATEFUNCID(Xor5),
GATEFUNCID(Xor6),
GATEFUNCID(Xor7),
GATEFUNCID(Xor8),
GATEFUNCID(Nand2),
GATEFUNCID(Nand3),
GATEFUNCID(Nand4),
GATEFUNCID(Nand5),
GATEFUNCID(Nand6),
GATEFUNCID(Nand7),
GATEFUNCID(Nand8),
GATEFUNCID(Nor2),
GATEFUNCID(Nor3),
GATEFUNCID(Nor4),
GATEFUNCID(Nor5),
GATEFUNCID(Nor6),
GATEFUNCID(Nor7),
GATEFUNCID(Nor8),
GATEFUNCID(Xnor2),
GATEFUNCID(Xnor3),
GATEFUNCID(Xnor4),
GATEFUNCID(Xnor5),
GATEFUNCID(Xnor6),
GATEFUNCID(Xnor7),
GATEFUNCID(Xnor8),
GATEFUNCID(Rom4x1),
GATEFUNCID(Rom4x4),
GATEFUNCID(Rom4x8),
GATEFUNCID(Rom6x1),
GATEFUNCID(Rom6x4),
GATEFUNCID(Rom6x8),
GATEFUNCID(Rom6x16),
GATEFUNCID(Rom6x32),
GATEFUNCID(Rom6x48),
GATEFUNCID(Rom6x64),
GATEFUNCID(Rom8x1),
GATEFUNCID(Rom8x4),
GATEFUNCID(Rom8x8),
GATEFUNCID(Rom8x16),
GATEFUNCID(Rom8x32),
GATEFUNCID(Rom8x48),
GATEFUNCID(Rom8x64),
GATEFUNCID(Rom9x1),
GATEFUNCID(Rom9x4),
GATEFUNCID(Rom9x8),
GATEFUNCID(Rom9x16),
GATEFUNCID(Rom9x32),
GATEFUNCID(Rom9x48),
GATEFUNCID(Rom9x64),
GATEFUNCID(Rom10x8),
GATEFUNCID(Rom10x16),
GATEFUNCID(Rom10x32),
GATEFUNCID(Rom10x48),
GATEFUNCID(Rom10x64),
GATEFUNCID(Rom11x8),
GATEFUNCID(Rom11x16),
GATEFUNCID(Rom11x32),
GATEFUNCID(Rom11x48),
GATEFUNCID(Rom11x64),
GATEFUNCID(Rom12x8),
GATEFUNCID(Rom12x16),
GATEFUNCID(Rom12x32),
GATEFUNCID(Rom12x48),
GATEFUNCID(Rom12x64),
GATEFUNCID(Ram8x8),
GATEFUNCID(Ram8x12),
};

395
sim/compiled_sim_gates.lua Normal file
View File

@ -0,0 +1,395 @@
-- Auto-generated by gencfuncs.lua
cFuncsByName = {
["diode"] = 1,
["diode up"] = 1,
["diode down"] = 1,
["not"] = 2,
["not up"] = 2,
["not down"] = 2,
["enabler 1 bit"] = 3,
["enabler 1 bit up"] = 3,
["enabler 1 bit down"] = 3,
["enabler 2 bit"] = 4,
["enabler 2 bit up"] = 4,
["enabler 2 bit down"] = 4,
["enabler 3 bit"] = 5,
["enabler 3 bit up"] = 5,
["enabler 3 bit down"] = 5,
["enabler 4 bit"] = 6,
["enabler 4 bit up"] = 6,
["enabler 4 bit down"] = 6,
["enabler 5 bit"] = 7,
["enabler 5 bit up"] = 7,
["enabler 5 bit down"] = 7,
["enabler 6 bit"] = 8,
["enabler 6 bit up"] = 8,
["enabler 6 bit down"] = 8,
["enabler 7 bit"] = 9,
["enabler 7 bit up"] = 9,
["enabler 7 bit down"] = 9,
["enabler 8 bit"] = 10,
["enabler 8 bit up"] = 10,
["enabler 8 bit down"] = 10,
["enabler 9 bit"] = 11,
["enabler 9 bit up"] = 11,
["enabler 9 bit down"] = 11,
["enabler 10 bit"] = 12,
["enabler 10 bit up"] = 12,
["enabler 10 bit down"] = 12,
["enabler 11 bit"] = 13,
["enabler 11 bit up"] = 13,
["enabler 11 bit down"] = 13,
["enabler 12 bit"] = 14,
["enabler 12 bit up"] = 14,
["enabler 12 bit down"] = 14,
["enabler 13 bit"] = 15,
["enabler 13 bit up"] = 15,
["enabler 13 bit down"] = 15,
["enabler 14 bit"] = 16,
["enabler 14 bit up"] = 16,
["enabler 14 bit down"] = 16,
["enabler 15 bit"] = 17,
["enabler 15 bit up"] = 17,
["enabler 15 bit down"] = 17,
["enabler 16 bit"] = 18,
["enabler 16 bit up"] = 18,
["enabler 16 bit down"] = 18,
["enabler 24 bit"] = 19,
["enabler 24 bit up"] = 19,
["enabler 24 bit down"] = 19,
["enabler 32 bit"] = 20,
["enabler 32 bit up"] = 20,
["enabler 32 bit down"] = 20,
["enabler 48 bit"] = 21,
["enabler 48 bit up"] = 21,
["enabler 48 bit down"] = 21,
["enabler 64 bit"] = 22,
["enabler 64 bit up"] = 22,
["enabler 64 bit down"] = 22,
["buffer 1 bit"] = 23,
["buffer 1 bit up"] = 23,
["buffer 1 bit down"] = 23,
["buffer 2 bit"] = 24,
["buffer 2 bit up"] = 24,
["buffer 2 bit down"] = 24,
["buffer 3 bit"] = 25,
["buffer 3 bit up"] = 25,
["buffer 3 bit down"] = 25,
["buffer 4 bit"] = 26,
["buffer 4 bit up"] = 26,
["buffer 4 bit down"] = 26,
["buffer 5 bit"] = 27,
["buffer 5 bit up"] = 27,
["buffer 5 bit down"] = 27,
["buffer 6 bit"] = 28,
["buffer 6 bit up"] = 28,
["buffer 6 bit down"] = 28,
["buffer 7 bit"] = 29,
["buffer 7 bit up"] = 29,
["buffer 7 bit down"] = 29,
["buffer 8 bit"] = 30,
["buffer 8 bit up"] = 30,
["buffer 8 bit down"] = 30,
["buffer 9 bit"] = 31,
["buffer 9 bit up"] = 31,
["buffer 9 bit down"] = 31,
["buffer 10 bit"] = 32,
["buffer 10 bit up"] = 32,
["buffer 10 bit down"] = 32,
["buffer 11 bit"] = 33,
["buffer 11 bit up"] = 33,
["buffer 11 bit down"] = 33,
["buffer 12 bit"] = 34,
["buffer 12 bit up"] = 34,
["buffer 12 bit down"] = 34,
["buffer 13 bit"] = 35,
["buffer 13 bit up"] = 35,
["buffer 13 bit down"] = 35,
["buffer 14 bit"] = 36,
["buffer 14 bit up"] = 36,
["buffer 14 bit down"] = 36,
["buffer 15 bit"] = 37,
["buffer 15 bit up"] = 37,
["buffer 15 bit down"] = 37,
["buffer 16 bit"] = 38,
["buffer 16 bit up"] = 38,
["buffer 16 bit down"] = 38,
["buffer 24 bit"] = 39,
["buffer 24 bit up"] = 39,
["buffer 24 bit down"] = 39,
["buffer 32 bit"] = 40,
["buffer 32 bit up"] = 40,
["buffer 32 bit down"] = 40,
["buffer 48 bit"] = 41,
["buffer 48 bit up"] = 41,
["buffer 48 bit down"] = 41,
["buffer 64 bit"] = 42,
["buffer 64 bit up"] = 42,
["buffer 64 bit down"] = 42,
["d flipflop 1 bit"] = 43,
["d flipflop 1 bit up"] = 43,
["d flipflop 1 bit down"] = 43,
["d flipflop 2 bit"] = 44,
["d flipflop 2 bit up"] = 44,
["d flipflop 2 bit down"] = 44,
["d flipflop 3 bit"] = 45,
["d flipflop 3 bit up"] = 45,
["d flipflop 3 bit down"] = 45,
["d flipflop 4 bit"] = 46,
["d flipflop 4 bit up"] = 46,
["d flipflop 4 bit down"] = 46,
["d flipflop 5 bit"] = 47,
["d flipflop 5 bit up"] = 47,
["d flipflop 5 bit down"] = 47,
["d flipflop 6 bit"] = 48,
["d flipflop 6 bit up"] = 48,
["d flipflop 6 bit down"] = 48,
["d flipflop 7 bit"] = 49,
["d flipflop 7 bit up"] = 49,
["d flipflop 7 bit down"] = 49,
["d flipflop 8 bit"] = 50,
["d flipflop 8 bit up"] = 50,
["d flipflop 8 bit down"] = 50,
["d flipflop 9 bit"] = 51,
["d flipflop 9 bit up"] = 51,
["d flipflop 9 bit down"] = 51,
["d flipflop 10 bit"] = 52,
["d flipflop 10 bit up"] = 52,
["d flipflop 10 bit down"] = 52,
["d flipflop 11 bit"] = 53,
["d flipflop 11 bit up"] = 53,
["d flipflop 11 bit down"] = 53,
["d flipflop 12 bit"] = 54,
["d flipflop 12 bit up"] = 54,
["d flipflop 12 bit down"] = 54,
["d flipflop 13 bit"] = 55,
["d flipflop 13 bit up"] = 55,
["d flipflop 13 bit down"] = 55,
["d flipflop 14 bit"] = 56,
["d flipflop 14 bit up"] = 56,
["d flipflop 14 bit down"] = 56,
["d flipflop 15 bit"] = 57,
["d flipflop 15 bit up"] = 57,
["d flipflop 15 bit down"] = 57,
["d flipflop 16 bit"] = 58,
["d flipflop 16 bit up"] = 58,
["d flipflop 16 bit down"] = 58,
["d flipflop 24 bit"] = 59,
["d flipflop 24 bit up"] = 59,
["d flipflop 24 bit down"] = 59,
["d flipflop 32 bit"] = 60,
["d flipflop 32 bit up"] = 60,
["d flipflop 32 bit down"] = 60,
["d flipflop 48 bit"] = 61,
["d flipflop 48 bit up"] = 61,
["d flipflop 48 bit down"] = 61,
["d flipflop 64 bit"] = 62,
["d flipflop 64 bit up"] = 62,
["d flipflop 64 bit down"] = 62,
["mux 1 bit"] = 63,
["mux 1 bit vertical"] = 63,
["mux 2 bit"] = 64,
["mux 2 bit vertical"] = 64,
["mux 3 bit"] = 65,
["mux 3 bit vertical"] = 65,
["mux 4 bit"] = 66,
["mux 4 bit vertical"] = 66,
["mux 5 bit"] = 67,
["mux 5 bit vertical"] = 67,
["mux 6 bit"] = 68,
["mux 6 bit vertical"] = 68,
["mux 7 bit"] = 69,
["mux 7 bit vertical"] = 69,
["mux 8 bit"] = 70,
["mux 8 bit vertical"] = 70,
["demux 1 bit"] = 71,
["demux 1 bit vertical"] = 71,
["demux 2 bit"] = 72,
["demux 2 bit vertical"] = 72,
["demux 3 bit"] = 73,
["demux 3 bit vertical"] = 73,
["demux 4 bit"] = 74,
["demux 4 bit vertical"] = 74,
["demux 5 bit"] = 75,
["demux 5 bit vertical"] = 75,
["demux 6 bit"] = 76,
["demux 6 bit vertical"] = 76,
["demux 7 bit"] = 77,
["demux 7 bit vertical"] = 77,
["demux 8 bit"] = 78,
["demux 8 bit vertical"] = 78,
["adder 2 bit"] = 79,
["adder 4 bit"] = 80,
["adder 8 bit"] = 81,
["adder 16 bit"] = 82,
["adder 32 bit"] = 83,
["incrementer 2 bit"] = 84,
["incrementer 4 bit"] = 85,
["incrementer 8 bit"] = 86,
["incrementer 16 bit"] = 87,
["incrementer 32 bit"] = 88,
["multiplier 2 bit"] = 89,
["multiplier 4 bit"] = 90,
["multiplier 8 bit"] = 91,
["multiplier 16 bit"] = 92,
["multiplier 32 bit"] = 93,
["divider 2 bit"] = 94,
["divider 4 bit"] = 95,
["divider 8 bit"] = 96,
["divider 16 bit"] = 97,
["divider 32 bit"] = 98,
["shifter left 2 bit"] = 99,
["shifter left 4 bit"] = 100,
["shifter left 8 bit"] = 101,
["shifter left 16 bit"] = 102,
["shifter left 32 bit"] = 103,
["shifter right 2 bit"] = 104,
["shifter right 4 bit"] = 105,
["shifter right 8 bit"] = 106,
["shifter right 16 bit"] = 107,
["shifter right 32 bit"] = 108,
["and 2 bit"] = 109,
["and 3 bit"] = 110,
["and 4 bit"] = 111,
["and 5 bit"] = 112,
["and 6 bit"] = 113,
["and 7 bit"] = 114,
["and 8 bit"] = 115,
["or 2 bit"] = 116,
["or 3 bit"] = 117,
["or 4 bit"] = 118,
["or 5 bit"] = 119,
["or 6 bit"] = 120,
["or 7 bit"] = 121,
["or 8 bit"] = 122,
["xor 2 bit"] = 123,
["xor 3 bit"] = 124,
["xor 4 bit"] = 125,
["xor 5 bit"] = 126,
["xor 6 bit"] = 127,
["xor 7 bit"] = 128,
["xor 8 bit"] = 129,
["nand 2 bit"] = 130,
["nand 3 bit"] = 131,
["nand 4 bit"] = 132,
["nand 5 bit"] = 133,
["nand 6 bit"] = 134,
["nand 7 bit"] = 135,
["nand 8 bit"] = 136,
["nor 2 bit"] = 137,
["nor 3 bit"] = 138,
["nor 4 bit"] = 139,
["nor 5 bit"] = 140,
["nor 6 bit"] = 141,
["nor 7 bit"] = 142,
["nor 8 bit"] = 143,
["xnor 2 bit"] = 144,
["xnor 3 bit"] = 145,
["xnor 4 bit"] = 146,
["xnor 5 bit"] = 147,
["xnor 6 bit"] = 148,
["xnor 7 bit"] = 149,
["xnor 8 bit"] = 150,
["rom 4x4"] = 151,
["rom 4x4x4"] = 152,
["rom 8x2x8"] = 153,
["rom 8x8"] = 154,
["rom 8x8x4"] = 155,
["rom 8x8x8"] = 156,
["rom 16x4x16"] = 157,
["rom 32x2x32"] = 158,
["rom 64x1x48"] = 159,
["rom 64x1x64"] = 160,
["rom 16x16"] = 161,
["rom 16x16x4"] = 162,
["rom 16x16x8"] = 163,
["rom 16x16x16"] = 164,
["rom 32x8x32"] = 165,
["rom 64x4x48"] = 166,
["rom 64x4x64"] = 167,
["rom 32x16"] = 168,
["rom 32x16x4"] = 169,
["rom 32x16x8"] = 170,
["rom 32x16x16"] = 171,
["rom 32x16x32"] = 172,
["rom 64x8x48"] = 173,
["rom 64x8x64"] = 174,
["rom 32x32x8"] = 175,
["rom 32x32x16"] = 176,
["rom 32x32x32"] = 177,
["rom 64x16x48"] = 178,
["rom 64x16x64"] = 179,
["rom 64x32x8"] = 180,
["rom 64x32x16"] = 181,
["rom 64x32x32"] = 182,
["rom 64x32x48"] = 183,
["rom 64x32x64"] = 184,
["rom 64x64x8"] = 185,
["rom 64x64x16"] = 186,
["rom 64x64x32"] = 187,
["rom 64x64x48"] = 188,
["rom 64x64x64"] = 189,
["ram 256 b"] = 190,
["ram 4 kb"] = 191,
}
cDataSizeByName = {
["demux 1 bit"] = 1,
["demux 1 bit vertical"] = 1,
["demux 2 bit"] = 1,
["demux 2 bit vertical"] = 1,
["demux 3 bit"] = 1,
["demux 3 bit vertical"] = 1,
["demux 4 bit"] = 1,
["demux 4 bit vertical"] = 1,
["demux 5 bit"] = 1,
["demux 5 bit vertical"] = 1,
["demux 6 bit"] = 1,
["demux 6 bit vertical"] = 1,
["demux 7 bit"] = 1,
["demux 7 bit vertical"] = 1,
["demux 8 bit"] = 1,
["demux 8 bit vertical"] = 1,
["rom 4x4"] = 16,
["rom 4x4x4"] = 64,
["rom 8x2x8"] = 128,
["rom 8x8"] = 64,
["rom 8x8x4"] = 256,
["rom 8x8x8"] = 512,
["rom 16x4x16"] = 1024,
["rom 32x2x32"] = 2048,
["rom 64x1x48"] = 3072,
["rom 64x1x64"] = 4096,
["rom 16x16"] = 256,
["rom 16x16x4"] = 1024,
["rom 16x16x8"] = 2048,
["rom 16x16x16"] = 4096,
["rom 32x8x32"] = 8192,
["rom 64x4x48"] = 12288,
["rom 64x4x64"] = 16384,
["rom 32x16"] = 512,
["rom 32x16x4"] = 2048,
["rom 32x16x8"] = 4096,
["rom 32x16x16"] = 8192,
["rom 32x16x32"] = 16384,
["rom 64x8x48"] = 24576,
["rom 64x8x64"] = 32768,
["rom 32x32x8"] = 8192,
["rom 32x32x16"] = 16384,
["rom 32x32x32"] = 32768,
["rom 64x16x48"] = 49152,
["rom 64x16x64"] = 65536,
["rom 64x32x8"] = 16384,
["rom 64x32x16"] = 32768,
["rom 64x32x32"] = 65536,
["rom 64x32x48"] = 98304,
["rom 64x32x64"] = 131072,
["rom 64x64x8"] = 32768,
["rom 64x64x16"] = 65536,
["rom 64x64x32"] = 131072,
["rom 64x64x48"] = 196608,
["rom 64x64x64"] = 262144,
["ram 256 b"] = 256,
["ram 4 kb"] = 4096,
}

20630
sim/dump.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +1,83 @@
local ffi = FFI
local ffi = FFI or require("ffi")
Gate = {}
ffi.cdef [[
struct Net;
struct Gate {
int* in_queue;
int* port_states;
int** port_net_state;
int** port_net_state_num;
int** port_net_in_queue;
struct Net** port_nets_c;
int objref;
int logic_function;
int data_size;
int* data;
};
]]
function Gate.new(objref, definition)
local o = {
--in_queue = ffi.new("bool", false),
--in_queue = false,
--in_queue = ffi.new("long long", 0),
in_queue = 0,
port_nets = {},
local gate = {
-- Logic Critical
in_queue = ffi.new("int[1]"),
port_states = ffi.new("int["..(#definition.ports+1).."]"),
logic = definition.logic,
ports = {},
port_nets = {},
port_net_state = ffi.new("int*["..(#definition.ports+1).."]"),
port_net_state_num = ffi.new("int*["..(#definition.ports+1).."]"),
port_net_in_queue = ffi.new("int*["..(#definition.ports+1).."]"),
port_nets_c = ffi.new("struct Net*["..(#definition.ports+1).."]"),
objref = objref,
definition = definition,
}
return o
end
function Gate.addport(gate, port)
gate.ports[#gate.ports+1] = port
Port.setgate(port, gate)
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
gate.c.port_net_state = gate.port_net_state
gate.c.port_net_state_num = gate.port_net_state_num
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
-- Logic Critical
function Gate.getportstate(gate, index)
return gate.port_nets[index].state
return gate.port_net_state[index][0]
end
-- Logic Critical
function Gate.setportstate(gate, index, state)
local port = gate.ports[index]
if state ~= port.state then
local group = port.group
group.state_num = group.state_num - port.state + state
port.state = state
if state ~= gate.port_states[index] then
gate.port_net_state_num[index][0] = gate.port_net_state_num[index][0] - gate.port_states[index] + state
gate.port_states[index] = state
if (group.state_num>0) ~= (group.state==1) then
Simulation.queuegroup(GSim, group)
if ((gate.port_net_state_num[index][0]>0) ~= (gate.port_net_state[index][0]==1)) and (gate.port_net_in_queue[index][0]==0) then
local cnet = gate.port_nets_c[index]
Simulation.queuegroup_c(GSim, cnet)
end
end
end
function Gate.preinit(gate)
end
function Gate.initdata(gate)
gate.data = {}
end
@ -51,6 +86,16 @@ function Gate.getdata(gate)
return gate.data
end
function Gate.getcdata(gate, i)
assert(i>=0 and i<gate.c.data_size)
return gate.c.data[i]
end
function Gate.setcdata(gate, i, v)
assert(i>=0 and i<gate.c.data_size)
gate.c.data[i] = v
end
function Gate.getportisrising(gate, index)
return Port.isrising(gate.ports[index])
end
@ -60,7 +105,11 @@ function Gate.getportisfalling(gate, index)
end
function Gate.cb(gate, ...)
Simulation.queuecallback(GSim, gate, ...)
Simulation.setcallback(GSim, gate, ...)
end
function Gate.cbQueue(gate, arg, limit)
Simulation.queuecallback(GSim, gate, arg, limit)
end
function Gate.queue(gate, delay)
@ -68,7 +117,7 @@ function Gate.queue(gate, delay)
end
function Gate.gettick(gate)
return GSim.current_tick
return GSim.current_tick[0]
end
function Gate.getdefinition(gate)
@ -81,10 +130,6 @@ function Gate.init(gate)
Gate.getdefinition(gate).init(gate)
end
function Gate.logic(gate)
gate.logic(gate)
end
function Gate.input(gate, argv)
Gate.getdefinition(gate).input(gate, argv)
end

View File

@ -1,4 +1,6 @@
local ffi = FFI or require("ffi")
GateDefinition = {
ports = {},
logic = function(gate) end,
@ -14,16 +16,20 @@ function GateDefinition.new(objref, name, description, init, logic, input, globa
global = collapseescape(global)
description = collapseescape(description)
local o = {
local def = {
objref = objref,
name = name,
description = description,
ports = ports or {}
ports = ports or {},
num_in_ports = 0,
num_out_ports = 0,
data_size_c = cDataSizeByName[name:lower()] or 0,
logic_function_c = cFuncsByName[name:lower()] or 0,
}
local initfunc = loadstring(tostring(init))
if initfunc~=nil then
o.init = initfunc() or function()end
def.init = initfunc() or function()end
else
print("Error loading init func for ".. (name or ""))
print(init)
@ -31,7 +37,7 @@ function GateDefinition.new(objref, name, description, init, logic, input, globa
local logicfunc = loadstring(tostring(logic))
if logicfunc ~= nil then
o.logic = logicfunc() or function()end
def.logic = logicfunc() or function()end
else
print("Error loading logic function for " .. (name or ""))
print(logic)
@ -39,7 +45,7 @@ function GateDefinition.new(objref, name, description, init, logic, input, globa
local inputfunc = loadstring(tostring(input))
if inputfunc ~= nil then
o.input = inputfunc() or function()end
def.input = inputfunc() or function()end
else
print("Error loading input function for " .. (name or ""))
print(input)
@ -53,12 +59,21 @@ function GateDefinition.new(objref, name, description, init, logic, input, globa
print(global)
end
return o
for i = 1, #def.ports do
local portd = def.ports[i]
if portd.type==PortTypes.output then
def.num_out_ports = def.num_out_ports + 1
elseif portd.type==PortTypes.input then
def.num_in_ports = def.num_in_ports + 1
else error("invalid port type: "..name.." port "..i) end
end
return def
end
function GateDefinition.constructgate(def, objref, position, rotation)
local gate = Gate.new(objref, def)
for i = 1, #def.ports do
local portd = def.ports[i]
local type = portd.type
@ -81,9 +96,18 @@ function GateDefinition.constructgate(def, objref, position, rotation)
pos[1] = -pos[2]
pos[2] = x
end
Gate.addport(gate, Port.new(type, dir, {position[1]+pos[1], position[2]+pos[2], position[3]+pos[3]}, portd.causeupdate, i))
local port = Port.new(type, dir, {position[1]+pos[1], position[2]+pos[2], position[3]+pos[3]}, portd.causeupdate, i, gate)
gate.ports[port.idx] = port
gate.port_nets[port.idx] = nil
gate.port_states[port.idx] = 0
gate.port_net_state [port.idx] = ffi.cast("int*", 0)
gate.port_net_state_num[port.idx] = ffi.cast("int*", 0)
gate.port_net_in_queue [port.idx] = ffi.cast("int*", 0)
gate.port_nets_c [port.idx] = ffi.cast("struct Net*", 0)
end
return gate
end

164
sim/gencfuncs.lua Normal file
View File

@ -0,0 +1,164 @@
local c_code = [[
// Auto-generated by gencfuncs.lua
enum GateFuncs {
GateFunc_None,
%s
};
%s
GateFunc sim_logic_functions[] = {
0,
%s
};
]]
local lua_code = [[
-- Auto-generated by gencfuncs.lua
cFuncsByName = {
%s
}
cDataSizeByName = {
%s
}
]]
local function writeFile(fn, data)
local f = io.open(fn, "wb") or error("Could not open file for writing: "..fn)
f:write(data)
f:close()
end
local function exportGates(gates)
local gateNameList = {}
local gateFuncList = {}
local gateSizeList = {}
local gateAliasList = {}
local numGates = 0
for k, gate in pairs(gates) do
table.insert(gateNameList, gate.name or error("gate "..k.." has no name"))
table.insert(gateFuncList, gate.func or error("gate "..gate.name.." has no c function"))
table.insert(gateSizeList, gate.size or 0)
numGates = numGates + 1; gate.idx = numGates;
for _, name in ipairs(gate.names) do
table.insert(gateAliasList, { name = name, idx = gate.idx } )
end
end
local function map(t, f) local u = {}; for i, v in ipairs(t) do table.insert(u, f(v, i)) end; return u; end
writeFile("compiled_sim_gates.c", string.format(c_code,
table.concat(map(gateNameList, function(v, i) return string.format("\tGateFunc_%s,", v) end), "\n"),
table.concat(map(gateNameList, function(v, i)
local func = gateFuncList[i]
local nl = func:find("\n") and "\n" or ""
local nt = func:find("\n") and "\t" or ""
local ns = func:find("\n") and "" or " "
return string.format("GATEFUNC(%s) {"..nl..nt..ns.."%s"..nl..ns.."}", v, gateFuncList[i]:gsub("\n", "\n\t"):gsub("\n+$", ""):gsub("^\n+", ""))
end), "\n"),
table.concat(map(gateNameList, function(v, i) return string.format("\tGATEFUNCID(%s),", v) end), "\n")
))
writeFile("compiled_sim_gates.lua", string.format(lua_code,
table.concat(map(gateAliasList, function(v, i) return string.format("\t[\"%s\"] = %i,", v.name:lower(), v.idx) end), "\n"),
table.concat(map(gateAliasList, function(v, i) if gateSizeList[v.idx]>0 then return string.format("\t[\"%s\"] = %i,", v.name:lower(), gateSizeList[v.idx]) else return nil end end), "\n")
))
end
local function log2(n) return math.max(math.ceil(math.log(n)/math.log(2)-0.00000001), 1) end
local function sizestrFromAddrwS(w) return ({"2 ", "4 ", "8 ", "16 ", "32 ", "64 ", "128 ", "256 ", "512 ", "1 K", "2 K", "4 K", "8 K", "16 K", "32 K", "64 K"})[w] end
local function sizestrFromAddrw(w) sizeFromAddrWS(w):gsub(" ", "") end
local function bwFromN(n) return ({"B", "W", nil, "DW"})[n/8] or error("invalid size "..n) end
local function sizecast(n) return n>=32 and "(unsigned long long)" or "" end
local function sizetype(n) return n>=32 and "unsigned long long" or "unsigned int" end
local function sizeword(n) return n>=32 and "64" or "" end
local function sizeint(n) return n>=32 and "ull" or "" end
local function sizemax(n) return math.pow(2, n)-1 end
local function createEnabler(n) return { name = "Enabler"..n, names = {"Enabler " ..n.." Bit", "Enabler " ..n.." Bit Up", "Enabler " ..n.." Bit Down"}, func = "if(getport("..(n*2+1)..")) { copyword("..n..", 1, "..(n+1).."); } else { clearword("..n..", "..(n+1).."); }" } end
local function createBuffer (n) return { name = "Buffer" ..n, names = {"Buffer " ..n.." Bit", "Buffer " ..n.." Bit Up", "Buffer " ..n.." Bit Down"}, func = "if(getport("..(n*2+1)..")) { copyword("..n..", 1, "..(n+1).."); } else { clearword("..n..", "..(n+1).."); }" } end
local function createDFF (n) return { name = "DFF" ..n, names = {"D FlipFlop " ..n.." Bit", "D FlipFlop " ..n.." Bit Up", "D FlipFlop " ..n.." Bit Down"}, func = "if(getport("..(n*2+1)..")) { copyword("..n..", 1, "..(n+1).."); }" } end
local function createMux(n) return { name = "Mux"..n, names = {"Mux "..n.." Bit", "Mux "..n.." Bit Vertical"}, func = "if(getport("..(n+math.pow(2,n)+1)..")) { setport("..(n+math.pow(2,n)+2)..", getport(getword("..n..", 1)+"..(n+1)..")); } else { setport("..(n+math.pow(2,n)+2)..", 0); }" } end
local function createDemux(n) return { name = "Demux"..n, names = {"Demux "..n.." Bit", "Demux "..n.." Bit Vertical"}, size = 1, func = "int pa = getdata(0); if(getport("..(n+math.pow(2,n)+1)..")) { int a = getword("..n..", 1) + "..(n+1).."; if(pa != a) { if(pa) { setport(pa, 0); } setport(a, 1); setdata(0, a); } } else { if(pa) { setport(pa, 0); setdata(0, 0); } }" } end
local function createRom(x, y, z) local w = log2(x*y); return { name = "Rom"..w.."x"..z, names = {"ROM "..x.."x"..y..(z>1 and ("x"..z) or "")}, size = x*y*z, func="if(getport("..(w+z+1)..")) { int a = getword("..w..", 1); for(int i=0; i<"..z.."; i++) { setport("..(w+1).."+i, getdata(a + i*"..(x*y)..")); } } else { clearword("..z..", "..(w+1).."); }" } end
local function createAdder(n) return { name = "Adder"..n, names = {"Adder "..n.." Bit"}, func =
sizetype(n).." v = "..
sizecast(n).."getword("..n..", 1) + "..
sizecast(n).."(getword("..n..", "..(n+1)..")^(getport("..(n*3+3)..")*"..sizemax(n)..")) + "..
sizecast(n).."getport("..(n*3+1).."); "..
"setword("..n..", "..(n*2+1)..", v); "..
"setport("..(n*3+2)..", (v>>"..n..sizeint(n)..") & 1);"
} end
local function createIncrementer(n) return { name = "Incrementer"..n, names = {"Incrementer "..n.." Bit"}, func =
sizetype(n).." a = "..
sizecast(n).."(getword("..n..", 1)^(getport("..(n*2+4)..")*"..sizemax(n)..")) + "..
sizecast(n).."getport("..(n*2+1)..") + "..
sizecast(n).."(getport("..(n*2+2)..")*"..sizemax(n).."); "..
"setword("..n..", "..(n+1)..", a); "..
"setport("..(n*2+3)..", (a>>"..n..sizeint(n)..") & 1);"
} end
local function createShifterLeft (n) return { name = "ShifterLeft" ..n, names = {"Shifter Left " ..n.." Bit"}, func =
"int dist = getword("..log2(n)..", "..(n*3+1).."); "..
"setword"..sizeword(n).."("..(n*2)..", "..(n+1)..", "..
" (("..sizecast(n).."getword("..n..", 1))<<dist"..") | "..
"(getport("..(n*3+log2(n)+1)..") ? ("..sizemax(n)..sizeint(n)..">>("..n .."-dist)) : 0"..sizeint(n).."));" } end
local function createShifterRight(n) return { name = "ShifterRight"..n, names = {"Shifter Right "..n.." Bit"}, func =
"int dist = getword("..log2(n)..", "..(n*3+1).."); "..
"setword"..sizeword(n).."("..(n*2)..", "..(n+1)..", "..
"(("..sizecast(n).."getword("..n..", 1))<<("..n.."-dist)) | "..
"("..(n>=16 and "dist!=0 && " or "").."getport("..(n*3+log2(n)+1)..") ? "..
"("..sizemax(n)..sizeint(n).."<<("..(n*2).."-dist)) : "..
"0"..sizeint(n)..
")"..
");"
} end
local function createMultiplier(n) return { name = "Multiplier"..n, names = {"Multiplier "..n.." Bit"}, func = "setword"..sizeword(n).."("..(n*2)..", "..(n*2+1)..", "..sizecast(n).."getword("..n..", 1) * "..sizecast(n).."getword("..n..", "..(n+1).."));" } end
local function createDivider(n) return { name = "Divider"..n, names = {"Divider "..n.." Bit"}, func = "unsigned int a = getword("..n..", 1); unsigned int b = getword("..n..", "..(n+1).."); setword("..n..", "..(n*2+1)..", b!=0 ? a/b : 0); setword("..n..", "..(n*3+1)..", b!=0 ? a%b : 0);" } end
local function createBinary(name, f, inv, n) local ilist = {}; for i = 1, n do table.insert(ilist, "getport("..i..")") end; return { name = name..n, names = {name:upper().." "..n.." Bit"}, func = "setport("..(n+1)..", "..inv.."("..table.concat(ilist, " "..f.." ").."));" } end
local function createRam(n, w) return { name = "Ram"..n.."x"..w, names = {"RAM "..sizestrFromAddrwS(w)..bwFromN(n)}, size = math.pow(2, w), func = "if(getport("..(n*2+w+1)..")) { setword("..n..", "..(n+1)..", getdata(getword("..w..", "..(n*2+1).."))); } else { clearword("..n..", "..(n+1).."); } if(getport("..(n*2+w+2)..")) { setdata(getword("..w..", "..(n*2+1).."), getword("..n..", 1)); }" } end -- in*n out*n addr*w readclk writeclk
local binaries = {
{"And" , "&&", "" },
{"Or" , "||", "" },
{"Xor" , "^" , "" },
{"Nand", "&&", "!"},
{"Nor" , "||", "!"},
{"Xnor", "^" , "!"},
}
local romsizes = { -- copied from brick gen
-- 1 bit data 4 bit data 8 bit data 16 bit data 32 bit data 48 bit data 64 bit data
{ 4, 4 }, { 4, 4, 4}, { 8, 2, 8}, -- 4 bit addr
{ 8, 8 }, { 8, 8, 4}, { 8, 8, 8}, {16, 4, 16}, {32, 2, 32}, {64, 1, 48}, {64, 1, 64}, -- 6 bit addr
{16, 16 }, {16, 16, 4}, {16, 16, 8}, {16, 16, 16}, {32, 8, 32}, {64, 4, 48}, {64, 4, 64}, -- 8 bit addr
{32, 16 }, {32, 16, 4}, {32, 16, 8}, {32, 16, 16}, {32, 16, 32}, {64, 8, 48}, {64, 8, 64}, -- 9 bit addr
{32, 32, 8}, {32, 32, 16}, {32, 32, 32}, {64, 16, 48}, {64, 16, 64}, -- 10 bit addr
{64, 32, 8}, {64, 32, 16}, {64, 32, 32}, {64, 32, 48}, {64, 32, 64}, -- 11 bit addr
{64, 64, 8}, {64, 64, 16}, {64, 64, 32}, {64, 64, 48}, {64, 64, 64}, -- 12 bit addr
}
local ramsizes = {
{8, 8},
{8, 12},
}
local gates = {
{ name = "Diode", names = {"Diode", "Diode Up", "Diode Down"}, func = "setport(2, getport(1));" },
{ name = "Not" , names = {"Not" , "Not Up" , "Not Down" }, func = "setport(2, !getport(1));" },
createEnabler(1), createEnabler(2), createEnabler(3), createEnabler(4), createEnabler(5), createEnabler(6), createEnabler(7), createEnabler(8), createEnabler(9), createEnabler(10), createEnabler(11), createEnabler(12), createEnabler(13), createEnabler(14), createEnabler(15), createEnabler(16), createEnabler(24), createEnabler(32), createEnabler(48), createEnabler(64),
createBuffer (1), createBuffer (2), createBuffer (3), createBuffer (4), createBuffer (5), createBuffer (6), createBuffer (7), createBuffer (8), createBuffer (9), createBuffer (10), createBuffer (11), createBuffer (12), createBuffer (13), createBuffer (14), createBuffer (15), createBuffer (16), createBuffer (24), createBuffer (32), createBuffer (48), createBuffer (64),
createDFF (1), createDFF (2), createDFF (3), createDFF (4), createDFF (5), createDFF (6), createDFF (7), createDFF (8), createDFF (9), createDFF (10), createDFF (11), createDFF (12), createDFF (13), createDFF (14), createDFF (15), createDFF (16), createDFF (24), createDFF (32), createDFF (48), createDFF (64),
createMux (1), createMux (2), createMux (3), createMux (4), createMux (5), createMux (6), createMux (7), createMux (8),
createDemux(1), createDemux(2), createDemux(3), createDemux(4), createDemux(5), createDemux(6), createDemux(7), createDemux(8),
createAdder (2), createAdder (4), createAdder (8), createAdder (16), createAdder (32),
createIncrementer (2), createIncrementer (4), createIncrementer (8), createIncrementer (16), createIncrementer (32),
createMultiplier (2), createMultiplier (4), createMultiplier (8), createMultiplier (16), createMultiplier (32),
createDivider (2), createDivider (4), createDivider (8), createDivider (16), createDivider (32),
createShifterLeft (2), createShifterLeft (4), createShifterLeft (8), createShifterLeft (16), createShifterLeft (32),
createShifterRight(2), createShifterRight(4), createShifterRight(8), createShifterRight(16), createShifterRight(32),
}
for _, v in ipairs(binaries) do for i = 2, 8 do table.insert(gates, createBinary(v[1], v[2], v[3], i)) end end
for i, size in ipairs(romsizes) do table.insert(gates, createRom(size[1], size[2], size[3] or 1)) end
for i, size in ipairs(ramsizes) do table.insert(gates, createRam(size[1], size[2])) end
exportGates(gates)

View File

@ -1,23 +1,34 @@
local ffi = FFI
local ffi = FFI or require("ffi")
Group = {}
ffi.cdef [[
struct Gate;
struct Net {
int* state;
int* state_num;
int* in_queue;
int* update_tick;
int* num_gates_update;
struct Gate** gates_update_c;
int id;
};
]]
local last_net_id = 1
function Group.new()
local o = {
--state = ffi.new("long long", 0),
state = 0,
--state_num = ffi.new("long long", 0),
state_num = 0,
--in_queue = ffi.new("bool", false),
--in_queue = false,
--in_queue = ffi.new("long long", 0),
in_queue = 0,
local net = {
-- Logic Critical
state = ffi.new("int[1]"),
state_num = ffi.new("int[1]"),
in_queue = ffi.new("int[1]"),
update_tick = ffi.new("int[1]"),
gates_update = {},
num_gates_update = 0,
num_gates_update = ffi.new("int[1]"),
gates_update_c = nil,
fxstate = 0,
update_tick = 0,
wires = {},
out_ports = {},
@ -25,8 +36,28 @@ function Group.new()
nwires = 0,
nout_ports = 0,
nin_ports = 0,
id = last_net_id,
}
return o
last_net_id = last_net_id + 1
net.state[0] = 0
net.state_num[0] = 0
net.in_queue[0] = 0
net.update_tick[0] = 0
net.gates_update_c = ffi.cast("struct Gate**", 0)
net.c = ffi.new("struct Net")
net.c.state = net.state
net.c.state_num = net.state_num
net.c.in_queue = net.in_queue
net.c.update_tick = net.update_tick
net.c.num_gates_update = net.num_gates_update
net.c.gates_update_c = net.gates_update_c
net.c.id = net.id
return net
end
function Group.getsize(group)
@ -44,7 +75,7 @@ function Group.addwire(group, wire)
Wire.setgroup(wire, group)
Wire.update(wire)
Simulation.queuegroup(GSim, group)
Simulation.queuegroup_safe(GSim, group)
end
end
end
@ -87,6 +118,7 @@ function Group.removewire(group, wire)
group.nout_ports = 0
group.nin_ports = 0
Simulation.remove_net(GSim, group)
Simulation.dequeuegroup(GSim, group)
end
@ -99,9 +131,9 @@ function Group.addport(group, port)
group.out_ports[port] = port
group.nout_ports = group.nout_ports + 1
group.state_num = group.state_num + Port.getstate(port)
group.state_num[0] = group.state_num[0] + Port.getstate(port)
Simulation.queuegroup(GSim, group)
Simulation.queuegroup_safe(GSim, group)
elseif port.type == PortTypes.input then
if group.in_ports[port] then error("port already in group") end
@ -109,7 +141,7 @@ function Group.addport(group, port)
group.in_ports[port] = port
group.nin_ports = group.nin_ports + 1
Simulation.queuegate(GSim, Port.getgate(port))
Simulation.queuegate_safe(GSim, Port.getgate(port))
end
@ -125,9 +157,9 @@ function Group.removeport(group, port)
group.out_ports[port] = nil
group.nout_ports = group.nout_ports - 1
group.state_num = group.state_num - Port.getstate(port)
group.state_num[0] = group.state_num[0] - Port.getstate(port)
Simulation.queuegroup(GSim, group)
Simulation.queuegroup_safe(GSim, group)
elseif port.type == PortTypes.input then
if not group.in_ports[port] then error("port not in group") end
@ -135,7 +167,7 @@ function Group.removeport(group, port)
group.in_ports[port] = nil
group.nin_ports = group.nin_ports - 1
Simulation.queuegate(GSim, Port.getgate(port))
Simulation.queuegate_safe(GSim, Port.getgate(port))
end
Group.rebuild_ports(group)
@ -175,39 +207,47 @@ function Group.mergeinto(group, group2)
group.nout_ports = 0
group.nin_ports = 0
Simulation.remove_net(GSim, group)
Simulation.dequeuegroup(GSim, group)
end
-- Logic Critical
function Group.setstate(group, state)
if state ~= group.state then
local sim = GSim
group.state = state
group.update_tick = sim.current_tick
--for k, gate in ipairs(group.gates_update) do
local len = group.num_gates_update
for i = 1, len do
local gate = group.gates_update[i]
Simulation.queuegate(sim, gate)
end
Simulation.queuegroupfx(sim, group)
end
end
-- Now implemented in C
--function Group.update_c(cnet, tick)
-- local state = cnet.state_num[0]>0 and 1 or 0
-- if state ~= cnet.state[0] then
-- cnet.state[0] = state
-- cnet.update_tick[0] = tick
--
-- local len = cnet.num_gates_update[0]-1
-- for i = 0, len do
-- local cgate = cnet.gates_update_c[i]
-- if cgate.in_queue[0]==0 then
-- Simulation.queuegate_c(GSim, cgate)
-- end
-- end
--
-- --Simulation.queuegroupfx(GSim, net)
-- end
--end
function Group.update(group)
Group.setstate(group, group.state_num>0 and 1 or 0)
end
function Group.rebuild_ports(group)
group.gates_update = {}
group.num_gates_update = 0
for k, port in pairs(group.in_ports) do
function Group.rebuild_ports(net)
net.gates_update = {}
net.num_gates_update[0] = 0
local gates_seen = {}
for k, port in pairs(net.in_ports) do
if port.causeupdate then
array_add(group.gates_update, Port.getgate(port))
group.num_gates_update = group.num_gates_update + 1
local gate = Port.getgate(port)
if not gates_seen[gate] then
gates_seen[gate] = true
net.gates_update[net.num_gates_update[0]+1] = gate
net.num_gates_update[0] = net.num_gates_update[0] + 1
end
end
end
net.gates_update_c = ffi.new("struct Gate*["..(net.num_gates_update[0]+1).."]")
for i = 0, net.num_gates_update[0]-1 do
net.gates_update_c[i] = net.gates_update[i+1].c
end
net.c.gates_update_c = net.gates_update_c
end

View File

@ -2,6 +2,7 @@
-- External requirements
local socket = require("socket")
local ffi = require("ffi")
local require_l = require
-- Disallow access to undefined global variables (helps detect errors)
assert(getmetatable(_G)==nil, "_G already has a metatable")
@ -18,6 +19,8 @@ print("Save location set to \""..OPT_SAVE_DIR.."\"")
-- Local includes
dofile("iosafe.lua")
FFI = ffi
Socket = socket
require = require_l
dofile("utility.lua")
dofile("simulation.lua")
dofile("group.lua")
@ -26,9 +29,11 @@ dofile("gatedef.lua")
dofile("port.lua")
dofile("gate.lua")
dofile("save.lua")
dofile("compile.lua")
dofile("network.lua")
dofile("compiled_sim_gates.lua")
FFI = nil
Socket = nil
require = nil
-- Default settings
OPT_TICK_ENABLED = true
@ -55,6 +60,8 @@ GSim = sim
network_accept_client()
while true do
network_update()
local time = os.clock()
if OPT_TICK_ENABLED then
@ -84,8 +91,6 @@ while true do
end
if time-lastfxtime >= OPT_FX_TIME then
network_update()
if OPT_FX_UPDATES then
Simulation.sendfxupdate(sim)
end

View File

@ -1,4 +1,6 @@
local socket = Socket or require("socket")
function network_send(data)
client:send(data)
end
@ -54,9 +56,6 @@ function network_update()
local gate = GateDefinition.constructgate(definition, objref, position, rotation)
Simulation.addgate(sim, gate)
--print(gate.objref)
--Gate.init(gate)
--Gate.logic(gate)
i = i + 4
elseif data[i] == "RW" then
@ -77,9 +76,10 @@ function network_update()
local input = data[i+6]
local global = data[i+7]
local numports = tonumber(data[i+8])
local ports = {}
i = i + 8
for a = i+9, numports*5+i+8, 5 do
local ports = {}
for a = i+1, numports*5+i, 5 do
local portd = {
type = tonumber(data[a]),
position = vectotable(data[a+1]),
@ -95,11 +95,13 @@ function network_update()
local definition = GateDefinition.new(objref, name, desc, init, logic, input, global, ports)
Simulation.addgatedefinition(sim, definition)
i = i + 8 + numports*5
i = i + numports*5
elseif data[i] == "SL" then
local wire = Simulation.getwirebyref(sim, tonumber(data[i+1]))
if wire ~= nil then
Wire.setlayer(wire, tonumber(data[i+2]))
else
error("Setlayer: no wire for objref "..tonumber(data[i+1]))
end
i = i + 2
@ -113,7 +115,7 @@ function network_update()
if value < 0 or value > 999999 then
value = 0
end
if value<=0.001 then value = 0.0001 end
if value<=0.001 then value = 0.001 end
OPT_TICK_TIME = value
elseif option == "FX_UPDATES" then
OPT_FX_UPDATES = toboolean(value)
@ -138,19 +140,19 @@ function network_update()
local group = Wire.getgroup(wire)
local numwires = 0; for k, wire2 in pairs(group.wires ) do numwires = numwires +1 end
local numportsi = 0; for k, port in pairs(group.in_ports ) do numportsi = numportsi+1 end
local numgatesu = group.num_gates_update
local numgatesu = group.num_gates_update[0]
local numportso = 0; local numportson=0;
for k, port in pairs(group.out_ports) do
numportso = numportso+1
if Port.getstate(port)==1 then numportson = numportson+1 end
end
info = "\\c5Net " .. tostring(group):match("table: 0x(.+)"):upper() .. "\n" .. (Wire.getgroup(wire).state==1 and "\\c2On" or "\\c0Off") .. "\n" ..
info = "\\c5Net " .. tostring(group):match("table: 0x(.+)"):upper() .. "\n" .. (Wire.getgroup(wire).state[0]==1 and "\\c2On" or "\\c0Off") .. "\n" ..
"Wires: "..numwires.."\n"..
"In Ports: " ..numportsi.."\n"..
"Out Ports: "..numportso.."\n"..
"Gates Update: "..numgatesu.."\n"..
"Out Ports On: "..(group.state_num)
"Out Ports On: "..(group.state_num[0])
;
end
@ -182,7 +184,7 @@ function network_update()
Simulation.tickinit(sim)
Simulation.tickinput(sim)
Simulation.ticklogic(sim)
ticks = ticks + 1
--ticks = ticks + 1
elseif data[i] == "IN" then
local gate = Simulation.getgatebyref(sim, tonumber(data[i+1]))
local argc = tonumber(data[i+2])
@ -205,9 +207,7 @@ function network_update()
i = i + 1
end
elseif err == "closed" then
--sim = Simulation.new(Simulation)
--acceptclient()
print("Connection closed")
error()
end
end
end

View File

@ -17,17 +17,14 @@ PortDirections = {
Port = {}
function Port.new(type, direction, position, causeupdate, idx)
function Port.new(type, direction, position, causeupdate, idx, gate)
local o = {
--state = ffi.new("long long", 0),
state = 0,
group = nil,
type = type,
direction = direction,
position = position,
causeupdate = causeupdate,
gate = nil,
gate = gate,
idx = idx,
}
return o
@ -39,24 +36,31 @@ function Port.getconnectionposition(port)
end
function Port.isrising(port)
return port.group.state==1 and (port.group.update_tick == GSim.current_tick)
return port.group.state[0]==1 and (port.group.update_tick[0] == GSim.current_tick[0])
end
function Port.isfalling(port)
return port.group.state==0 and (port.group.update_tick == GSim.current_tick)
return port.group.state[0]==0 and (port.group.update_tick[0] == GSim.current_tick[0])
end
function Port.getgate(port)
return port.gate
end
function Port.setgate(port, gate)
port.gate = gate
end
function Port.setgroup(port, group)
port.group = group
Port.getgate(port).port_nets[port.idx] = group
if group then
Port.getgate(port).port_net_state [port.idx] = group.state
Port.getgate(port).port_net_state_num[port.idx] = group.state_num
Port.getgate(port).port_net_in_queue [port.idx] = group.in_queue
Port.getgate(port).port_nets_c [port.idx] = group.c
else
Port.getgate(port).port_net_state [port.idx] = ffi.cast("int*", 0)
Port.getgate(port).port_net_state_num[port.idx] = ffi.cast("int*", 0)
Port.getgate(port).port_net_in_queue [port.idx] = ffi.cast("int*", 0)
Port.getgate(port).port_nets_c [port.idx] = ffi.cast("struct Net*", 0)
end
end
function Port.getgroup(port)
@ -68,5 +72,5 @@ function Port.gettype(port)
end
function Port.getstate(port)
return port.state
return Port.getgate(port).port_states[port.idx]
end

View File

@ -1,18 +1,39 @@
local ffi = FFI or require("ffi")
ffi.cdef [[
struct Gate;
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
if jit.os=="Windows" then
csim = ffi.load("./compiled_sim.dll")
else
csim = ffi.load("./compiled_sim.so")
end
Simulation = {}
local queue_max = 65536
local cb_queue_max = 256
function Simulation.new(sim)
local o = {
groupqueue = {},
num_groupqueue = 0,
gatequeue = {},
num_gatequeue = 0,
groupfxqueue = {},
current_tick = 0,
-- Logic Critical
groupqueue = ffi.new("struct Net*["..queue_max.."]"),
num_groupqueue = ffi.new("int[1]"),
gatequeue = ffi.new("struct Gate*["..queue_max.."]"),
num_gatequeue = ffi.new("int[1]"),
current_tick = ffi.new("int[1]"),
--groupfxqueue = {},
definitions = {},
wires = {},
gates = {},
nets = {},
nwires = 0,
ngates = 0,
ninports = 0,
@ -22,10 +43,13 @@ function Simulation.new(sim)
inputqueue = nil,
tickqueue = {},
callbacks = nil,
}
setmetatable(o, sim)
sim.__index = sim
o.num_groupqueue[0] = 0
o.num_gatequeue[0] = 0
o.current_tick[0] = 0
csim.sim_set_data(o.groupqueue, o.num_groupqueue, o.gatequeue, o.num_gatequeue, o.current_tick, queue_max)
return o
end
@ -116,8 +140,9 @@ function Simulation.addgate(sim, gate)
sim.ngates = sim.ngates + 1
Gate.preinit(gate)
Simulation.queuegateinit(sim, gate)
Simulation.queuegate(sim, gate)
Simulation.queuegate_safe(sim, gate)
end
function Simulation.removewire(sim, objref)
@ -183,7 +208,10 @@ function Simulation.connectwireat(sim, wire, x, y, z)
for k, obj in pairs(objs) do
if obj ~= wire and obj.group ~= nil then
if is_wire(obj) then -- wire
if Wire.getlayer(obj) == Wire.getlayer(wire) then -- same layer
local layer1 = Wire.getlayer(wire)
local layer2 = Wire.getlayer(obj)
--if they are on the same real layer, or exactly one is rainbow but not both, then connect
if ((layer1==layer2) or (layer1==-1 and layer2~=-1) or (layer1~=-1 and layer2==-1)) and (not (layer1==-1 and layer2==-1)) then
Group.addwire(obj.group, wire)
end
else -- port
@ -218,7 +246,9 @@ function Simulation.connectwire(sim, wire)
end
if Wire.getgroup(wire)==nil then
Group.addwire(Group.new(), wire)
local newnet = Group.new()
Simulation.add_net(sim, newnet)
Group.addwire(newnet, wire)
end
end
@ -232,21 +262,34 @@ function Simulation.connectport(sim, port)
end
if Port.getgroup(port) == nil then
Group.addport(Group.new(), port)
local newnet = Group.new()
Simulation.add_net(sim, newnet)
Group.addport(newnet, port)
end
end
-- Logic Critical
function Simulation.queuegate_c(sim, cgate)
assert(sim.num_gatequeue[0] < queue_max-1)
sim.gatequeue[sim.num_gatequeue[0]] = cgate
sim.num_gatequeue[0] = sim.num_gatequeue[0] + 1
cgate.in_queue[0] = 1
end
function Simulation.queuegate(sim, gate)
if gate.in_queue==0 then
table.insert(sim.gatequeue, gate)
sim.num_gatequeue = sim.num_gatequeue + 1
gate.in_queue = 1
local cgate = gate.c
Simulation.queuegate_c(sim, cgate)
end
function Simulation.queuegate_safe(sim, gate)
if gate.in_queue[0]==0 then
Simulation.queuegate(sim, gate)
end
end
-- Logic Critical
function Simulation.queuegatelater(sim, gate, delay)
local tick = sim.current_tick + delay
local tick = sim.current_tick[0] + delay
if sim.tickqueue[tick] == nil then
sim.tickqueue[tick] = {}
end
@ -255,7 +298,8 @@ end
function Simulation.queuegateinput(sim, gate, argv)
sim.inputqueue = sim.inputqueue or {}
sim.inputqueue[gate] = argv
sim.inputqueue[gate] = sim.inputqueue[gate] or {}
table.insert(sim.inputqueue[gate], argv)
end
function Simulation.queuegateinit(sim, gate)
@ -264,29 +308,36 @@ function Simulation.queuegateinit(sim, gate)
end
-- Logic Critical
function Simulation.queuegroup(sim, group)
if group.in_queue==0 then
--table.insert(sim.groupqueue, group)
sim.groupqueue[sim.num_groupqueue+1] = group
sim.num_groupqueue = sim.num_groupqueue + 1
group.in_queue = 1
function Simulation.queuegroup_c(sim, cnet)
assert(sim.num_groupqueue[0] < queue_max-1)
sim.groupqueue[sim.num_groupqueue[0]] = cnet
sim.num_groupqueue[0] = sim.num_groupqueue[0] + 1
cnet.in_queue[0] = 1
end
function Simulation.queuegroup(sim, net)
local cnet = net.c
Simulation.queuegroup_c(sim, cnet)
end
function Simulation.queuegroup_safe(sim, group)
if group.in_queue[0]==0 then
Simulation.queuegroup(sim, group)
end
end
function Simulation.dequeuegroup(sim, group)
if group.in_queue~=0 then
array_remove(sim.groupqueue, group)
sim.num_groupqueue = sim.num_groupqueue - 1
group.in_queue = 0
if group.in_queue[0]~=0 then
sim.num_groupqueue[0] = array_remove(sim.groupqueue, sim.num_groupqueue[0], group.c, true)
group.in_queue[0] = 0
end
sim.groupfxqueue[group] = nil
--sim.groupfxqueue[group] = nil
end
function Simulation.dequeuegate(sim, gate)
if gate.in_queue~=0 then
array_remove(sim.gatequeue, gate)
sim.num_gatequeue = sim.num_gatequeue - 1
gate.in_queue = 0
if gate.in_queue[0]~=0 then
sim.num_gatequeue[0] = array_remove(sim.gatequeue, sim.num_gatequeue[0], gate.c, true)
gate.in_queue[0] = 0
end
if sim.inputqueue~=nil then sim.inputqueue[gate] = nil end
if sim.initqueue ~=nil then sim.initqueue [gate] = nil end
@ -295,45 +346,68 @@ function Simulation.dequeuegate(sim, gate)
end
end
function Simulation.queuegroupfx(sim, group)
sim.groupfxqueue[group] = group
--function Simulation.queuegroupfx(sim, group)
-- sim.groupfxqueue[group] = group
--end
-- Callbacks
function Simulation.setcallback(sim, gate, arg)
sim.callbacks = sim.callbacks or {}
sim.callbacks[gate.objref] = { arg }
end
function Simulation.queuecallback(sim, gate, ...)
function Simulation.queuecallback(sim, gate, arg, limit)
sim.callbacks = sim.callbacks or {}
sim.callbacks[gate.objref] = {...}
sim.callbacks[gate.objref] = sim.callbacks[gate.objref] or {}
if #sim.callbacks[gate.objref] < limit then
table.insert(sim.callbacks[gate.objref], arg)
end
end
function Simulation.sendcallbacks(sim)
if sim.callbacks ~= nil then
local data = "CB"
for objref, args in pairs(sim.callbacks) do
local escargs = {}
for argidx, argv in ipairs(args) do
table.insert(escargs, expandescape(tostring(argv)))
end
local argstr = table.concat(escargs, "\t")
data = data .. "\t" .. objref .. "\t" .. #escargs .. (#escargs>0 and ("\t"..argstr) or "")
end
network_send(data .. "\n")
sim.callbacks = nil
end
end
-- Logic Critical
function Simulation.ticklogic(sim)
--for k, group in ipairs(sim.groupqueue) do
local len = sim.num_groupqueue
for i = 1, len do
local group = sim.groupqueue[i]
Group.update(group)
group.in_queue = 0
end
sim.groupqueue = {}
sim.num_groupqueue = 0
csim.sim_update_nets()
if sim.tickqueue[sim.current_tick] ~= nil then
for i, gate in pairs(sim.tickqueue[sim.current_tick]) do
Simulation.queuegate(sim, gate)
if sim.tickqueue[sim.current_tick[0]] ~= nil then
for i, gate in pairs(sim.tickqueue[sim.current_tick[0]]) do
if gate.in_queue[0]==0 then
Simulation.queuegate(sim, gate)
end
end
sim.tickqueue[sim.current_tick] = nil
sim.tickqueue[sim.current_tick[0]] = nil
end
--for k, gate in ipairs(sim.gatequeue) do
local len = sim.num_gatequeue
for i = 1, len do
local gate = sim.gatequeue[i]
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)
gate.logic(gate)
gate.in_queue = 0
cgate.in_queue[0] = 0
sim.gatequeue[i] = nil
end
sim.gatequeue = {}
sim.num_gatequeue = 0
sim.num_gatequeue[0] = 0
sim.current_tick = sim.current_tick + 1
sim.current_tick[0] = sim.current_tick[0] + 1
end
function Simulation.tickinit(sim)
@ -347,19 +421,24 @@ end
function Simulation.tickinput(sim)
if sim.inputqueue ~= nil then
for gate, argv in pairs(sim.inputqueue) do
Gate.input(gate, argv)
for gate, inputs in pairs(sim.inputqueue) do
for k, argv in ipairs(inputs) do
Gate.input(gate, argv)
end
end
sim.inputqueue = nil
end
end
-- FX
function Simulation.sendfxupdate(sim)
for k, group in pairs(sim.groupfxqueue) do
if group.state ~= group.fxstate then
group.fxstate = group.state
--for k, group in pairs(sim.groupfxqueue) do
for k, group in pairs(sim.nets) do
if group.state[0] ~= group.fxstate then
group.fxstate = group.state[0]
local data = group.state
local data = group.state[0]
for i, wire in pairs(group.wires) do
data = data .. "\t" .. Wire.getobjref(wire)
@ -369,22 +448,20 @@ function Simulation.sendfxupdate(sim)
end
end
sim.groupfxqueue = {}
--sim.groupfxqueue = {}
end
function Simulation.sendcallbacks(sim)
if sim.callbacks ~= nil then
local data = "CB"
for objref, args in pairs(sim.callbacks) do
local escargs = {}
for argidx, argv in ipairs(args) do
table.insert(escargs, expandescape(tostring(argv)))
end
data = data .. "\t" .. objref .. "\t"..(#escargs)..(#escargs>0 and ("\t"..table.concat(escargs, "\t")) or "")
end
network_send(data .. "\n")
sim.callbacks = nil
end
function Simulation.add_net(sim, net)
sim.nets[net.id] = net
end
function Simulation.remove_net(sim, net)
sim.nets[net.id] = nil
end
function Simulation.net_from_cnet(sim, cnet)
return sim.nets[cnet.id] or error("no net for id "..cnet.id)
end
function Simulation.gate_from_cgate(sim, cgate)
return sim.gates[cgate.objref] or error("no gate for objref "..cgate.objref)
end

View File

@ -68,24 +68,28 @@ function tobitstring(num, len)
return bitstring
end
function array_remove(array, value)
for i = 1, #array do
function array_remove(array, len, value, pass)
for i = 0, len-1 do
local v = array[i]
if v==value then
array[i] = array[#array]
array[#array] = nil
return
array[i] = array[len-1]
array[len-1] = nil
len = len - 1
return len
end
end
error("element not in array")
if not pass then error("element not in array") end
return len
end
function array_add(array, value)
for i = 1, #array do
function array_add(array, len, value)
for i = 0, len-1 do
local v = array[i]
if v==value then return end
if v==value then return len end
end
table.insert(array, value)
array[len] = value
len = len + 1
return len
end
function round(x)

View File

@ -20,7 +20,9 @@ function Wire.setlayer(wire, layer)
end
function Wire.update(wire)
network_send("WU\t" .. (wire.group.state~=0 and "1" or "0") .. "\t" .. wire.objref .. "\n")
if wire.layer~=-1 then
network_send("WU\t" .. (wire.group.state[0]~=0 and "1" or "0") .. "\t" .. wire.objref .. "\n")
end
end
function Wire.setgroup(wire, group)