121 lines
8.3 KiB
Lua
121 lines
8.3 KiB
Lua
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.log(n)/math.log(2) 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 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 = (n>=32 and "unsigned long long" or "int").." v = getword("..n..", 1) + getword("..n..", "..(n+1)..") + getport("..(n*3+1).."); setword("..n..", "..(n*2+1)..", v); setport("..(n*3+2)..", (v>>"..n..") & 1);" } 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(1), createAdder(2), createAdder(4), createAdder(8), createAdder(16), createAdder(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)
|