From 959ac3229e73f97a1d0fffd0d00670156ccba5b6 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 8 Feb 2014 10:16:11 -0800 Subject: [PATCH] Start a sizer backend. --- Makefile.in | 2 +- configure.in | 2 +- tgt-sizer/Makefile.in | 103 ++++++++++++++++++++++++++++++++ tgt-sizer/scan_logs.cc | 33 +++++++++++ tgt-sizer/scan_lpms.cc | 43 ++++++++++++++ tgt-sizer/sizer-s.conf | 6 ++ tgt-sizer/sizer.cc | 131 +++++++++++++++++++++++++++++++++++++++++ tgt-sizer/sizer.conf | 6 ++ tgt-sizer/sizer_priv.h | 51 ++++++++++++++++ verilog.spec | 3 + 10 files changed, 378 insertions(+), 2 deletions(-) create mode 100644 tgt-sizer/Makefile.in create mode 100644 tgt-sizer/scan_logs.cc create mode 100644 tgt-sizer/scan_lpms.cc create mode 100644 tgt-sizer/sizer-s.conf create mode 100644 tgt-sizer/sizer.cc create mode 100644 tgt-sizer/sizer.conf create mode 100644 tgt-sizer/sizer_priv.h diff --git a/Makefile.in b/Makefile.in index 04747cf0c..c31e2d735 100644 --- a/Makefile.in +++ b/Makefile.in @@ -38,7 +38,7 @@ srcdir = @srcdir@ datarootdir = @datarootdir@ SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \ - tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif driver + tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver # Only run distclean for these directories. NOTUSED = tgt-fpga tgt-pal tgt-verilog diff --git a/configure.in b/configure.in index e7aa13457..c5a31bf33 100644 --- a/configure.in +++ b/configure.in @@ -325,4 +325,4 @@ AC_MSG_ERROR(cannot configure white space in libdir: $libdir) fi AC_MSG_RESULT(ok) -AC_OUTPUT(Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile) +AC_OUTPUT(Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile) diff --git a/tgt-sizer/Makefile.in b/tgt-sizer/Makefile.in new file mode 100644 index 000000000..ad771a714 --- /dev/null +++ b/tgt-sizer/Makefile.in @@ -0,0 +1,103 @@ +# +# This source code is free software; you can redistribute it +# and/or modify it in source code form under the terms of the GNU +# Library 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 Library General Public License for more details. +# +# You should have received a copy of the GNU Library 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. +# +SHELL = /bin/sh + +suffix = @install_suffix@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +srcdir = @srcdir@ + +VPATH = $(srcdir) + +bindir = @bindir@ +libdir = @libdir@ + +CXX = @CXX@ +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +ifeq (@srcdir@,.) +INCLUDE_PATH = -I. -I.. +else +INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. +endif + +CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ +CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ +LDFLAGS = @LDFLAGS@ + +O = sizer.o scan_lpms.o scan_logs.o + +all: dep sizer.tgt + +check: all + +clean: + rm -rf *.o dep sizer.tgt + +distclean: clean + rm -f Makefile config.log + +cppcheck: $(O:.o=.cc) + cppcheck --enable=all -f $(INCLUDE_PATH) $^ + +Makefile: $(srcdir)/Makefile.in ../config.status + cd ..; ./config.status --file=tgt-sizer/$@ + +dep: + mkdir dep + +%.o: %.cc + $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o + mv $*.d dep + +ifeq (@WIN32@,yes) + TGTLDFLAGS=-L.. -livl + TGTDEPLIBS=../libivl.a +else + TGTLDFLAGS= + TGTDEPLIBS= +endif + +sizer.tgt: $O $(TGTDEPLIBS) + $(CXX) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) + +install: all installdirs $(libdir)/ivl$(suffix)/sizer.tgt $(INSTALL_DOC) $(libdir)/ivl$(suffix)/sizer.conf $(libdir)/ivl$(suffix)/sizer-s.conf + +$(libdir)/ivl$(suffix)/sizer.tgt: ./sizer.tgt + $(INSTALL_PROGRAM) ./sizer.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer.tgt" + +$(libdir)/ivl$(suffix)/sizer.conf: $(srcdir)/sizer.conf + $(INSTALL_DATA) $(srcdir)/sizer.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer.conf" + +$(libdir)/ivl$(suffix)/sizer-s.conf: $(srcdir)/sizer-s.conf + $(INSTALL_DATA) $(srcdir)/sizer-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer-s.conf" + + +installdirs: $(srcdir)/../mkinstalldirs + $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)/ivl$(suffix)" + +uninstall: + rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer.tgt" + rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer.conf" + rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer-s.conf" + + +-include $(patsubst %.o, dep/%.d, $O) diff --git a/tgt-sizer/scan_logs.cc b/tgt-sizer/scan_logs.cc new file mode 100644 index 000000000..a58dd0950 --- /dev/null +++ b/tgt-sizer/scan_logs.cc @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014 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 "sizer_priv.h" + +void scan_logs(ivl_scope_t scope, struct sizer_statistics&stats) +{ + for (unsigned idx = 0 ; idx < ivl_scope_logs(scope) ; idx += 1) { + ivl_net_logic_t log = ivl_scope_log(scope, idx); + switch (ivl_logic_type(log)) { + default: + stats.log_unknown += 1; + break; + } + } +} diff --git a/tgt-sizer/scan_lpms.cc b/tgt-sizer/scan_lpms.cc new file mode 100644 index 000000000..cfd3f45fc --- /dev/null +++ b/tgt-sizer/scan_lpms.cc @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 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 "sizer_priv.h" + +static void scan_lpms_ff(ivl_scope_t scope, ivl_lpm_t lpm, struct sizer_statistics&stats) +{ + ivl_nexus_t out = ivl_lpm_q(lpm); + unsigned wid = get_nexus_width(out); + + stats.flop_count += wid; +} + +void scan_lpms(ivl_scope_t scope, struct sizer_statistics&stats) +{ + for (unsigned idx = 0 ; idx < ivl_scope_lpms(scope) ; idx += 1) { + ivl_lpm_t lpm = ivl_scope_lpm(scope,idx); + switch (ivl_lpm_type(lpm)) { + case IVL_LPM_FF: + scan_lpms_ff(scope, lpm, stats); + break; + default: + stats.lpm_unknown += 1; + break; + } + } +} diff --git a/tgt-sizer/sizer-s.conf b/tgt-sizer/sizer-s.conf new file mode 100644 index 000000000..8a54159b7 --- /dev/null +++ b/tgt-sizer/sizer-s.conf @@ -0,0 +1,6 @@ +functor:synth2 +functor:synth +functor:syn-rules +functor:cprop +functor:nodangle +flag:DLL=sizer.tgt diff --git a/tgt-sizer/sizer.cc b/tgt-sizer/sizer.cc new file mode 100644 index 000000000..d4cd85ec8 --- /dev/null +++ b/tgt-sizer/sizer.cc @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014 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 "version_base.h" +# include "version_tag.h" +# include "config.h" +# include "sizer_priv.h" +# include +# include +# include + +/* + * This is a null target module. It does nothing. + */ + + +static const char*version_string = +"Icarus Verilog SIZER Statistics Generator " VERSION " (" VERSION_TAG ")\n\n" +"Copyright (c) 2014 Stephen Williams (steve@icarus.com)\n\n" +" This program is free software; you can redistribute it and/or modify\n" +" it under the terms of the GNU General Public License as published by\n" +" the Free Software Foundation; either version 2 of the License, or\n" +" (at your option) any later version.\n" +"\n" +" This program is distributed in the hope that it will be useful,\n" +" but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +" GNU General Public License for more details.\n" +"\n" +" You should have received a copy of the GNU General Public License along\n" +" with this program; if not, write to the Free Software Foundation, Inc.,\n" +" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" +; + +int sizer_errors = 0; + +FILE*sizer_out = 0; + +static int process_scan_fun(ivl_process_t net, void*raw); +static void emit_sizer_root(ivl_design_t des, ivl_scope_t model); + +int target_design(ivl_design_t des) +{ + const char*sizer_path = ivl_design_flag(des, "-o"); + + sizer_out = fopen(sizer_path, "wt"); + assert(sizer_out); + + // Detect processes and dispatch them. + ivl_design_process(des, &process_scan_fun, 0); + + // Locate the root scope for the design. + ivl_scope_t*roots; + unsigned nroots; + ivl_design_roots(des, &roots, &nroots); + + for (unsigned idx = 0 ; idx < nroots ; idx += 1) { + if (ivl_scope_type(roots[idx]) != IVL_SCT_MODULE) { + fprintf(stderr, "SIZER: The root scope %s must be a module.\n", ivl_scope_basename(roots[idx])); + sizer_errors += 1; + continue; + } + + emit_sizer_root(des, roots[idx]); + } + + return sizer_errors; +} + + +const char* target_query(const char*key) +{ + if (strcmp(key,"version") == 0) + return version_string; + + return 0; +} + +static int process_scan_fun(ivl_process_t net, void* /*raw*/) +{ + fprintf(stderr, "%s:%u: SIZER: Processes not synthesized for statistics.\n", + ivl_process_file(net), ivl_process_lineno(net)); + sizer_errors += 1; + return 0; +} + +static void emit_sizer_root(ivl_design_t des, ivl_scope_t model) +{ + fprintf(sizer_out, "**** Root module: %s\n", ivl_scope_name(model)); + fprintf(sizer_out, " Logic gates: %u (ivl_net_logic_t nodes))\n", ivl_scope_logs(model)); + fprintf(sizer_out, " LPM nodes : %u (ivl_lpm_t nodes)\n", ivl_scope_lpms(model)); + + struct sizer_statistics stats; + scan_logs(model, stats); + scan_lpms(model, stats); + + fprintf(sizer_out, " Flip-Flops : %u\n", stats.flop_count); + fprintf(sizer_out, " LPM Unknown : %u\n", stats.lpm_unknown); + fprintf(sizer_out, " Logic Unknown: %u\n", stats.log_unknown); +} + +unsigned get_nexus_width(ivl_nexus_t nex) +{ + ivl_signal_t sig = 0; + + for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { + ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex,idx); + sig = ivl_nexus_ptr_sig(ptr); + if (sig) return ivl_signal_width(sig); + } + + fprintf(stderr, "SIZER: Unable to find width of nexus?!\n"); + sizer_errors += 1; + return 0; +} diff --git a/tgt-sizer/sizer.conf b/tgt-sizer/sizer.conf new file mode 100644 index 000000000..8a54159b7 --- /dev/null +++ b/tgt-sizer/sizer.conf @@ -0,0 +1,6 @@ +functor:synth2 +functor:synth +functor:syn-rules +functor:cprop +functor:nodangle +flag:DLL=sizer.tgt diff --git a/tgt-sizer/sizer_priv.h b/tgt-sizer/sizer_priv.h new file mode 100644 index 000000000..39fcdcb72 --- /dev/null +++ b/tgt-sizer/sizer_priv.h @@ -0,0 +1,51 @@ +#ifndef __sizer_priv_H +#define __sizer_priv_H +/* + * Copyright (c) 2014 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 "config.h" +# include "ivl_target.h" + +# include + +struct sizer_statistics { + unsigned flop_count; + + unsigned lpm_unknown; + unsigned log_unknown; + + inline sizer_statistics() + { + flop_count = 0; + + lpm_unknown = 0; + log_unknown = 0; + } +}; + +extern int sizer_errors; +extern FILE*sizer_out; + +extern void scan_logs(ivl_scope_t scope, struct sizer_statistics&stats); +extern void scan_lpms(ivl_scope_t scope, struct sizer_statistics&stats); + + +extern unsigned get_nexus_width(ivl_nexus_t nex); + +#endif diff --git a/verilog.spec b/verilog.spec index 80fa8763f..21ef8d295 100644 --- a/verilog.spec +++ b/verilog.spec @@ -74,6 +74,9 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) %{_libdir}/ivl%{suff}/null.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/null.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/null-s.conf +%attr(-,root,root) %{_libdir}/ivl%{suff}/sizer.tgt +%attr(-,root,root) %{_libdir}/ivl%{suff}/sizer.conf +%attr(-,root,root) %{_libdir}/ivl%{suff}/sizer-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/stub.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/stub.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/stub-s.conf