Implement blif support for constants and some logic/lpm gates.
This starts the handling of various logic gates.
This commit is contained in:
parent
01b81e0dbc
commit
e0c9efd129
|
|
@ -44,7 +44,7 @@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
|||
CXXFLAGS = @WARNING_FLAGS@ @CXXFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = blif.o nex_data.o
|
||||
O = blif.o constants.o logic_gate.o lpm.o nex_data.o
|
||||
|
||||
all: dep blif.tgt
|
||||
|
||||
|
|
|
|||
104
tgt-blif/blif.cc
104
tgt-blif/blif.cc
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
# include "version_base.h"
|
||||
# include "version_tag.h"
|
||||
# include "config.h"
|
||||
# include "priv.h"
|
||||
# include "ivl_target.h"
|
||||
# include "nex_data.h"
|
||||
# include <vector>
|
||||
|
|
@ -51,11 +51,20 @@ static const char*version_string =
|
|||
" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
|
||||
;
|
||||
|
||||
static int emit_blif(const char*blif_path, ivl_scope_t model);
|
||||
int blif_errors = 0;
|
||||
|
||||
static void emit_blif(const char*blif_path, ivl_design_t des, ivl_scope_t model);
|
||||
|
||||
static int process_scan_fun(ivl_process_t net, void*raw)
|
||||
{
|
||||
fprintf(stderr, "%s:%u: sorry: BLIF: Processes not supported yet.\n",
|
||||
ivl_process_file(net), ivl_process_lineno(net));
|
||||
blif_errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_design(ivl_design_t des)
|
||||
{
|
||||
int rc = 0;
|
||||
const char*blif_path = ivl_design_flag(des, "-o");
|
||||
|
||||
// Locate the root scope for the design. Note that the BLIF
|
||||
|
|
@ -75,11 +84,14 @@ int target_design(ivl_design_t des)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Detect processes and dispatch them.
|
||||
ivl_design_process(des, &process_scan_fun, 0);
|
||||
|
||||
// Emit to the destination file.
|
||||
assert(blif_path);
|
||||
rc += emit_blif(blif_path, roots[0]);
|
||||
emit_blif(blif_path, des, roots[0]);
|
||||
|
||||
return rc;
|
||||
return blif_errors;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -122,57 +134,33 @@ static void print_signal_bits(FILE*fd, ivl_signal_t sig)
|
|||
}
|
||||
}
|
||||
|
||||
static void print_logic_gate(FILE*fd, ivl_net_logic_t net)
|
||||
|
||||
static void emit_scope(FILE*fd, ivl_scope_t scope)
|
||||
{
|
||||
#if 0
|
||||
fprintf(fd, "# LOGIC: name=%s, type=%d, pins=%u, width=%u\n",
|
||||
ivl_logic_basename(net), ivl_logic_type(net),
|
||||
ivl_logic_pins(net), ivl_logic_width(net));
|
||||
#endif
|
||||
|
||||
fprintf(fd, ".names");
|
||||
ivl_nexus_t nex;
|
||||
blif_nex_data_t*ned;
|
||||
for (unsigned idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) {
|
||||
nex = ivl_logic_pin(net,idx);
|
||||
ned = blif_nex_data_t::get_nex_data(nex);
|
||||
fprintf(fd, " %s", ned->get_name());
|
||||
for (unsigned idx = 0 ; idx < ivl_scope_logs(scope) ; idx += 1) {
|
||||
ivl_net_logic_t net = ivl_scope_log(scope, idx);
|
||||
assert(net);
|
||||
blif_errors += print_logic_gate(fd, net);
|
||||
}
|
||||
nex = ivl_logic_pin(net,0);
|
||||
ned = blif_nex_data_t::get_nex_data(nex);
|
||||
fprintf(fd, " %s", ned->get_name());
|
||||
fprintf(fd, "\n");
|
||||
|
||||
switch (ivl_logic_type(net)) {
|
||||
case IVL_LO_AND:
|
||||
for (unsigned idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1)
|
||||
fprintf(fd, "1");
|
||||
fprintf(fd, " 1\n");
|
||||
break;
|
||||
case IVL_LO_OR:
|
||||
assert(ivl_logic_pins(net)==3);
|
||||
fprintf(fd, "1- 1\n");
|
||||
fprintf(fd, "-1 1\n");
|
||||
break;
|
||||
case IVL_LO_XOR:
|
||||
assert(ivl_logic_pins(net)==3);
|
||||
fprintf(fd, "10 1\n");
|
||||
fprintf(fd, "01 1\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(fd, "# ERROR: Logic type not handled\n");
|
||||
break;
|
||||
for (unsigned idx = 0 ; idx < ivl_scope_lpms(scope) ; idx += 1) {
|
||||
ivl_lpm_t net = ivl_scope_lpm(scope, idx);
|
||||
blif_errors += print_lpm(fd, net);
|
||||
}
|
||||
|
||||
for (size_t idx = 0 ; idx < ivl_scope_childs(scope) ; idx += 1) {
|
||||
ivl_scope_t child = ivl_scope_child(scope, idx);
|
||||
emit_scope(fd, child);
|
||||
}
|
||||
}
|
||||
|
||||
static int emit_blif(const char*blif_path, ivl_scope_t model)
|
||||
static void emit_blif(const char*blif_path, ivl_design_t des, ivl_scope_t model)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
FILE*fd = fopen(blif_path, "wt");
|
||||
if (fd == 0) {
|
||||
perror(blif_path);
|
||||
return 1;
|
||||
blif_errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fd, ".model %s\n", ivl_scope_basename(model));
|
||||
|
|
@ -197,7 +185,7 @@ static int emit_blif(const char*blif_path, ivl_scope_t model)
|
|||
fprintf(stderr, "BLIF: error: "
|
||||
"Model port %s is bi-directional.\n",
|
||||
ivl_signal_basename(prt));
|
||||
rc += 1;
|
||||
blif_errors += 1;
|
||||
ports_in.push_back(prt);
|
||||
ports_out.push_back(prt);
|
||||
break;
|
||||
|
|
@ -221,14 +209,22 @@ static int emit_blif(const char*blif_path, ivl_scope_t model)
|
|||
fprintf(fd, "\n");
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < ivl_scope_logs(model) ; idx += 1) {
|
||||
ivl_net_logic_t net = ivl_scope_log(model, idx);
|
||||
assert(net);
|
||||
print_logic_gate(fd, net);
|
||||
}
|
||||
emit_scope(fd, model);
|
||||
|
||||
emit_constants(fd, des, model);
|
||||
|
||||
fprintf(fd, ".end\n");
|
||||
fclose(fd);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool scope_is_in_model(ivl_scope_t model, ivl_scope_t scope)
|
||||
{
|
||||
while (scope) {
|
||||
if (scope==model)
|
||||
return true;
|
||||
|
||||
scope = ivl_scope_parent(scope);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "priv.h"
|
||||
# include "nex_data.h"
|
||||
# include <cstdio>
|
||||
|
||||
static void print_constant(FILE*fd, ivl_net_const_t net)
|
||||
{
|
||||
unsigned wid = ivl_const_width(net);
|
||||
const char*val = ivl_const_bits(net);
|
||||
ivl_nexus_t nex = ivl_const_nex(net);
|
||||
blif_nex_data_t*ned = blif_nex_data_t::get_nex_data(nex);
|
||||
|
||||
if (wid == 1) {
|
||||
switch (val[0]) {
|
||||
case '1':
|
||||
fprintf(fd, ".names %s # const 1\n1\n", ned->get_name());
|
||||
break;
|
||||
case '0':
|
||||
fprintf(fd, ".names %s # const 0\n", ned->get_name());
|
||||
break;
|
||||
default:
|
||||
fprintf(fd, ".names %s # const %c\n", ned->get_name(), val[0]);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
switch (val[idx]) {
|
||||
case '1':
|
||||
fprintf(fd, ".names %s[%u]\n # const 1\n", ned->get_name(), idx);
|
||||
break;
|
||||
case '0':
|
||||
fprintf(fd, ".names %s[%u]\n # const 0", ned->get_name(), idx);
|
||||
break;
|
||||
default:
|
||||
fprintf(fd, ".names %s[%u]\n # const %c", ned->get_name(), idx, val[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emit_constants(FILE*fd, ivl_design_t des, ivl_scope_t model)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) {
|
||||
ivl_net_const_t net = ivl_design_const(des, idx);
|
||||
if (! scope_is_in_model(model, ivl_const_scope(net)))
|
||||
continue;
|
||||
|
||||
print_constant(fd, net);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "priv.h"
|
||||
# include "nex_data.h"
|
||||
# include <cassert>
|
||||
|
||||
int print_logic_gate(FILE*fd, ivl_net_logic_t net)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
// Do not handle logic gate widths.
|
||||
assert(ivl_logic_width(net) == 1);
|
||||
|
||||
ivl_nexus_t nex_out = ivl_logic_pin(net,0);
|
||||
blif_nex_data_t*ned_out = blif_nex_data_t::get_nex_data(nex_out);
|
||||
|
||||
assert(ned_out->get_width() == 1);
|
||||
|
||||
fprintf(fd, ".names");
|
||||
for (unsigned idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) {
|
||||
ivl_nexus_t nex = ivl_logic_pin(net,idx);
|
||||
blif_nex_data_t*ned = blif_nex_data_t::get_nex_data(nex);
|
||||
fprintf(fd, " %s", ned->get_name());
|
||||
}
|
||||
|
||||
fprintf(fd, " %s", ned_out->get_name());
|
||||
fprintf(fd, "\n");
|
||||
|
||||
switch (ivl_logic_type(net)) {
|
||||
case IVL_LO_AND:
|
||||
for (unsigned idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1)
|
||||
fprintf(fd, "1");
|
||||
fprintf(fd, " 1\n");
|
||||
break;
|
||||
case IVL_LO_OR:
|
||||
assert(ivl_logic_pins(net)==3);
|
||||
fprintf(fd, "1- 1\n");
|
||||
fprintf(fd, "-1 1\n");
|
||||
break;
|
||||
case IVL_LO_XOR:
|
||||
assert(ivl_logic_pins(net)==3);
|
||||
fprintf(fd, "10 1\n");
|
||||
fprintf(fd, "01 1\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(fd, "# ERROR: Logic type not handled\n");
|
||||
rc += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "priv.h"
|
||||
# include "nex_data.h"
|
||||
# include <cassert>
|
||||
|
||||
/*
|
||||
* Implement IVL_LPM_CONCAT devices by creating a .names buffer for
|
||||
* each bit of the output. Connect the output bit to the input bit. So
|
||||
* for example:
|
||||
* Q = {A, B, C}
|
||||
* becomes:
|
||||
* .names C Q[0]
|
||||
* 1 1
|
||||
* .names B Q[1]
|
||||
* 1 1
|
||||
* .names A Q[2]
|
||||
* 1 1
|
||||
* (In this example, A, B, and C are 1 bit.)
|
||||
*/
|
||||
static int print_concat(FILE*fd, ivl_lpm_t net)
|
||||
{
|
||||
fprintf(fd, "# %s:%u: IVL_LPM_CONCAT: width=%u\n",
|
||||
ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_width(net));
|
||||
|
||||
ivl_nexus_t nex_q = ivl_lpm_q(net);
|
||||
blif_nex_data_t*ned_q = blif_nex_data_t::get_nex_data(nex_q);
|
||||
|
||||
ivl_nexus_t nex_d = ivl_lpm_data(net,0);
|
||||
blif_nex_data_t*ned_d = blif_nex_data_t::get_nex_data(nex_d);
|
||||
unsigned didx = 0;
|
||||
unsigned dpos = 0;
|
||||
for (unsigned wid = 0 ; wid < ivl_lpm_width(net) ; wid += 1) {
|
||||
if (dpos >= ned_d->get_width()) {
|
||||
didx += 1;
|
||||
dpos = 0;
|
||||
nex_d = ivl_lpm_data(net,didx);
|
||||
ned_d = blif_nex_data_t::get_nex_data(nex_d);
|
||||
}
|
||||
|
||||
char dsub[8];
|
||||
if (ned_d->get_width() > 1)
|
||||
snprintf(dsub, sizeof dsub, "[%u]", dpos);
|
||||
else
|
||||
dsub[0] = 0;
|
||||
|
||||
fprintf(fd, ".names %s%s %s[%u]\n1 1\n",
|
||||
ned_d->get_name(), dsub,
|
||||
ned_q->get_name(), wid);
|
||||
dpos += 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This implements the IVL_LPM_PART_VP, which is the vector-to-part
|
||||
* part select. Implement this as a .names buffer.
|
||||
*/
|
||||
static int print_part_vp(FILE*fd, ivl_lpm_t net)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
ivl_nexus_t nex_out = ivl_lpm_q(net);
|
||||
blif_nex_data_t*ned_out = blif_nex_data_t::get_nex_data(nex_out);
|
||||
|
||||
// Only handle bit selects.
|
||||
assert(ned_out->get_width() == 1);
|
||||
// Only handle constant part select base.
|
||||
assert(ivl_lpm_data(net,1) == 0);
|
||||
|
||||
unsigned bit_sel = ivl_lpm_base(net);
|
||||
|
||||
ivl_nexus_t nex_in = ivl_lpm_data(net,0);
|
||||
blif_nex_data_t*ned_in = blif_nex_data_t::get_nex_data(nex_in);
|
||||
|
||||
assert(bit_sel < ned_in->get_width());
|
||||
|
||||
fprintf(fd, ".names %s[%u] %s\n1 1\n", ned_in->get_name(), bit_sel, ned_out->get_name());
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int print_lpm(FILE*fd, ivl_lpm_t net)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
switch (ivl_lpm_type(net)) {
|
||||
case IVL_LPM_CONCAT:
|
||||
case IVL_LPM_CONCATZ:
|
||||
rc += print_concat(fd, net);
|
||||
break;
|
||||
case IVL_LPM_PART_VP:
|
||||
rc += print_part_vp(fd, net);
|
||||
break;
|
||||
default:
|
||||
fprintf(fd, "# XXXX ivl_lpm_type(net) --> %d\n", ivl_lpm_type(net));
|
||||
fprintf(stderr, "%s:%u: sorry: ivl_lpm_type(net)==%d not implemented.\n",
|
||||
ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_type(net));
|
||||
rc += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -18,13 +18,16 @@
|
|||
*/
|
||||
|
||||
# include "nex_data.h"
|
||||
# include <iostream>
|
||||
# include <cstdlib>
|
||||
# include <cstdio>
|
||||
# include <cstring>
|
||||
# include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
inline blif_nex_data_t::blif_nex_data_t(ivl_nexus_t nex)
|
||||
: nex_(nex), name_(0)
|
||||
: nex_(nex), name_(0), width_(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +62,14 @@ const char* blif_nex_data_t::get_name(void)
|
|||
if (sig == 0)
|
||||
continue;
|
||||
|
||||
name_ = strdup(ivl_signal_basename(sig));
|
||||
string tmp = ivl_signal_basename(sig);
|
||||
for (ivl_scope_t sscope = ivl_signal_scope(sig) ; ivl_scope_parent(sscope) ; sscope = ivl_scope_parent(sscope)) {
|
||||
tmp = ivl_scope_basename(sscope) + string("/") + tmp;
|
||||
}
|
||||
|
||||
name_ = strdup(tmp.c_str());
|
||||
width_ = ivl_signal_width(sig);
|
||||
assert(width_ > 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -72,3 +82,25 @@ const char* blif_nex_data_t::get_name(void)
|
|||
assert(name_);
|
||||
return name_;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the width from any signal that is attached to the nexus.
|
||||
*/
|
||||
size_t blif_nex_data_t::get_width(void)
|
||||
{
|
||||
if (width_ > 0)
|
||||
return width_;
|
||||
|
||||
for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex_) ; idx += 1) {
|
||||
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex_, idx);
|
||||
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
|
||||
if (sig == 0)
|
||||
continue;
|
||||
|
||||
width_ = ivl_signal_width(sig);
|
||||
break;
|
||||
}
|
||||
|
||||
assert(width_ > 0);
|
||||
return width_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
# include "ivl_target.h"
|
||||
# include <cstddef>
|
||||
|
||||
/*
|
||||
* The ivl_target.h API allows for binding data to a nexus. This class
|
||||
|
|
@ -41,14 +42,22 @@ class blif_nex_data_t {
|
|||
// the same nexus.
|
||||
static blif_nex_data_t* get_nex_data(ivl_nexus_t nex);
|
||||
|
||||
// In certain situations, we know a priori what we want the
|
||||
// nexus name to be. In those cases, the context can use this
|
||||
// method to set the name. Note that this must be called
|
||||
// before the name is otherwise queried.
|
||||
void set_name(const char*);
|
||||
|
||||
// Get the symbolic name chosen for this nexus.
|
||||
const char*get_name(void);
|
||||
|
||||
// Get the vector width for this nexus.
|
||||
size_t get_width(void);
|
||||
|
||||
public:
|
||||
ivl_nexus_t nex_;
|
||||
char*name_;
|
||||
size_t width_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef __priv_H
|
||||
#define __priv_H
|
||||
/*
|
||||
* Copyright (c) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "ivl_target.h"
|
||||
# include <cstdio>
|
||||
|
||||
/*
|
||||
* Errors are counted here. When the blif processing is done, this
|
||||
* value is returned to ivl so that it can report error counts.
|
||||
*/
|
||||
extern int blif_errors;
|
||||
|
||||
extern int print_logic_gate(FILE*fd, ivl_net_logic_t net);
|
||||
|
||||
extern int print_lpm(FILE*fd, ivl_lpm_t net);
|
||||
|
||||
/*
|
||||
* Emit all the constants for a model. This works by scanning the
|
||||
* design for all constants, testing that they are part of the model,
|
||||
* and writing them out as .names records.
|
||||
*/
|
||||
extern void emit_constants(FILE*fd, ivl_design_t des, ivl_scope_t model);
|
||||
|
||||
/*
|
||||
* Return true if the passed scope is under the model scope, at any
|
||||
* depth. The scope may be an immediate child, or a child several
|
||||
* levels removed.
|
||||
*/
|
||||
extern bool scope_is_in_model(ivl_scope_t model, ivl_scope_t scope);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue