
/*
 * $Id: unrouted.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $
 *
 * $Log: unrouted.c,v $
 * Revision 1.1.1.1  2003/11/04 23:34:57  mjames
 * Imported into local repositrory
 *
 * Revision 1.5  2002/09/27 22:27:37  MJAMES
 * Added lhs_expr for cases like
 *
 * x(0) <= y
 *
 * where x is std_logic_vector(0 downto 0) and y is std_logic.
 *
 * Revision 1.4  2002/01/16 10:08:53  mjames
 * converted to use #ident
 *
 * Revision 1.3  2001/10/31 22:20:19  mjames
 * Tidying up problematical comments caused by CVS
 * 'intelligent' comment guessing
 *
 */

#include "unrouted.h"

#include "cmdlog.h"
#include "cmdparse.h"
#include "database.h"
#include "expression.h"
#include "generic.h"
#include "lx_support.h"
#include "statistics.h"
#include "vertcl_main.h"

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ident                                                                                        \
    "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/unrouted.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"

/* function that creates the node reference lists for one chip in the list ,
   these functions perform operations that were done inside database.c.
  */

int create_nodes_from_refs (socket_t *socket, int donesomething)
{
        unrouted_ref_t *ref, *prev;
        node_t *cnode;
        net_t *cnet;
        char null_name;
        char *netname;
        int errseen = 0;
        if (!socket)
        {
                Log (LOG_ERROR, "-- missing socket \n");
                return (1);
        }

        ref = socket->unrouted_refs;
        while (ref)
        {
                /* pick up any new pin identifiers */
                cnode = find_node (socket, Ident, ref->identifier, Create);

                /* if this node is already on a net on the routed list,
                   it has already been linked up
                   so it should not be duplicated !!  */
                /* iterate each node on the chip */

                if ((ref->listref == &routed_list) && cnode->net) /* duplicate !!! */
                {
                        if (!errseen)
                        {
                                errseen = 1;
                                Log (
                                    LOG_ERROR,
                                    "-- Errors while creating unrouted list from pins :\n");
                        }
                        Log (
                            LOG_ERROR,
                            "--  Error ! node %s(%s) is already in existence on routed net "
                            "%s\n",
                            socket->identifier,
                            ref->identifier,
                            cnode->net->name);
                }
                else
                {
                        netname = ref->name;
                        null_name = ISNULLSTR (netname);
                        /* bidir pins are essentially free for routing */
                        if (null_name || socket->is_template)
                        {
                                if (ref->pindir != BIDIR)
                                        cnode->fixed_pin = 1;
                                cnode->pindir = ref->pindir;
                        }
                        if (socket->is_template || ref->listref == &routed_list)
                        {
                                cnode->pin_group = ref->pin_group;

                                cnode->vhdltype = ref->vhdltype;
#if defined DEBUG_EXPRESSION
                                if (cnode->vhdltype)
                                {
                                        print_msg_expression (
                                            stdout, "COPYING ", cnode->vhdltype->expr);
                                }
#endif
                                if (!null_name)
                                        cnode->name = strdup (netname);
                        }
                        if (!socket->is_template && !null_name)
                        {
                                cnet = find_net (ref->listref, Ident, netname, Create);
                                connect_node_net (
                                    ref->orig_name,
                                    cnode,
                                    cnet,
                                    ref->pindir,
                                    ref->vhdltype,
                                    ref->orig_vhdltype,
                                    ref->lhs_expr);
                                donesomething = 1;
                        };
                }
                prev = ref;
                ref = ref->next;
                free (prev);
        }
        socket->unrouted_refs = NULL; /* remove any references to unrouted stuff,
                                         they are all free()'d now */

        return 0;
}

/* creates the unrouted list from unrouted_refs list for all sockets */

void create_unrouted_list (void)
{
        socket_t *socket = socket_head;
        int donesomething = 0;
        while (socket)
        {
                donesomething = create_nodes_from_refs (socket, donesomething);
                socket = socket->next;
        }
        if (donesomething)
                Log (LOG_GENERAL, "-- New pins converted to unrouted net\n");
}

void rename_unrouted_pin_socket (
    socket_t *socket, char *old_name, char *new_name, vhdl_t *vhdl_type)
{
        unrouted_ref_t *ref;
        char *socket_name;

        socket_name = socket->identifier;

        ref = socket->unrouted_refs;

        if (!ref)
                Log (
                    LOG_ERROR, "# ERROR pin rename : no pin '%s.%s'\n", socket_name, old_name);

        while (ref)
        {
                if (strcmp2 (old_name, ref->name) == 0)
                {
                        /* do rename only if there is a rename */
                        if (strcmp2 (ref->orig_name, ref->name) != 0)
                        {
                                ref->orig_name = ref->name; /* keep old name in alias part */
                                ref->name =
                                    strdup (new_name); /* and rename the unrouted node */
                        }
                        /* if it does not have a base type then copy it */
                        if (!vhdl_type->basetype)
                                vhdl_type->basetype = default_vhdl_datatype->basetype;

                        /* do pinslicing only if there is a pin slice involved */

                        if (vhdl_type != default_vhdl_datatype)
                        {
                                ref->orig_vhdltype =
                                    ref->vhdltype; /* keep old VHDL type around */
                                if (vhdl_type)
                                        ref->vhdltype = copy_vhdl (
                                            vhdl_type, socket); /* assign the new vhdl type */
                        }

                        if (level & 16)
                        {
                                Log (
                                    LOG_GENERAL,
                                    "# renaming '%s.%s' to be '%s'\n",
                                    socket_name,
                                    ref->orig_name,
                                    ref->name);
                        }
                        break;
                }
                ref = ref->next;
        }
}

void rename_unrouted_pin (char *socket_name, char *old_name, char *new_name, vhdl_t *vhdl_type)
{
        socket_t *socket;
        socket = find_socket (Ident, socket_name, Search, &socket_head);
        if (!socket)
        {
                Log (
                    LOG_ERROR,
                    "# ERROR connecting port : Cannot Locate socket identified as '%s'\n",
                    socket_name);
        }
        else
                rename_unrouted_pin_socket (socket, old_name, new_name, vhdl_type);
}