mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			221 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
#!/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
 | 
						|
	<?spl var net = []; ?>
 | 
						|
	  ${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
 | 
						|
	<?spl var ports; ?>
 | 
						|
	  ${makeGraph(1, 100, ports, ports)}
 | 
						|
	<?spl numNodes["needle_1"] = idx*4; ?>
 | 
						|
	<spl:foreach var="[]net" list="ports">
 | 
						|
	:   extern $net
 | 
						|
	</spl:foreach>
 | 
						|
	: endgraph
 | 
						|
	:
 | 
						|
	: graph needle_2
 | 
						|
	<?spl var ports; ?>
 | 
						|
	  ${makeGraph(2, 200, ports, ports)}
 | 
						|
	<?spl numNodes["needle_2"] = idx*4; ?>
 | 
						|
	<spl:foreach var="[]net" list="ports">
 | 
						|
	:   extern $net
 | 
						|
	</spl:foreach>
 | 
						|
	: endgraph
 | 
						|
	:
 | 
						|
	: graph needle_3
 | 
						|
	<?spl var ports; ?>
 | 
						|
	  ${makeGraph(3, 300, ports, ports)}
 | 
						|
	<?spl numNodes["needle_3"] = idx*4; ?>
 | 
						|
	<spl:foreach var="[]net" list="ports">
 | 
						|
	:   extern $net
 | 
						|
	</spl:foreach>
 | 
						|
	: endgraph
 | 
						|
	:
 | 
						|
	: graph haystack
 | 
						|
 | 
						|
	<?spl count_nand=0; count_nor=0; ?>
 | 
						|
 | 
						|
	<?spl var inPorts1, outPorts1; ?>
 | 
						|
	  ${makeGraph(1, 100, inPorts1, outPorts1)}
 | 
						|
 | 
						|
	<?spl var inPorts2, outPorts2; ?>
 | 
						|
	  ${makeGraph(2, 200, inPorts2, outPorts2)}
 | 
						|
 | 
						|
	<?spl var inPorts3, outPorts3; ?>
 | 
						|
	  ${makeGraph(3, 300, inPorts3, outPorts3)}
 | 
						|
 | 
						|
	<?spl var inPorts4, outPorts4; ?>
 | 
						|
	  ${makeGraph(2, 200, inPorts4, outPorts4)}
 | 
						|
 | 
						|
	<?spl var inPorts5, outPorts5; ?>
 | 
						|
	  ${makeGraph(1, 100, inPorts5, outPorts5)}
 | 
						|
	<?spl numNodes["haystack"] = idx*4; ?>
 | 
						|
 | 
						|
	  ${makeConnections(outPorts1, inPorts2)}
 | 
						|
	  ${makeConnections(outPorts2, inPorts3)}
 | 
						|
	  ${makeConnections(outPorts3, inPorts4)}
 | 
						|
	  ${makeConnections(outPorts4, inPorts5)}
 | 
						|
 | 
						|
	: endgraph
 | 
						|
	:
 | 
						|
	: solve nand haystack false
 | 
						|
	: expect $count_nand
 | 
						|
	: clearoverlap
 | 
						|
	:
 | 
						|
	: solve nor haystack false
 | 
						|
	: expect $count_nor
 | 
						|
	: clearoverlap
 | 
						|
	:
 | 
						|
	: solve needle_1 haystack false
 | 
						|
	: expect 2
 | 
						|
	:
 | 
						|
	: solve needle_2 haystack false
 | 
						|
	: expect 2
 | 
						|
	:
 | 
						|
	: solve needle_3 haystack false
 | 
						|
	: expect 1
 | 
						|
</>);
 | 
						|
 | 
						|
numNodes["haystack"] -= numNodes["needle_3"];
 | 
						|
numNodes["needle_3"] -= numNodes["needle_2"];
 | 
						|
numNodes["needle_2"] -= numNodes["needle_1"];
 | 
						|
 | 
						|
write(<:>
 | 
						|
	:
 | 
						|
	: # Needle_1: ${numNodes["needle_1"]} transistors
 | 
						|
	: # Needle_2: ${numNodes["needle_2"]} transistors
 | 
						|
	: # Needle_3: ${numNodes["needle_3"]} transistors
 | 
						|
	: # Haystack: ${numNodes["haystack"]} transistors
 | 
						|
</>);
 | 
						|
 |