Stuff registers into macrocells.
This commit is contained in:
parent
a4da2c7ed5
commit
16c50ad810
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue