Stuff registers into macrocells.

This commit is contained in:
steve 2000-12-09 03:42:52 +00:00
parent a4da2c7ed5
commit 16c50ad810
6 changed files with 220 additions and 30 deletions

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.2 2000/12/09 01:19:58 steve Exp $"
#ident "$Id: Makefile.in,v 1.3 2000/12/09 03:42:52 steve Exp $"
#
#
SHELL = /bin/sh
@ -50,7 +50,7 @@ all: pal.tgt
$(CC) -Wall $(CPPFLAGS) -I$(srcdir)/.. -MD -c $< -o $*.o
mv $*.d dep
O = imain.o enables.o pads.o
O = imain.o dump_final.o enables.o fit_reg.o pads.o
ifeq (@CYGWIN@,yes)
TGTLDFLAGS=-Wl,--enable-auto-image-base -L.. -livl

59
tgt-pal/dump_final.c Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: dump_final.c,v 1.1 2000/12/09 03:42:52 steve Exp $"
#endif
# include "priv.h"
# include <stdio.h>
void dump_final_design(FILE*out)
{
unsigned idx;
for (idx = 0 ; idx < pins ; idx += 1) {
struct pal_bind_s*pin = bind_pin + idx;
if (bind_pin[idx].sop) {
fprintf(out, "Output pin %u:\n", idx+1);
fprintf(out, " pin nexus=%s\n",
pin->nexus? ivl_nexus_name(pin->nexus) : "");
fprintf(out, " pin enable=%s\n",
pin->enable ? ivl_logic_name(pin->enable) : "1");
fprintf(out, " pin ff=%s.q%u\n",
pin->reg ? ivl_lpm_name(pin->reg) : "*",
pin->reg_q);
} else {
fprintf(out, "Input pin %u:\n", idx+1);
fprintf(out, " pin nexus=%s\n",
pin->nexus? ivl_nexus_name(pin->nexus) : "");
}
}
}
/*
* $Log: dump_final.c,v $
* Revision 1.1 2000/12/09 03:42:52 steve
* Stuff registers into macrocells.
*
*/

View File

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: enables.c,v 1.1 2000/12/09 01:17:38 steve Exp $"
#ident "$Id: enables.c,v 1.2 2000/12/09 03:42:52 steve Exp $"
# include <ivl_target.h>
# include <assert.h>
@ -25,7 +25,8 @@
/*
* Given a pin index, look at the nexus for a bufif device that is
* driving it, if any.
* driving it, if any. Save that device in the enable slot for the
* cell. We'll try to fit it later.
*/
static void absorb_pad_enable(unsigned idx)
{
@ -76,6 +77,9 @@ void absorb_pad_enables(void)
/*
* $Log: enables.c,v $
* Revision 1.2 2000/12/09 03:42:52 steve
* Stuff registers into macrocells.
*
* Revision 1.1 2000/12/09 01:17:38 steve
* Add the pal loadable target.
*

127
tgt-pal/fit_reg.c Normal file
View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: fit_reg.c,v 1.1 2000/12/09 03:42:52 steve Exp $"
#endif
# include <ivl_target.h>
# include <stdio.h>
# include <assert.h>
# include "priv.h"
static int scan_ff_q(ivl_lpm_ff_t ff, unsigned q);
int fit_registers(ivl_scope_t scope)
{
int rc;
unsigned idx;
unsigned lpms;
rc = ivl_scope_children(scope, fit_registers);
if (rc != 0)
return rc;
lpms = ivl_scope_lpms(scope);
for (idx = 0 ; idx < lpms ; idx += 1) {
ivl_lpm_t lpm = ivl_scope_lpm(scope, idx);
ivl_lpm_ff_t ff;
unsigned wid, q;
if (ivl_lpm_type(lpm) != IVL_LPM_FF)
continue;
wid = ivl_lpm_width(lpm);
ff = ivl_lpm_ff(lpm);
for (q = 0 ; q < wid ; q += 1) {
rc = scan_ff_q(ff, q);
if (rc != 0)
return rc;
}
}
return 0;
}
int scan_ff_q(ivl_lpm_ff_t ff, unsigned q)
{
unsigned idx;
ivl_nexus_t nex;
nex = ivl_lpm_ff_q(ff, q);
/* First, look to see if the Q is already connected to a pin
or an enable. If I find such a connection, then immediately
finish. */
for (idx = 0 ; idx < pins ; idx += 1) {
struct pal_bind_s*pin = bind_pin + idx;
if (pin->sop == 0)
continue;
if (pin->enable) {
if (nex == ivl_logic_pin(pin->enable, 1)) {
pin->reg = ff;
pin->reg_q = q;
return 0;
}
} else if (pin->nexus == nex) {
pin->reg = ff;
pin->reg_q = q;
return 0;
}
}
/* There is no poin connection, so try setting this to an
unbound sop cell. We know that a sop is unbound if there
are no enables, nexus or ff devices connected to it. */
for (idx = 0 ; idx < pins ; idx += 1) {
struct pal_bind_s*pin = bind_pin + idx;
if (pin->sop == 0)
continue;
if (pin->enable || pin->nexus || pin->reg)
continue;
/* Found one. Put the reg here. Leave the nexus empty so
that the code generator knows to disable the pin. */
pin->reg = ff;
pin->reg_q = q;
return 0;
}
fprintf(stderr, "No room for this ff.\n");
error_count += 1;
return 0;
}
/*
* $Log: fit_reg.c,v $
* Revision 1.1 2000/12/09 03:42:52 steve
* Stuff registers into macrocells.
*
*/

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: imain.c,v 1.1 2000/12/09 01:17:38 steve Exp $"
#ident "$Id: imain.c,v 1.2 2000/12/09 03:42:52 steve Exp $"
#endif
/*
@ -31,6 +31,8 @@
# include <stdlib.h>
# include <assert.h>
extern void dump_final_design(FILE*out);
/*
* As processing proceeds, this variable is incremented as errors are
* encountered. This allows the code generator to give up if it
@ -50,29 +52,6 @@ pal_t pal = 0;
unsigned pins = 0;
struct pal_bind_s* bind_pin = 0;
static void dump_final_design(FILE*out)
{
unsigned idx;
for (idx = 0 ; idx < pins ; idx += 1) {
if (bind_pin[idx].sop) {
fprintf(out, "Output pin %u:\n", idx+1);
fprintf(out, " pin nexus=%s\n",
bind_pin[idx].nexus?
ivl_nexus_name(bind_pin[idx].nexus) : "");
fprintf(out, " pin enable=%s\n",
bind_pin[idx].enable ?
ivl_logic_name(bind_pin[idx].enable) : "1");
} else {
fprintf(out, "Input pin %u:\n", idx+1);
fprintf(out, " pin nexus=%s\n",
bind_pin[idx].nexus?
ivl_nexus_name(bind_pin[idx].nexus) : "");
}
}
}
/*
* This is the main entry point that Icarus Verilog calls to generate
@ -120,7 +99,7 @@ int target_design(ivl_design_t des)
get_pad_bindings(root);
if (pal_errors) {
fprintf(stderr, "code generator failed.\n");
fprintf(stderr, "PAD assignment failed.\n");
pal_free(pal);
return -1;
}
@ -129,6 +108,16 @@ int target_design(ivl_design_t des)
enables that are connected to them. */
absorb_pad_enables();
/* Scan all the registers, and assign them to
macro-cells. */
root = ivl_design_root(des);
fit_registers(root);
if (pal_errors) {
fprintf(stderr, "Register fitting failed.\n");
pal_free(pal);
return -1;
}
dump_final_design(stdout);
@ -143,6 +132,9 @@ DECLARE_CYGWIN_DLL(DllMain);
/*
* $Log: imain.c,v $
* Revision 1.2 2000/12/09 03:42:52 steve
* Stuff registers into macrocells.
*
* Revision 1.1 2000/12/09 01:17:38 steve
* Add the pal loadable target.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: priv.h,v 1.1 2000/12/09 01:17:38 steve Exp $"
#ident "$Id: priv.h,v 1.2 2000/12/09 03:42:52 steve Exp $"
#endif
# include <ivl_target.h>
@ -41,6 +41,9 @@ struct pal_bind_s {
pal_sop_t sop;
/* If the output has an enable, this is it. */
ivl_net_logic_t enable;
/* If there is a register here, this is it. */
ivl_lpm_ff_t reg;
unsigned reg_q;
};
extern unsigned pins;
@ -50,8 +53,13 @@ extern int get_pad_bindings(ivl_scope_t net);
extern void absorb_pad_enables(void);
extern int fit_registers(ivl_scope_t scope);
/*
* $Log: priv.h,v $
* Revision 1.2 2000/12/09 03:42:52 steve
* Stuff registers into macrocells.
*
* Revision 1.1 2000/12/09 01:17:38 steve
* Add the pal loadable target.
*