view ueda/sverp/prim.c @ 81:6e43956e740d

beginning of BOM utils refactoring: seqrefdes code factored out
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 23 Feb 2017 19:15:48 +0000
parents 7b4f78fcca08
children
line wrap: on
line source

/*
 * Parsing of the primitives definition file happens here.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "../libueda/xga.h"
#include "struct.h"
#include "lexer.h"

extern struct grid_pkg_desc *read_grid_pkg_file();

extern struct module_def *glob_module_list;

extern char *parser_filename;
extern FILE *parser_readF;
extern int parser_lineno;
extern char parser_read_word[];
extern int parser_read_number;
extern int pushback_token;

static struct module_def *curmod;

static void
create_module()
{
	register struct module_def *mod, **modp;
	char *buf;

	for (modp = &glob_module_list; mod = *modp; modp = &mod->next) {
		if (!strcmp(mod->name, parser_read_word))
			parse_error("primitive conflicts with a module name");
	}
	buf = malloc(sizeof(struct module_def) + strlen(parser_read_word) + 1);
	if (!buf) {
		perror("malloc");
		exit(1);
	}
	mod = (struct module_def *) buf;
	bzero(mod, sizeof(struct module_def));
	buf += sizeof(struct module_def);
	strcpy(buf, parser_read_word);
	mod->name = buf;
	mod->is_primitive = 1;
	*modp = mod;
	curmod = mod;
}

static void
add_pin(pinname)
	register char *pinname;
{
	register struct module_net_def *n, **np;
	char *buf;

	for (np = &curmod->nets; n = *np; np = &n->next) {
		if (!strcmp(n->name, pinname))
			parse_error("duplicate pin name");
	}
	buf = malloc(sizeof(struct module_net_def) + strlen(pinname) + 1);
	if (!buf) {
		perror("malloc");
		exit(1);
	}
	n = (struct module_net_def *) buf;
	bzero(n, sizeof(struct module_net_def));
	buf += sizeof(struct module_net_def);
	strcpy(buf, pinname);
	n->name = buf;
	n->is_port = 1;
	n->def_complete = 1;
	n->bus_width = 1;
	n->array_index = curmod->nports;
	*np = n;
	curmod->nports++;
	curmod->nwires_ports++;
}

static void
handle_num_pins()
{
	int t;
	register int i;
	char namebuf[MAXDIGITS+5];

	curmod->prim_numeric_pins = 1;
	t = get_token();
	if (t != NUMBER)
		parse_error("expected a number after numpins");
	for (i = 1; i <= parser_read_number; i++) {
		sprintf(namebuf, "pin_%d", i);
		add_pin(namebuf);
	}
}

static void
handle_named_pins(ismapped)
{
	register int t;

	curmod->prim_is_mapped = ismapped;
	t = get_token();
	if (t != '(')
		parse_error("expected '(' after named_pins or mapped_pins");
	for (;;) {
		t = get_token();
		if (t == ')')
			return;
		if (t != WORD)
			parse_error("expected pin name");
		add_pin(parser_read_word);
		t = get_token();
		if (t == ')')
			return;
		if (t != ',')
			parse_error("expected ',' or ')' in pin name list");
	}
}

static void
handle_grid_pkg()
{
	int t;
	register struct grid_pkg_desc *desc;
	register int r, c;
	char namebuf[32];

	t = get_token();
	if (t != QSTRING)
		parse_error("expected quoted filename after grid");
	desc = read_grid_pkg_file(parser_read_word);
	for (r = 0; r < desc->nrows; r++)
		for (c = 0; c < desc->ncolumns; c++) {
			if (desc->holes_array[r * desc->ncolumns + c])
				continue;
			sprintf(namebuf, "%c%d", desc->row_letters[r], c + 1);
			add_pin(namebuf);
		}
	free_grid_pkg_desc(desc);
}

read_primitives_file(filename_arg)
	char *filename_arg;
{
	register int t;

	parser_filename = filename_arg;
	parser_readF = fopen(parser_filename, "r");
	if (!parser_readF) {
		perror(parser_filename);
		exit(1);
	}
	parser_lineno = 1;
	pushback_token = 0;

	for (;;) {
		t = get_token();
		if (!t)
			break;
		if (t != WORD)
			parse_error("expected primitive name");
		create_module();
		t = get_token();
		if (t != WORD)
			parse_error("expected pins type keyword");
		if (!strcmp(parser_read_word, "numpins"))
			handle_num_pins();
		else if (!strcmp(parser_read_word, "grid"))
			handle_grid_pkg();
		else if (!strcmp(parser_read_word, "named_pins"))
			handle_named_pins(0);
		else if (!strcmp(parser_read_word, "mapped_pins"))
			handle_named_pins(1);
		else {
			fprintf(stderr,
		"%s line %d: \"%s\" is not an understood primitive type\n",
				parser_filename, parser_lineno,
				parser_read_word);
			exit(1);
		}
		t = get_token();
		if (t != ';')
			parse_error("expected terminating ';'");
	}

	fclose(parser_readF);
	return(0);
}