view ueda/sverp/output.c @ 139:bf188727e606

donl-rename-parts reader: no tEDAx-style escapes
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 07 Sep 2020 04:25:11 +0000
parents 7b4f78fcca08
children
line wrap: on
line source

/*
 * ueda-sverp netlist output
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "struct.h"

extern struct output_net *output_net_head;
extern struct output_element *output_element_head;
extern int total_good_nets, total_singular_nets, total_null_nets;
extern int total_output_elements;
extern char *output_filename;

static FILE *outF;
static int net_comment_column;

static void
find_net_comment_column()
{
	register struct output_net *net;
	register int len, maxlen;

	maxlen = 0;
	for (net = output_net_head; net; net = net->next) {
		if (net->npoints < 2)
			continue;
		len = strlen(net->name);
		if (len > maxlen)
			maxlen = len;
	}
	maxlen += 4;
	do
		maxlen++;
	while (maxlen % 8);
	net_comment_column = maxlen;
}

static void
emit_good_nets()
{
	register struct output_net *net;
	register int col;

	fprintf(outF, "\n# Elaborated net wires (%d total):\n#\n",
		total_good_nets);
	for (net = output_net_head; net; net = net->next) {
		if (net->npoints < 2)
			continue;
		fprintf(outF, "NET %s", net->name);
		col = 4 + strlen(net->name);
		do {
			fputc('\t', outF);
			col += 8;
			col &= ~7;
		} while (col < net_comment_column);
		fprintf(outF, "# %d points\n", net->npoints);
	}
}

static void
emit_singular_nets()
{
	register struct output_net *net;

	fprintf(outF,
		"\n# Singular nets converted into no-connects (%d total):\n#\n",
		total_singular_nets);
	for (net = output_net_head; net; net = net->next) {
		if (net->npoints != 1)
			continue;
		fprintf(outF, "# %s\n", net->name);
	}
}

static void
emit_null_nets()
{
	register struct output_net *net;

	fprintf(outF, "\n# Net wires declared but not used (%d total):\n#\n",
		total_null_nets);
	for (net = output_net_head; net; net = net->next) {
		if (net->npoints)
			continue;
		fprintf(outF, "# %s\n", net->name);
	}
}

static void
emit_output_element(elem)
	struct output_element *elem;
{
	register struct module_def *mod = elem->prim_def;
	register struct module_net_def *port;
	register struct output_net **connp = elem->connections, *conn;
	char *pinkw, *pinname;

	fprintf(outF, "\nCOMPONENT %s {\n  PRIMITIVE %s\n\n",
		elem->hier_inst_name, mod->name);
	if (mod->prim_is_mapped)
		pinkw = "PINMAP";
	else
		pinkw = "PIN";
	for (port = mod->nets; port; port = port->next) {
		pinname = port->name;
		if (mod->prim_numeric_pins)
			pinname += 4;
		fprintf(outF, "  %s %s = ", pinkw, pinname);
		conn = *connp++;
		if (conn->name) {
			if (conn->npoints > 1)
				fprintf(outF, "NET %s", conn->name);
			else
				fprintf(outF, "NC (singular net %s)",
					conn->name);
		} else
			fprintf(outF, "NC (module %s line %d inst %s)",
				conn->nc_module_name, conn->nc_module_lineno,
				conn->nc_module_inst);
		fputc('\n', outF);
	}
	fputs("}\n", outF);
}

static void
emit_output_elements()
{
	register struct output_element *elem;

	fprintf(outF, "\n# Total instantiated components: %d\n",
		total_output_elements);
	for (elem = output_element_head; elem; elem = elem->next)
		emit_output_element(elem);
}

generate_output()
{
	outF = fopen(output_filename, "w");
	if (!outF) {
		perror(output_filename);
		exit(1);
	}
	fputs("# This netlist has been generated by ueda-sverp\n", outF);
	fputs("# from structural Verilog sources\n", outF);
	if (total_good_nets) {
		find_net_comment_column();
		emit_good_nets();
	}
	if (total_singular_nets)
		emit_singular_nets();
	if (total_null_nets)
		emit_null_nets();
	emit_output_elements();
	fclose(outF);
}