#!/usr/bin/env splrun
var idx = 0;
var count_nand = 0;
var count_nor = 0;
function makeNAND(net, id)
{
count_nand++;
net["${id}_VDD"] = "${id}_pa S";
net["${id}_VSS"] = "${id}_nb S";
net["${id}_A"] = "${id}_pa G";
net["${id}_B"] = "${id}_pb G";
net["${id}_Y"] = "${id}_pb D";
return <:>
: node ${id}_pa pmos S 1 D 1 G 1
: node ${id}_pb pmos S 1 D 1 G 1
: node ${id}_na nmos S 1 D 1 G 1
: node ${id}_nb nmos S 1 D 1 G 1
: connect ${id}_pa S ${id}_pb S
: connect ${id}_pa D ${id}_pb D
: connect ${id}_pa D ${id}_na D
: connect ${id}_na S ${id}_nb D
: connect ${id}_pa G ${id}_na G
: connect ${id}_pb G ${id}_nb G
>;
}
function makeNOR(net, id)
{
count_nor++;
net["${id}_VDD"] = "${id}_pa S";
net["${id}_VSS"] = "${id}_nb S";
net["${id}_A"] = "${id}_pa G";
net["${id}_B"] = "${id}_pb G";
net["${id}_Y"] = "${id}_pb D";
return <:>
: node ${id}_pa pmos S 1 D 1 G 1
: node ${id}_pb pmos S 1 D 1 G 1
: node ${id}_na nmos S 1 D 1 G 1
: node ${id}_nb nmos S 1 D 1 G 1
: connect ${id}_pa D ${id}_pb S
: connect ${id}_pb D ${id}_na D
: connect ${id}_pb D ${id}_nb D
: connect ${id}_na S ${id}_nb S
: connect ${id}_pa G ${id}_na G
: connect ${id}_pb G ${id}_nb G
>;
}
function makeGraph(seed, gates, primaryInputs, primaryOutputs)
{
srand(seed);
var code = "";
var net, vdd, vss, outputs;
var unusedOutpus;
for (var i = 0; i < gates; i++)
{
var id = fmt("G%d", idx++);
if (rand(2) == 0)
code ~= makeNAND(net, id);
else
code ~= makeNOR(net, id);
if (i == 0) {
vdd = net["${id}_VDD"];
vss = net["${id}_VSS"];
} else {
code ~= <:>
: connect $vdd ${net["${id}_VDD"]}
: connect $vss ${net["${id}_VSS"]}
>;
}
var inIdx1 = rand((elementsof outputs) + 1);
if (inIdx1 < elementsof outputs) {
code ~= " connect ${outputs[inIdx1]} ${net["${id}_A"]}\n";
delete unusedOutpus[outputs[inIdx1]];
} else
push primaryInputs, net["${id}_A"];
var inIdx2 = rand((elementsof outputs) + 1);
if (inIdx2 < elementsof outputs) {
code ~= " connect ${outputs[inIdx2]} ${net["${id}_B"]}\n";
delete unusedOutpus[outputs[inIdx2]];
} else
push primaryInputs, net["${id}_B"];
unusedOutpus[net["${id}_Y"]] = 1;
push outputs, net["${id}_Y"];
}
foreach netDecl (unusedOutpus)
push primaryOutputs, netDecl;
return code;
}
function makeConnections(fromNets, toNets)
{
var code = "";
foreach[] toNet (toNets) {
var fromNet = fromNets[rand(elementsof fromNets)];
code != " connect $fromNet $toNet\n";
}
return code;
}
var numNodes;
write(<:>
: graph nand
${makeNAND(net, "nand")}
: extern ${net["nand_VDD"]}
: extern ${net["nand_VSS"]}
: extern ${net["nand_A"]}
: extern ${net["nand_B"]}
: extern ${net["nand_Y"]}
: endgraph
:
: graph nor
${makeNOR(net, "nor")}
: extern ${net["nor_VDD"]}
: extern ${net["nor_VSS"]}
: extern ${net["nor_A"]}
: extern ${net["nor_B"]}
: extern ${net["nor_Y"]}
: endgraph
:
: graph needle_1
${makeGraph(1, 100, ports, ports)}