From 49c4f2d106ee974e082808d5991fc775da9083d0 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 30 Aug 2008 15:28:31 -0700 Subject: [PATCH 01/12] Fix crash on uninitialized data. --- netlist.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/netlist.cc b/netlist.cc index 2f0f6f23d..4da3f5755 100644 --- a/netlist.cc +++ b/netlist.cc @@ -426,7 +426,8 @@ const Link& NetDelaySrc::condit_pin() const NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins) : NetObj(s, n, 1), sig_next_(0), sig_prev_(0), type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), - signed_(false), isint_(false), msb_(npins-1), lsb_(0), dimensions_(0), + signed_(false), isint_(false), discipline_(0), msb_(npins-1), lsb_(0), + dimensions_(0), s0_(0), e0_(0), local_flag_(false), eref_count_(0), lref_count_(0) { assert(s); @@ -466,7 +467,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, : NetObj(s, n, 1), sig_next_(0), sig_prev_(0), type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false), - isint_(false), msb_(ms), lsb_(ls), dimensions_(0), s0_(0), e0_(0), + isint_(false), discipline_(0), msb_(ms), lsb_(ls), dimensions_(0), s0_(0), e0_(0), local_flag_(false), eref_count_(0), lref_count_(0) { assert(s); @@ -514,7 +515,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, : NetObj(s, n, calculate_count(array_s, array_e)), sig_next_(0), sig_prev_(0), type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false), - msb_(ms), lsb_(ls), dimensions_(1), s0_(array_s), e0_(array_e), + discipline_(0), msb_(ms), lsb_(ls), dimensions_(1), s0_(array_s), e0_(array_e), local_flag_(false), eref_count_(0), lref_count_(0) { assert(s); From fc476aa281b266396a93b4e04092b75e96c7fe0f Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 30 Aug 2008 15:30:22 -0700 Subject: [PATCH 02/12] Fix right shift of vvp_vector2_t. The right shift of vvp_vector2_t needs to account for and mask off shifted bits. Otherwise there will be unexpected results after a vvp_vector2_t::trim method. --- vvp/vvp_net.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index f921e014c..a3bd2ee19 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1557,8 +1557,19 @@ vvp_vector2_t& vvp_vector2_t::operator >>= (unsigned shift) } // Cleanup the tail bits. - unsigned long mask = -1UL >> (BITS_PER_WORD - wid_%BITS_PER_WORD); - vec_[words-1] &= mask; + unsigned use_words = words; + unsigned long mask_shift = BITS_PER_WORD - wid_%BITS_PER_WORD; + mask_shift += oshift; + while (mask_shift >= BITS_PER_WORD) { + vec_[use_words-1] = 0; + use_words -= 1; + mask_shift -= BITS_PER_WORD; + } + if (mask_shift > 0) { + assert(use_words > 0); + unsigned long mask = -1UL >> mask_shift; + vec_[use_words-1] &= mask; + } } return *this; From 319b886118a6f9ad8494da20139d6361da208e53 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 30 Aug 2008 17:09:51 -0700 Subject: [PATCH 03/12] Build files compatible with snapshot 20080830 --- Makefile.in | 4 ++-- cadpli/Makefile.in | 6 +++--- driver/Makefile.in | 10 +++++----- ivlpp/Makefile.in | 6 +++--- libveriuser/Makefile.in | 6 +++--- tgt-null/Makefile.in | 14 +++++++------- tgt-stub/Makefile.in | 14 +++++++------- tgt-vhdl/Makefile.in | 8 ++++---- tgt-vvp/Makefile.in | 10 +++++----- verilog.spec | 22 ++++++++++++++-------- vpi/Makefile.in | 29 ++++++++++++++--------------- vvp/Makefile.in | 16 ++++++++-------- 12 files changed, 75 insertions(+), 70 deletions(-) diff --git a/Makefile.in b/Makefile.in index a45841892..3b16d2dd9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -244,10 +244,10 @@ $(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@ $(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(DESTDIR)$(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/include/constants.vams: $(srcdir)/constants.vams - $(INSTALL_DATA) $(srcdir)/constants.vams $@ + $(INSTALL_DATA) $(srcdir)/constants.vams $(DESTDIR)$(libdir)/ivl/include/constants.vams $(libdir)/ivl/include/disciplines.vams: $(srcdir)/disciplines.vams - $(INSTALL_DATA) $(srcdir)/disciplines.vams $@ + $(INSTALL_DATA) $(srcdir)/disciplines.vams $(DESTDIR)$(libdir)/ivl/include/disciplines.vams $(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf $(INSTALL_DATA) $(srcdir)/xnf-s.conf $(DESTDIR)$(libdir)/ivl/xnf-s.conf diff --git a/cadpli/Makefile.in b/cadpli/Makefile.in index 9d8885847..2d4f81c0f 100644 --- a/cadpli/Makefile.in +++ b/cadpli/Makefile.in @@ -76,13 +76,13 @@ distclean: clean install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32) $(vpidir)/cadpli.vpl: ./cadpli.vpl - $(INSTALL_PROGRAM) ./cadpli.vpl $(vpidir)/cadpli.vpl + $(INSTALL_PROGRAM) ./cadpli.vpl $(DESTDIR)$(vpidir)/cadpli.vpl installdirs: ../mkinstalldirs - $(srcdir)/../mkinstalldirs $(vpidir) + $(srcdir)/../mkinstalldirs $(DESTDIR)$(vpidir) uninstall: $(UNINSTALL32) - rm -f $(vpidir)/cadpli.vpl + rm -f $(DESTDIR)$(vpidir)/cadpli.vpl uninstall32: diff --git a/driver/Makefile.in b/driver/Makefile.in index 254b65dfd..e3b91d3e4 100644 --- a/driver/Makefile.in +++ b/driver/Makefile.in @@ -100,17 +100,17 @@ endif install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC) $(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@ - $(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog@EXEEXT@ + $(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(DESTDIR)$(bindir)/iverilog@EXEEXT@ $(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man - $(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog.1 + $(INSTALL_DATA) $(srcdir)/iverilog.man $(DESTDIR)$(mandir)/man1/iverilog.1 $(prefix)/iverilog.pdf: iverilog.pdf $(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf installdirs: ../mkinstalldirs - $(srcdir)/../mkinstalldirs $(bindir) $(INSTALL_DOCDIR) + $(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(INSTALL_DOCDIR) uninstall: - rm -f $(bindir)/iverilog@EXEEXT@ - rm -f $(mandir)/man1/iverilog.1 $(prefix)/iverilog.pdf + rm -f $(DESTDIR)$(bindir)/iverilog@EXEEXT@ + rm -f $(DESTDIR)$(mandir)/man1/iverilog.1 $(DESTDIR)$(prefix)/iverilog.pdf diff --git a/ivlpp/Makefile.in b/ivlpp/Makefile.in index b55b5c7ac..b66ed207a 100644 --- a/ivlpp/Makefile.in +++ b/ivlpp/Makefile.in @@ -63,13 +63,13 @@ lexor.c: lexor.lex install: all installdirs $(libdir)/ivl/ivlpp@EXEEXT@ $(libdir)/ivl/ivlpp@EXEEXT@: ivlpp@EXEEXT@ - $(INSTALL_PROGRAM) ./ivlpp@EXEEXT@ $(libdir)/ivl/ivlpp@EXEEXT@ + $(INSTALL_PROGRAM) ./ivlpp@EXEEXT@ $(DESTDIR)$(libdir)/ivl/ivlpp@EXEEXT@ installdirs: ../mkinstalldirs - $(srcdir)/../mkinstalldirs $(libdir)/ivl + $(srcdir)/../mkinstalldirs $(DESTDIR)$(libdir)/ivl uninstall: - rm -f $(libdir)/ivl/ivlpp@EXEEXT@ + rm -f $(DESTDIR)$(libdir)/ivl/ivlpp@EXEEXT@ lexor.o: lexor.c globals.h main.o: main.c globals.h diff --git a/libveriuser/Makefile.in b/libveriuser/Makefile.in index c8a56679c..7fc807e84 100644 --- a/libveriuser/Makefile.in +++ b/libveriuser/Makefile.in @@ -89,12 +89,12 @@ distclean: clean install:: all installdirs $(libdir)/libveriuser.a $(INSTALL32) $(libdir)/libveriuser.a: ./libveriuser.a - $(INSTALL_DATA) ./libveriuser.a $(libdir)/libveriuser.a + $(INSTALL_DATA) ./libveriuser.a $(DESTDIR)$(libdir)/libveriuser.a installdirs: mkinstalldirs - $(srcdir)/mkinstalldirs $(includedir) $(libdir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(includedir) $(DESTDIR)$(libdir) uninstall:: - rm -f $(libdir)/libveriuser.a + rm -f $(DESTDIR)$(libdir)/libveriuser.a -include $(patsubst %.o, dep/%.d, $O) diff --git a/tgt-null/Makefile.in b/tgt-null/Makefile.in index 204e6a00c..426d35230 100644 --- a/tgt-null/Makefile.in +++ b/tgt-null/Makefile.in @@ -75,22 +75,22 @@ check: all install: all installdirs $(libdir)/ivl/null.tgt $(INSTALL_DOC) $(libdir)/ivl/null.conf $(libdir)/ivl/null-s.conf $(libdir)/ivl/null.tgt: ./null.tgt - $(INSTALL_PROGRAM) ./null.tgt $(libdir)/ivl/null.tgt + $(INSTALL_PROGRAM) ./null.tgt $(DESTDIR)$(libdir)/ivl/null.tgt $(libdir)/ivl/null.conf: $(srcdir)/null.conf - $(INSTALL_DATA) $(srcdir)/null.conf $(libdir)/ivl/null.conf + $(INSTALL_DATA) $(srcdir)/null.conf $(DESTDIR)$(libdir)/ivl/null.conf $(libdir)/ivl/null-s.conf: $(srcdir)/null-s.conf - $(INSTALL_DATA) $(srcdir)/null-s.conf $(libdir)/ivl/null-s.conf + $(INSTALL_DATA) $(srcdir)/null-s.conf $(DESTDIR)$(libdir)/ivl/null-s.conf installdirs: ../mkinstalldirs - $(srcdir)/../mkinstalldirs $(includedir) $(bindir) $(libdir)/ivl + $(srcdir)/../mkinstalldirs $(DESTDIR)$(includedir) $(DESTDIR)$(bindir) $(DESTDIR)$(libdir)/ivl uninstall: - rm -f $(libdir)/ivl/null.tgt - rm -f $(libdir)/ivl/null.conf - rm -f $(libdir)/ivl/null-s.conf + rm -f $(DESTDIR)$(libdir)/ivl/null.tgt + rm -f $(DESTDIR)$(libdir)/ivl/null.conf + rm -f $(DESTDIR)$(libdir)/ivl/null-s.conf -include $(patsubst %.o, dep/%.d, $O) diff --git a/tgt-stub/Makefile.in b/tgt-stub/Makefile.in index 679226758..20d0136f9 100644 --- a/tgt-stub/Makefile.in +++ b/tgt-stub/Makefile.in @@ -76,21 +76,21 @@ install: all installdirs $(libdir)/ivl/stub.tgt \ $(libdir)/ivl/stub.conf $(libdir)/ivl/stub-s.conf $(libdir)/ivl/stub.tgt: ./stub.tgt - $(INSTALL_PROGRAM) ./stub.tgt $(libdir)/ivl/stub.tgt + $(INSTALL_PROGRAM) ./stub.tgt $(DESTDIR)$(libdir)/ivl/stub.tgt $(libdir)/ivl/stub.conf: stub.conf - $(INSTALL_DATA) $< $(libdir)/ivl/stub.conf + $(INSTALL_DATA) $< $(DESTDIR)$(libdir)/ivl/stub.conf $(libdir)/ivl/stub-s.conf: stub-s.conf - $(INSTALL_DATA) $< $(libdir)/ivl/stub-s.conf + $(INSTALL_DATA) $< $(DESTDIR)$(libdir)/ivl/stub-s.conf installdirs: ../mkinstalldirs - $(srcdir)/../mkinstalldirs $(includedir) $(bindir) $(libdir)/ivl + $(srcdir)/../mkinstalldirs $(DESTDIR)$(includedir) $(DESTDIR)$(bindir) $(DESTDIR)$(libdir)/ivl uninstall: - rm -f $(libdir)/ivl/stub.tgt - rm -f $(libdir)/ivl/stub.conf - rm -f $(libdir)/ivl/stub-s.conf + rm -f $(DESTDIR)$(libdir)/ivl/stub.tgt + rm -f $(DESTDIR)$(libdir)/ivl/stub.conf + rm -f $(DESTDIR)$(libdir)/ivl/stub-s.conf -include $(patsubst %.o, dep/%.d, $O) diff --git a/tgt-vhdl/Makefile.in b/tgt-vhdl/Makefile.in index bbd0cfeaf..7b76b1936 100644 --- a/tgt-vhdl/Makefile.in +++ b/tgt-vhdl/Makefile.in @@ -77,16 +77,16 @@ check: all install: all installdirs $(libdir)/ivl/vhdl.tgt $(libdir)/ivl/vhdl.conf $(libdir)/ivl/vhdl.tgt: ./vhdl.tgt - $(INSTALL_PROGRAM) ./vhdl.tgt $(libdir)/ivl/vhdl.tgt + $(INSTALL_PROGRAM) ./vhdl.tgt $(DESTDIR)$(libdir)/ivl/vhdl.tgt $(libdir)/ivl/vhdl.conf: vhdl.conf - $(INSTALL_DATA) $< $(libdir)/ivl/vhdl.conf + $(INSTALL_DATA) $< $(DESTDIR)$(libdir)/ivl/vhdl.conf installdirs: ../mkinstalldirs - $(srcdir)/../mkinstalldirs $(libdir)/ivl + $(srcdir)/../mkinstalldirs $(DESTDIR)$(libdir)/ivl uninstall: - rm -f $(libdir)/ivl/vhdl.tgt $(libdir)/ivl/vhdl.conf + rm -f $(DESTDIR)$(libdir)/ivl/vhdl.tgt $(DESTDIR)$(libdir)/ivl/vhdl.conf -include $(patsubst %.o, dep/%.d, $O) diff --git a/tgt-vvp/Makefile.in b/tgt-vvp/Makefile.in index 323212332..f3e8b9b0d 100644 --- a/tgt-vvp/Makefile.in +++ b/tgt-vvp/Makefile.in @@ -88,20 +88,20 @@ check: all install: all installdirs $(libdir)/ivl/vvp.tgt $(libdir)/ivl/vvp.conf $(libdir)/ivl/vvp-s.conf $(libdir)/ivl/vvp.tgt: ./vvp.tgt - $(INSTALL_PROGRAM) ./vvp.tgt $(libdir)/ivl/vvp.tgt + $(INSTALL_PROGRAM) ./vvp.tgt $(DESTDIR)$(libdir)/ivl/vvp.tgt $(libdir)/ivl/vvp.conf: vvp.conf - $(INSTALL_DATA) $< $(libdir)/ivl/vvp.conf + $(INSTALL_DATA) $< $(DESTDIR)$(libdir)/ivl/vvp.conf $(libdir)/ivl/vvp-s.conf: vvp-s.conf - $(INSTALL_DATA) $< $(libdir)/ivl/vvp-s.conf + $(INSTALL_DATA) $< $(DESTDIR)$(libdir)/ivl/vvp-s.conf installdirs: ../mkinstalldirs - $(srcdir)/../mkinstalldirs $(libdir)/ivl + $(srcdir)/../mkinstalldirs $(DESTDIR)$(libdir)/ivl uninstall: - rm -f $(libdir)/ivl/vvp.tgt $(libdir)/ivl/vvp.conf $(libdir)/ivl/vvp-s.conf + rm -f $(DESTDIR)$(libdir)/ivl/vvp.tgt $(DESTDIR)$(libdir)/ivl/vvp.conf $(DESTDIR)$(libdir)/ivl/vvp-s.conf -include $(patsubst %.o, dep/%.d, $O) diff --git a/verilog.spec b/verilog.spec index ed747afae..a96b1100d 100644 --- a/verilog.spec +++ b/verilog.spec @@ -1,6 +1,6 @@ #norootforbuild # -%define rev_date 20080429 +%define rev_date 20080830 # # Summary: Icarus Verilog @@ -41,11 +41,10 @@ rm -rf $RPM_BUILD_ROOT %files -%attr(-,root,root) %doc COPYING README.txt BUGS.txt QUICK_START.txt ieee1364-notes.txt mingw.txt swift.txt netlist.txt t-dll.txt vpi.txt xnf.txt tgt-fpga/fpga.txt cadpli/cadpli.txt xilinx-hint.txt +%attr(-,root,root) %doc COPYING README.txt BUGS.txt QUICK_START.txt ieee1364-notes.txt mingw.txt swift.txt netlist.txt t-dll.txt vpi.txt tgt-fpga/fpga.txt cadpli/cadpli.txt %attr(-,root,root) %doc examples/* %attr(-,root,root) %{_mandir}/man1/iverilog.1.gz -#%attr(-,root,root) /usr/man/man1/iverilog-fpga.1.gz %attr(-,root,root) %{_mandir}/man1/iverilog-vpi.1.gz %attr(-,root,root) %{_mandir}/man1/vvp.1.gz @@ -63,16 +62,19 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) %{_libdir}/ivl/vvp.tgt %attr(-,root,root) %{_libdir}/ivl/vvp.conf %attr(-,root,root) %{_libdir}/ivl/vvp-s.conf -#%attr(-,root,root) %{_libdir}/ivl/fpga.tgt -#%attr(-,root,root) %{_libdir}/ivl/fpga.conf -#%attr(-,root,root) %{_libdir}/ivl/fpga-s.conf -#%attr(-,root,root) %{_libdir}/ivl/xnf.conf -#%attr(-,root,root) %{_libdir}/ivl/xnf-s.conf +%attr(-,root,root) %{_libdir}/ivl/vhdl.tgt +%attr(-,root,root) %{_libdir}/ivl/vhdl.conf %attr(-,root,root) %{_libdir}/ivl/system.sft %attr(-,root,root) %{_libdir}/ivl/system.vpi +%attr(-,root,root) %{_libdir}/ivl/va_math.sft +%attr(-,root,root) %{_libdir}/ivl/va_math.vpi +%attr(-,root,root) %{_libdir}/ivl/v2005_math.sft +%attr(-,root,root) %{_libdir}/ivl/v2005_math.vpi %attr(-,root,root) %{_libdir}/ivl/cadpli.vpl %attr(-,root,root) %{_libdir}/libvpi.a %attr(-,root,root) %{_libdir}/libveriuser.a +%attr(-,root,root) %{_libdir}/ivl/include/constants.vams +%attr(-,root,root) %{_libdir}/ivl/include/disciplines.vams %attr(-,root,root) /usr/include/ivl_target.h %attr(-,root,root) /usr/include/vpi_user.h %attr(-,root,root) /usr/include/acc_user.h @@ -80,6 +82,10 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) /usr/include/_pli_types.h %changelog -n verilog +* Sat Aug 30 2008 - steve@icarus.com +- Add vhdl target files +- Add V/AMS header files. + * Fri Jan 25 2008 - steve@icarus.com - Removed vvp32 support for x86_64 build. diff --git a/vpi/Makefile.in b/vpi/Makefile.in index 0b5c703ed..29701d77b 100644 --- a/vpi/Makefile.in +++ b/vpi/Makefile.in @@ -116,36 +116,35 @@ check: all install: all installdirs \ $(vpidir)/system.vpi $(libdir)/ivl/system.sft \ $(vpidir)/va_math.vpi $(libdir)/ivl/va_math.sft \ - $(vpidir)/v2005_math.vpi $(libdir)/ivl/v2005_math.sft \ - $(vpidir)/include/ + $(vpidir)/v2005_math.vpi $(libdir)/ivl/v2005_math.sft $(vpidir)/system.vpi: ./system.vpi - $(INSTALL_PROGRAM) ./system.vpi $(vpidir)/system.vpi + $(INSTALL_PROGRAM) ./system.vpi $(DESTDIR)$(vpidir)/system.vpi $(libdir)/ivl/system.sft: system.sft - $(INSTALL_DATA) $< $@ + $(INSTALL_DATA) $< $(DESTDIR)$@ $(vpidir)/va_math.vpi: ./va_math.vpi - $(INSTALL_PROGRAM) ./va_math.vpi $(vpidir)/va_math.vpi + $(INSTALL_PROGRAM) ./va_math.vpi $(DESTDIR)$(vpidir)/va_math.vpi $(libdir)/ivl/va_math.sft: va_math.sft - $(INSTALL_DATA) $< $@ + $(INSTALL_DATA) $< $(DESTDIR)$@ $(vpidir)/v2005_math.vpi: ./v2005_math.vpi - $(INSTALL_PROGRAM) ./v2005_math.vpi $(vpidir)/v2005_math.vpi + $(INSTALL_PROGRAM) ./v2005_math.vpi $(DESTDIR)$(vpidir)/v2005_math.vpi $(libdir)/ivl/v2005_math.sft: v2005_math.sft - $(INSTALL_DATA) $< $@ + $(INSTALL_DATA) $< $(DESTDIR)$@ installdirs: ../mkinstalldirs - $(srcdir)/../mkinstalldirs $(vpidir) + $(srcdir)/../mkinstalldirs $(DESTDIR)$(libdir) $(DESTDIR)$(vpidir) uninstall: - rm -f $(vpidir)/system.vpi - rm -f $(libdir)/ivl/system.sft - rm -f $(vpidir)/va_math.vpi - rm -f $(libdir)/ivl/va_math.sft - rm -f $(vpidir)/v2005_math.vpi - rm -f $(libdir)/ivl/v2005_math.sft + rm -f $(DESTDIR)$(vpidir)/system.vpi + rm -f $(DESTDIR)$(libdir)/ivl/system.sft + rm -f $(DESTDIR)$(vpidir)/va_math.vpi + rm -f $(DESTDIR)$(libdir)/ivl/va_math.sft + rm -f $(DESTDIR)$(vpidir)/v2005_math.vpi + rm -f $(DESTDIR)$(libdir)/ivl/v2005_math.sft -include $(patsubst %.o, dep/%.d, $O) diff --git a/vvp/Makefile.in b/vvp/Makefile.in index ab1e8b227..a65994e6b 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -161,24 +161,24 @@ Makefile: Makefile.in config.status install: all installdirs $(bindir)/vvp@EXEEXT@ $(libdir)/libvpi.a $(INSTALL_DOC) $(bindir)/vvp@EXEEXT@: ./vvp@EXEEXT@ - $(INSTALL_PROGRAM) ./vvp@EXEEXT@ $(bindir)/vvp@EXEEXT@ + $(INSTALL_PROGRAM) ./vvp@EXEEXT@ $(DESTDIR)$(bindir)/vvp@EXEEXT@ $(libdir)/libvpi.a : ./libvpi.a - $(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a + $(INSTALL_DATA) libvpi.a $(DESTDIR)$(libdir)/libvpi.a $(mandir)/man1/vvp.1: $(srcdir)/vvp.man - $(INSTALL_DATA) $(srcdir)/vvp.man $(mandir)/man1/vvp.1 + $(INSTALL_DATA) $(srcdir)/vvp.man $(DESTDIR)$(mandir)/man1/vvp.1 $(prefix)/vvp.pdf: vvp.pdf - $(INSTALL_DATA) vvp.pdf $(prefix)/vvp.pdf + $(INSTALL_DATA) vvp.pdf $(DESTDIR)$(prefix)/vvp.pdf installdirs: $(srcdir)/mkinstalldirs - $(srcdir)/mkinstalldirs $(bindir) $(libdir) $(libdir) $(INSTALL_DOCDIR) + $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(libdir) $(DESTDIR)$(INSTALL_DOCDIR) uninstall: $(UNINSTALL32) - rm -f $(bindir)/vvp@EXEEXT@ - rm -f $(libdir)/libvpi.a - rm -f $(mandir)/man1/vvp.1 $(prefix)/vvp.pdf + rm -f $(DESTDIR)$(bindir)/vvp@EXEEXT@ + rm -f $(DESTDIR)$(libdir)/libvpi.a + rm -f $(DESTDIR)$(mandir)/man1/vvp.1 $(DESTDIR)$(prefix)/vvp.pdf -include $(patsubst %.o, dep/%.d, $O) From c0a4b7c6700447750dc77c614053e8b6f5adbbb5 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 30 Aug 2008 17:35:57 -0700 Subject: [PATCH 04/12] Fix a bug in vector evaluation of abs(). The calculation of the abs of a signed value was inverting the value if it was signed, and not if it was negative. --- eval_tree.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eval_tree.cc b/eval_tree.cc index 50fdaf02b..3b82d99f6 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -1775,7 +1775,7 @@ NetExpr* evaluate_abs(NetExpr*arg) NetEConst*tmpi = dynamic_cast(arg); if (tmpi) { verinum arg = tmpi->value(); - if (arg.has_sign()) { + if (arg.is_negative()) { arg = v_not(arg) + verinum(1); } return new NetEConst(arg); From c150223a3a3219c0927a71ced22398ef1c6b0879 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 1 Sep 2008 13:55:42 -0700 Subject: [PATCH 05/12] Fix problem with vvp_vector2_t right shift that trips only when starting with perfectly aligned inputs. --- vvp/vvp_net.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index a3bd2ee19..179305dd3 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1557,8 +1557,15 @@ vvp_vector2_t& vvp_vector2_t::operator >>= (unsigned shift) } // Cleanup the tail bits. + unsigned use_words = words; + // Mask_shift is the number of high bits of the top word + // that are to be masked off. We start with the number + // of bits that are not included even in the original, + // then we include the bits of the shift, that are to be + // masked to zero. unsigned long mask_shift = BITS_PER_WORD - wid_%BITS_PER_WORD; + mask_shift %= BITS_PER_WORD; mask_shift += oshift; while (mask_shift >= BITS_PER_WORD) { vec_[use_words-1] = 0; From 23127852c79b8c4a9d5c1e01f5e8b114df49b79a Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Sun, 31 Aug 2008 14:36:52 -0700 Subject: [PATCH 06/12] Compatibility with gcc-4.3 Add "include" to fix error with abort() in dup_expr.cc Add "include" to AStatement.h so usage of struct PExpr works Get rid of eval_tree.cc:577: warning: suggest parentheses around comparison in operand of ^ --- AStatement.h | 1 + dup_expr.cc | 1 + eval_tree.cc | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/AStatement.h b/AStatement.h index a1b2085ef..0b1b60396 100644 --- a/AStatement.h +++ b/AStatement.h @@ -22,6 +22,7 @@ # include # include "StringHeap.h" # include "LineInfo.h" +# include "PExpr.h" class PExpr; diff --git a/dup_expr.cc b/dup_expr.cc index ad4bb7b0a..c6bf13416 100644 --- a/dup_expr.cc +++ b/dup_expr.cc @@ -21,6 +21,7 @@ # include "netlist.h" # include +# include # include "ivl_assert.h" NetEAccess* NetEAccess::dup_expr() const diff --git a/eval_tree.cc b/eval_tree.cc index 3b82d99f6..9ed5ba649 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -574,7 +574,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag) assert(0); } - verinum result((lv == rv ^ ne_flag) ? verinum::V1 : verinum::V0, 1); + verinum result(((lv == rv) ^ ne_flag) ? verinum::V1 : verinum::V0, 1); vtmp = new NetEConst(result); vtmp->set_line(*this); From 8fbfdffe913c1c5bdb683a5e102dfa154c696b90 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 1 Sep 2008 11:49:52 -0700 Subject: [PATCH 07/12] Allow .array/port input access generate statement. For nested array accesses the .array/port statement must evaluate its input argument before it starts printing the actual .array/port statement. --- tgt-vvp/vvp_scope.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index e018166bb..89cc691a9 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -1193,13 +1193,10 @@ static void draw_lpm_array(ivl_lpm_t net) { ivl_nexus_t nex; ivl_signal_t mem = ivl_lpm_array(net); - - fprintf(vvp_out, "L_%p .array/port v%p, ", net, mem); - nex = ivl_lpm_select(net); - fprintf(vvp_out, "%s", draw_net_input(nex)); + const char*tmp = draw_net_input(nex); - fprintf(vvp_out, ";\n"); + fprintf(vvp_out, "L_%p .array/port v%p, %s;\n", net, mem, tmp); } static void draw_lpm_cmp(ivl_lpm_t net) From 1944f372c59d009b1f49f6c783ec193722d1e1dc Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 1 Sep 2008 14:30:09 -0700 Subject: [PATCH 08/12] Fix a couple uninitialized value problems found with tgt-vhdl. This patch fixes two uninitialized variable problems found with valgrind when testing the VHDL code generator. --- t-dll.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/t-dll.cc b/t-dll.cc index 98ade6c15..8cec7bac7 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -1921,6 +1921,7 @@ void dll_target::lpm_mult(const NetMult*net) unsigned wid = net->width_r(); obj->width = wid; + obj->u_.arith.signed_flag = 0; const Nexus*nex; @@ -2204,6 +2205,7 @@ bool dll_target::net_const(const NetConst*net) assert(net->pin_count() == 1); obj->width_ = net->width(); + obj->signed_ = 0; if (obj->width_ <= sizeof(obj->b.bit_)) { bits = obj->b.bit_; From 456fffa7ed3c966a5e8bcb127e06c36c7cca0a11 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 2 Sep 2008 18:23:48 -0700 Subject: [PATCH 09/12] Remove last vestiges of XNF. XNF hasn't been supported in a while. Xilinx doesn't put any effort into it either, for that matter. --- Makefile.in | 10 +- README.txt | 5 +- driver/iverilog.man | 12 +- main.cc | 6 - t-xnf.cc | 1151 ------------------------------------------- targets.cc | 54 -- xnf-s.conf | 6 - xnf.conf | 6 - xnf.txt | 298 ----------- xnf2pcf.sh | 26 - xnfio.cc | 478 ------------------ 11 files changed, 3 insertions(+), 2049 deletions(-) delete mode 100644 t-xnf.cc delete mode 100644 xnf-s.conf delete mode 100644 xnf.conf delete mode 100644 xnf.txt delete mode 100644 xnf2pcf.sh delete mode 100644 xnfio.cc diff --git a/Makefile.in b/Makefile.in index 3b16d2dd9..c5432c351 100644 --- a/Makefile.in +++ b/Makefile.in @@ -230,8 +230,6 @@ else WIN32_INSTALL = $(bindir)/iverilog-vpi endif -XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf - install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/include/constants.vams $(libdir)/ivl/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC) for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done for dir in vpi ivlpp driver; \ @@ -249,12 +247,6 @@ $(libdir)/ivl/include/constants.vams: $(srcdir)/constants.vams $(libdir)/ivl/include/disciplines.vams: $(srcdir)/disciplines.vams $(INSTALL_DATA) $(srcdir)/disciplines.vams $(DESTDIR)$(libdir)/ivl/include/disciplines.vams -$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf - $(INSTALL_DATA) $(srcdir)/xnf-s.conf $(DESTDIR)$(libdir)/ivl/xnf-s.conf - -$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf - $(INSTALL_DATA) $(srcdir)/xnf.conf $(DESTDIR)$(libdir)/ivl/xnf.conf - $(includedir)/ivl_target.h: $(srcdir)/ivl_target.h $(INSTALL_DATA) $(srcdir)/ivl_target.h $(DESTDIR)$(includedir)/ivl_target.h @@ -304,7 +296,7 @@ uninstall: for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done for dir in vpi ivlpp driver; \ do (cd $$dir ; $(MAKE) $@); done - for f in xnf.conf xnf-s.conf ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \ + for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \ do rm -f $(DESTDIR)$(libdir)/ivl/$$f; done -rmdir $(DESTDIR)$(libdir)/ivl/include -rmdir $(DESTDIR)$(libdir)/ivl diff --git a/README.txt b/README.txt index 2d447a2be..b980e9c1f 100644 --- a/README.txt +++ b/README.txt @@ -12,10 +12,7 @@ home page at . Icarus Verilog is not aimed at being a simulator in the traditional sense, but a compiler that generates code employed by back-end -tools. These back-end tools currently include a simulator engine -called VVP, an XNF (Xilinx Netlist Format) generator and an EDIF FPGA -netlist generator. In the future, backends are expected for EDIF/LPM, -structural Verilog, VHDL, etc. +tools. For instructions on how to run Icarus Verilog, see the ``iverilog'' man page. diff --git a/driver/iverilog.man b/driver/iverilog.man index 3c74e9feb..bdadee29e 100644 --- a/driver/iverilog.man +++ b/driver/iverilog.man @@ -14,7 +14,7 @@ iverilog - Icarus Verilog compiler \fIiverilog\fP is a compiler that translates Verilog source code into executable programs for simulation, or other netlist formats for further processing. The currently supported targets are \fIvvp\fP for -simulation, and \fIxnf\fP and \fIfpga\fP for synthesis. Other target +simulation, and \fIfpga\fP for synthesis. Other target types are added as code generators are implemented. .SH OPTIONS @@ -212,11 +212,6 @@ This is the default. The vvp target generates code for the vvp runtime. The output is a complete program that simulates the design but must be run by the \fBvvp\fP command. .TP 8 -.B xnf -This is the Xilinx Netlist Format used by many tools for placing -devices in FPGAs or other programmable devices. This target is -obsolete, use the \fBfpga\fP target instead. -.TP 8 .B fpga This is a synthesis target that supports a variety of fpga devices, mostly by EDIF format output. The Icarus Verilog fpga code generator @@ -418,11 +413,6 @@ To compile and run explicitly using the vvp runtime: iverilog -ohello.vvp -tvvp hello.v -To compile hello.v to a file in XNF-format called hello.xnf - - iverilog -txnf -ohello.xnf hello.v - - .SH "AUTHOR" .nf Steve Williams (steve@icarus.com) diff --git a/main.cc b/main.cc index 17235f3cf..026a90b92 100644 --- a/main.cc +++ b/main.cc @@ -161,9 +161,6 @@ extern void synth(Design*des); extern void synth2(Design*des); extern void syn_rules(Design*des); extern void nodangle(Design*des); -#ifdef WITH_T_XNF -extern void xnfio(Design*des); -#endif typedef void (*net_func)(Design*); static struct net_func_map { @@ -175,9 +172,6 @@ static struct net_func_map { { "synth", &synth }, { "synth2", &synth2 }, { "syn-rules", &syn_rules }, -#ifdef WITH_T_XNF - { "xnfio", &xnfio }, -#endif { 0, 0 } }; diff --git a/t-xnf.cc b/t-xnf.cc deleted file mode 100644 index e6bf20bc8..000000000 --- a/t-xnf.cc +++ /dev/null @@ -1,1151 +0,0 @@ -/* - * Copyright (c) 1998-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 - */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: t-xnf.cc,v 1.52 2004/02/20 18:53:36 steve Exp $" -#endif - -# include "config.h" - -# include - -/* XNF BACKEND - * This target supports generating Xilinx Netlist Format netlists for - * use by Xilinx tools, and other tools that accepts Xilinx designs. - * - * The code generator automatically detects ports to top level modules - * and generates SIG records that make the XNF usable as a schematic. - * - * FLAGS - * The XNF backend uses the following flags from the command line to - * affect the generated file: - * - * part= - * Specify the part type. The part string is written into the - * PART record. Valid types are defined by Xilinx or the - * receiving tools. - * - * ncf= - * Specify the path to a NCF file. This is an OUTPUT file into - * which the code generator will write netlist constraints that - * relate to pin assignments, CLB placement, etc. If this flag is - * not given, no NCF file will be written. - * - * WIRE ATTRIBUTES - * - * PAD = - * Tell the XNF generator that this wire goes to a PAD. The - * is a single character that tells the direction, and is the - * pin number. For example, "o31" is output on pin 31. The PAD - * attribute is not practically connected to a vector, as all the - * bits would go to the same pad. - * - * NODE ATTRIBUTES - * - * XNF-LCA = :,... - * Specify the LCA library part type for the gate. The lname - * is the name of the symbol to use (i.e. DFF) and the comma - * separated list is the names of the pins, in the order they - * appear in the Verilog source. If the name is prefixed with a - * tilde (~) then the pin is inverted, and the proper "INV" token - * will be added to the PIN record. - * - * This attribute can override even the typical generation of - * gates that one might naturally expect of the code generator, - * but may be used by the optimizers for placing parts. - * - * An example is "XNF-LCA=OBUF:O,~I". This attribute means that - * the object is an OBUF. Pin 0 is called "O", and pin 1 is - * called "I". In addition, pin 1 is inverted. - */ - -# include "netlist.h" -# include "target.h" -# include -# include - -verinum::V link_get_ival(const Link&lnk) -{ - const Nexus*nex = lnk.nexus(); - for (const Link*cur = nex->first_nlink() - ; cur ; cur = cur->next_nlink()) { - if (cur == &lnk) - continue; - - if (dynamic_cast(cur->get_obj())) - return cur->nexus()->get_init(); - - } - - return verinum::Vx; -} - -class target_xnf : public target_t { - - public: - bool start_design(const Design*); - int end_design(const Design*); - void memory(const NetMemory*); - void signal(const NetNet*); - - void lpm_add_sub(const NetAddSub*); - void lpm_compare(const NetCompare*); - void lpm_compare_eq_(ostream&os, const NetCompare*); - void lpm_compare_ge_(ostream&os, const NetCompare*); - void lpm_compare_le_(ostream&os, const NetCompare*); - void lpm_ff(const NetFF*); - void lpm_mux(const NetMux*); - void lpm_ram_dq(const NetRamDq*); - - bool net_const(const NetConst*); - void logic(const NetLogic*); - bool bufz(const NetBUFZ*); - void udp(const NetUDP*); - - private: - static string mangle(const string&); - static string mangle(perm_string); - static string choose_sig_name(const Link*lnk); - static void draw_pin(ostream&os, const string&name, - const Link&lnk); - static void draw_sym_with_lcaname(ostream&os, string lca, - const NetNode*net); - static void draw_xor(ostream&os, const NetAddSub*, unsigned idx); - enum adder_type {FORCE0, LOWER, DOUBLE, LOWER_W_CO, EXAMINE_CI }; - static void draw_carry(ostream&os, const NetAddSub*, unsigned idx, - enum adder_type); - - ofstream out_; - ofstream ncf_; -}; - -/* - * This function takes a signal name and mangles it into an equivalent - * name that is suitable to the XNF format. - */ -string target_xnf::mangle(const string&name) -{ - string result; - for (unsigned idx = 0 ; idx < name.length() ; idx += 1) - switch (name[idx]) { - case '.': - result = result + "/"; - break; - default: - result = result + name[idx]; - break; - } - - return result; -} - -string target_xnf::mangle(perm_string name) -{ - return mangle(string(name)); -} - -/* - * This method takes a signal and pin number as a nexus. Scan the - * nexus to decide which name to use if there are lots of attached - * signals. - */ -string target_xnf::choose_sig_name(const Link*lnk) -{ - return mangle( string(lnk->nexus()->name()) ); -} - -void target_xnf::draw_pin(ostream&os, const string&name, - const Link&lnk) -{ - bool inv = false; - string use_name = name; - if (use_name[0] == '~') { - inv = true; - use_name = use_name.substr(1); - } - - char type=0; - switch (lnk.get_dir()) { - case Link::INPUT: - case Link::PASSIVE: - type = 'I'; - break; - case Link::OUTPUT: - type = 'O'; - break; - } - assert(type); - - os << " PIN, " << use_name << ", " << type << ", " << - choose_sig_name(&lnk); - if (inv) os << ",,INV"; - os << endl; -} - -static string scrape_pin_name(string&list) -{ - unsigned idx = list.find(','); - string name = list.substr(0, idx); - list = list.substr(idx+1); - return name; -} - -/* - * This method draws an LCA item based on the XNF-LCA attribute - * given. The LCA attribute gives enough information to completely - * draw the node in XNF, which is pretty handy at this point. - */ -void target_xnf::draw_sym_with_lcaname(ostream&os, string lca, - const NetNode*net) -{ - unsigned idx = lca.find(':'); - string lcaname = lca.substr(0, idx); - lca = lca.substr(idx+1); - - os << "SYM, " << mangle(net->name()) << ", " << lcaname - << ", LIBVER=2.0.0" << endl; - - for (idx = 0 ; idx < net->pin_count() ; idx += 1) { - string usename = scrape_pin_name(lca); - if (usename == "") continue; - draw_pin(os, usename, net->pin(idx)); - } - - os << "END" << endl; -} - -bool target_xnf::start_design(const Design*des) -{ - out_.open(des->get_flag("-o"), ios::out | ios::trunc); - - string ncfpath = des->get_flag("ncf"); - if (ncfpath != "") - ncf_.open(ncfpath.c_str()); - - out_ << "LCANET,6" << endl; - out_ << "PROG,verilog,$Name: $,\"Icarus Verilog\"" << endl; - ncf_ << "# Generated by Icarus Verilog $Name: $" << endl; - - if (des->get_flag("part") != 0) { - out_ << "PART," << des->get_flag("part") << endl; - ncf_ << "CONFIG PART=" << des->get_flag("part") << ";" << endl; - } - - return true; -} - -int target_xnf::end_design(const Design*) -{ - out_ << "EOF" << endl; - ncf_.close(); - return 0; -} - -void scrape_pad_info(string str, char&dir, unsigned&num) -{ - // Get rid of leading white space - while (str[0] == ' ') - str = str.substr(1); - - // Get the direction letter - switch (str[0]) { - case 'b': - case 'B': - dir = 'B'; - break; - case 'o': - case 'O': - dir = 'O'; - break; - case 'i': - case 'I': - dir = 'I'; - break; - case 't': - case 'T': - dir = 'T'; - break; - default: - dir = '?'; - break; - } - - // Get the number part. - str = str.substr(1); - unsigned val = 0; - while (str.size() && isdigit(str[0])) { - val = val * 10 + (str[0]-'0'); - str = str.substr(1); - } - num = val; -} - -/* - * Memories are handled by the lpm_ram_dq method, so there is nothing - * to do here. - */ -void target_xnf::memory(const NetMemory*) -{ -} - -/* - * Look for signals that have attributes that are pertinent to XNF - * files. The most obvious are those that have the PAD attribute. - * - * Individual signals are easy, the pad description is a letter - * followed by a decimal number that is the pin. - * - * The PAD attribute for a vector is a comma separated pin - * descriptions, that enumerate the pins from most significant to - * least significant. - */ -void target_xnf::signal(const NetNet*net) -{ - - /* Look for signals that are ports to the root module. If they - are, the write a SIG record and generate a pin name so that - this module can be used as a macro. */ - - if (const NetScope*scope = net->scope()) do { - - if (scope->parent()) - break; - - if (net->port_type() == NetNet::NOT_A_PORT) - break; - - string mname = mangle(net->name()); - string pname = mname.substr(mname.find('/')+1, mname.length()); - - if (net->pin_count() == 1) { - out_ << "SIG, " << mangle(net->name()) << ", PIN=" - << pname << endl; - - } else for (unsigned idx = 0; idx < net->pin_count(); idx += 1) { - out_ << "SIG, " << mangle(net->name()) << "<" << idx - << ">, PIN=" << pname << idx << endl; - } - - } while (0); - - - /* Now look to see if a PAD attribute is attached, and if so - write out PAD information to the XNF and the ncf files. */ - - string pad = net->attribute(perm_string::literal("PAD")).as_string(); - if (pad == "") - return; - - if (net->pin_count() > 1) { - cerr << "Signal ``" << net->name() << "'' with PAD=" << - pad << " is a vector." << endl; - return; - } - - char dir; - unsigned num; - scrape_pad_info(pad, dir, num); - out_ << "EXT, " << mangle(net->name()) << ", " << dir - << ", " << num << endl; - - ncf_ << "# Assignment to pin " << num << " (DIR=" << dir << - ") by $attribute(" << net->name() << ", \"PAD\", \"" << - pad << "\")" << endl; - ncf_ << "NET " << mangle(net->name()) << " LOC=P" << num << ";" - << endl; -} - -void target_xnf::draw_xor(ostream &os, const NetAddSub*gate, unsigned idx) -{ - string name = mangle(gate->name()); - string name_add = name; - string name_cout = name + "/COUT"; - - // We only need to pick up the - // carry if we are not the 0 bit. (We know it is 0). - os << "SYM, " << name_add << "<" << (idx+0) << ">, XOR, " - "LIBVER=2.0.0" << endl; - draw_pin(os, "O", gate->pin_Result(idx)); - draw_pin(os, "I0", gate->pin_DataA(idx)); - draw_pin(os, "I1", gate->pin_DataB(idx)); - if (idx > 0) { - os << " PIN, I2, I, " << name_cout << "<" << - idx << ">" << endl; - } - os << "END" << endl; -} - -void target_xnf::draw_carry(ostream &os, const NetAddSub*gate, unsigned idx, - enum adder_type type) -{ - string name = mangle(gate->name()); - - string name_cy4 = name + "/CY"; - string name_cym = name + "/CM"; - string name_cout = name + "/COUT"; - - os << "SYM, " << name_cy4 << "<" << idx << ">, CY4, " - "LIBVER=2.0.0" << endl; - - // Less significant bit addends, if any - if ( type == LOWER || type == DOUBLE || type == LOWER_W_CO ) { - draw_pin(os, "A0", gate->pin_DataA(idx)); - draw_pin(os, "B0", gate->pin_DataB(idx)); - } - - // More significant bit addends, if any - if ( type == DOUBLE ) { - draw_pin(os, "A1", gate->pin_DataA(idx+1)); - draw_pin(os, "B1", gate->pin_DataB(idx+1)); - } - - // All but FORCE0 cells have carry input - if ( type != FORCE0 ) { - os << " PIN, CIN, I, " << name_cout << "<" << idx << ">" << endl; - } - - // Connect the Cout0 to a signal so that I can connect - // it to the adder. - switch (type) { - case LOWER: - case DOUBLE: - os << " PIN, COUT0, O, " << name_cout << "<" << (idx+1) << - ">" << endl; - break; - case EXAMINE_CI: - case LOWER_W_CO: - draw_pin(os, "COUT0", gate->pin_Cout()); - break; - - default: - assert(0); - } - - // Connect the Cout, this will connect to the next Cin - if ( type == FORCE0 || type == DOUBLE ) { - unsigned int to = (type==FORCE0)?(0):(idx+2); - os << " PIN, COUT, O, " << name_cout << "<" << to << - ">" << endl; - } - - // These are the mode inputs from the CY_xx pseudo-device - for (unsigned cn = 0 ; cn < 8 ; cn += 1) { - os << " PIN, C" << cn << ", I, " << name << "/C" - << cn << "<" << (idx) << ">" << endl; - } - os << "END" << endl; - - // On to the CY_xx pseudo-device itself - os << "SYM, " << name_cym << "<" << (idx) << ">, "; - switch (type) { - case FORCE0: - os << "CY4_37, CYMODE=FORCE-0" << endl; - break; - case LOWER: - os << "CY4_01, CYMODE=ADD-F-CI" << endl; - break; - case LOWER_W_CO: - os << "CY4_01, CYMODE=ADD-F-CI" << endl; - break; - case DOUBLE: - os << "CY4_02, CYMODE=ADD-FG-CI" << endl; - break; - case EXAMINE_CI: - os << "CY4_42, CYMODE=EXAMINE-CI" << endl; - break; - } - for (unsigned cn = 0 ; cn < 8 ; cn += 1) { - os << " PIN, C" << cn << ", O, " << name << "/C" - << cn << "<" << (idx) << ">" << endl; - } - os << "END" << endl; -} - -/* - * This function makes an adder out of carry logic symbols. It makes - * as many 2 bit adders as are possible, then the top bit is made into - * a 1-bit adder (with carry in) in the F unit. The low carry is - * initialized with the FORCE-0 configuration of a carry unit below - * the 0 bit. This takes up the carry logic of the CLB below, but not - * the G function. - * - * References: - * XNF 6.1 Specification - * Application note XAPP013 - * Xilinx Libraries Guide, Chapter 12 - */ -void target_xnf::lpm_add_sub(const NetAddSub*gate) -{ - unsigned width = gate->width(); - - /* Make the force-0 carry mode object to initialize the bottom - bits of the carry chain. Label this with the width instead - of the bit position so that symbols don't clash. */ - - draw_carry(out_, gate, width+1, FORCE0); - - - /* Now make the 2 bit adders that chain from the cin - initializer and up. Save the tail bits for later. */ - for (unsigned idx = 0 ; idx < width-2 ; idx += 2) - draw_carry(out_, gate, idx, DOUBLE); - - /* Always have one or two tail bits. The situation gets a - little tricky if we want the carry output, so handle that - here. - - If the carry-out is connected, and there are an even number - of data bits, we need to see the cout from the CLB. This is - done by configuring the top CLB CY device as ADD-FG-CI (to - activate cout) and create an extra CLB CY device on top of - the carry chain configured EXAMINE-CI to put the carry into - the G function block. - - IF the carry-out is connected and there are an odd number - of data bits, then the top CLB can be configured to carry - the top bit in the F unit and deliver the carry out through - the G unit. - - If the carry-out is not connected, then configure this top - CLB as ADD-F-CI. The draw_xor for the top bit will include - the F carry if needed. */ - - if (gate->pin_Cout().is_linked()) { - if (width%2 == 0) { - draw_carry(out_, gate, width-2, DOUBLE); - draw_carry(out_, gate, width, EXAMINE_CI); - } else { - draw_carry(out_, gate, width-1, LOWER_W_CO); - } - - } else { - if (width%2 == 0) - draw_carry(out_, gate, width-2, LOWER); - else - draw_carry(out_, gate, width-1, LOWER); - } - - /* Now draw all the single bit (plus carry in) adders from XOR - gates. This puts the F and G units to use. */ - for (unsigned idx = 0 ; idx < width ; idx += 1) - draw_xor(out_, gate, idx); - -} - -/* - * In XNF, comparators are done differently depending on the type of - * comparator being implemented. So, here we dispatch to the correct - * code generator. - */ -void target_xnf::lpm_compare(const NetCompare*dev) -{ - if (dev->pin_AEB().is_linked() || dev->pin_ANEB().is_linked()) { - lpm_compare_eq_(out_, dev); - return; - } - - if (dev->pin_AGEB().is_linked()) { - lpm_compare_ge_(out_, dev); - return; - } - - if (dev->pin_ALEB().is_linked()) { - lpm_compare_le_(out_, dev); - return; - } - - assert(0); -} - -/* - * To compare that vectors are equal (identity comparator) generate - * XNOR gates to compare each pair of bits, then generate an AND gate - * to combine the bitwise results. This is pretty much the best way to - * do an identity compare in Xilinx CLBs. - */ -void target_xnf::lpm_compare_eq_(ostream&os, const NetCompare*dev) -{ - string mname = mangle(dev->name()); - - /* Draw XNOR gates for each bit pair. These gates to the - bitwise comparison. */ - for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) { - os << "SYM, " << mname << "/cmp<" << idx << ">, " - << "XNOR, LIBVER=2.0.0" << endl; - os << " PIN, O, O, " << mname << "/bit<" << idx << ">" - << endl; - draw_pin(os, "I0", dev->pin_DataA(idx)); - draw_pin(os, "I1", dev->pin_DataB(idx)); - os << "END" << endl; - } - - /* Now draw an AND gate to combine all the bitwise - comparisons. If there are more the 5 bits of data, then we - are going to have generate a nested AND to combine the - results. */ - - if (dev->width() > 5) { - for (unsigned idx = 0 ; idx < dev->width() ; idx += 5) { - - if ((idx+1) >= dev->width()) break; - os << "SYM, " << mname << "/nest<" << idx - << ">, AND, LIBVER=2.0.0" << endl; - - os << " PIN, O, O, " << mname << "/nbit<" << idx - << ">" << endl; - - os << " PIN, I0, I, " << mname << "/bit<" << idx+0 - << ">" << endl; - os << " PIN, I1, I, " << mname << "/bit<" << idx+1 - << ">" << endl; - if ((idx+2) >= dev->width()) goto gate_out; - os << " PIN, I2, I, " << mname << "/bit<" << idx+2 - << ">" << endl; - if ((idx+3) >= dev->width()) goto gate_out; - os << " PIN, I3, I, " << mname << "/bit<" << idx+3 - << ">" << endl; - if ((idx+4) >= dev->width()) goto gate_out; - os << " PIN, I4, I, " << mname << "/bit<" << idx+4 - << ">" << endl; - gate_out: - os << "END" << endl; - } - - /* Draw an AND gate if this is an EQ result, or a NAND - gate of this is a NEQ result. */ - - if (dev->pin_AEB().is_linked()) { - assert( ! dev->pin_ANEB().is_linked()); - os << "SYM, " << mname << ", AND, LIBVER=2.0.0" << endl; - draw_pin(os, "O", dev->pin_AEB()); - - } else { - assert( dev->pin_ANEB().is_linked()); - os << "SYM, " << mname << ", NAND, LIBVER=2.0.0" << endl; - draw_pin(os, "O", dev->pin_ANEB()); - } - - for (unsigned idx = 0 ; idx < dev->width() ; idx += 5) { - if ((idx+1) == dev->width()) - os << " PIN, I" << idx/5 << ", I, " << mname - << "/bit<" << idx << ">" << endl; - else - os << " PIN, I" << idx/5 << ", I, " << mname - << "/nbit<" << idx << ">" << endl; - } - os << "END" << endl; - - } else { - if (dev->pin_AEB().is_linked()) { - assert( ! dev->pin_ANEB().is_linked()); - os << "SYM, " << mname << ", AND, LIBVER=2.0.0" << endl; - draw_pin(os, "O", dev->pin_AEB()); - - } else { - assert( dev->pin_ANEB().is_linked()); - os << "SYM, " << mname << ", NAND, LIBVER=2.0.0" << endl; - draw_pin(os, "O", dev->pin_ANEB()); - } - - for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) { - os << " PIN, I" << idx << ", I, " << mname << "/bit<" - << idx << ">" << endl; - } - os << "END" << endl; - } -} - -void target_xnf::lpm_compare_ge_(ostream&os, const NetCompare*dev) -{ - cerr << "XXXX GE not supported yet" << endl; -} - -void target_xnf::lpm_compare_le_(ostream&os, const NetCompare*dev) -{ - cerr << "XXXX LE not supported yet" << endl; -} - -void target_xnf::lpm_ff(const NetFF*net) -{ - string type = net->attribute(perm_string::literal("LPM_FFType")).as_string(); - if (type == "") type = "DFF"; - - // XXXX For now, only support DFF - assert(type == "DFF"); - - string lcaname = net->attribute(perm_string::literal("XNF-LCA")).as_string(); - if (lcaname != "") { - draw_sym_with_lcaname(out_, lcaname, net); - return; - } - - assert(net->attribute(perm_string::literal("XNF-LCA")) == verinum("")); - - /* Create a DFF object for each bit of width. The symbol name - has the index number appended so that read XNF may be able - to buss them. If the NetNet objects connected to the Q - output of the DFF have an initial value, the write an INIT= - parameter to set the power-up value. */ - - for (unsigned idx = 0 ; idx < net->width() ; idx += 1) { - - verinum::V ival = link_get_ival(net->pin_Q(idx)); - - out_ << "SYM, " << mangle(net->name()) << "<" << idx << ">, DFF, "; - - switch (ival) { - case verinum::V0: - out_ << "INIT=R, "; - break; - case verinum::V1: - out_ << "INIT=S, "; - break; - - default: - break; - } - - out_ << "LIBVER=2.0.0" << endl; - draw_pin(out_, "Q", net->pin_Q(idx)); - draw_pin(out_, "D", net->pin_Data(idx)); - - if (net->attribute(perm_string::literal("Clock:LPM_Polarity")) == verinum("INVERT")) - draw_pin(out_, "~C", net->pin_Clock()); - else - draw_pin(out_, "C", net->pin_Clock()); - - if (net->pin_Enable().is_linked()) - draw_pin(out_, "CE", net->pin_Enable()); - - out_ << "END" << endl; - } -} - -/* - * Generate an LPM_MUX. - * - * XXXX NOTE: For now, this only supports combinational LPM_MUX - * devices that have a single select input. These are typically - * generated from ?: expressions. - */ -void target_xnf::lpm_mux(const NetMux*net) -{ - assert(net->sel_width() == 1); - assert(net->size() == 2); - - for (unsigned idx = 0 ; idx < net->width() ; idx += 1) { - - out_ << "SYM, " << mangle(net->name()) << "<" << idx << ">," - << " EQN, EQN=(I0 * I2) + (~I0 * I1)" << endl; - - draw_pin(out_, "I0", net->pin_Sel(0)); - draw_pin(out_, "I1", net->pin_Data(idx,0)); - draw_pin(out_, "I2", net->pin_Data(idx,1)); - draw_pin(out_, "O", net->pin_Result(idx)); - - out_ << "END" << endl; - } - -} - -void target_xnf::lpm_ram_dq(const NetRamDq*ram) -{ - assert(ram->count_partners() == 1); - - for (unsigned idx = 0 ; idx < ram->width() ; idx += 1) { - out_ << "SYM, " << mangle(ram->name()) - << "<" << idx << ">, RAMS" << endl; - - draw_pin(out_, "O", ram->pin_Q(idx)); - draw_pin(out_, "D", ram->pin_Data(idx)); - draw_pin(out_, "WE", ram->pin_WE()); - draw_pin(out_, "WCLK", ram->pin_InClock()); - for (unsigned adr = 0 ; adr < ram->awidth() ; adr += 1) { - ostringstream tmp; - tmp << "A" << adr; - draw_pin(out_, tmp.str(), ram->pin_Address(adr)); - } - - out_ << "END" << endl; - } -} - -bool target_xnf::net_const(const NetConst*c) -{ - unsigned x_bits = 0; - for (unsigned idx = 0 ; idx < c->pin_count() ; idx += 1) { - verinum::V v=c->value(idx); - const Link& lnk = c->pin(idx); - - switch (v) { - case verinum::V0: - out_ << " PWR, 0, " << choose_sig_name(&lnk) << endl; - break; - case verinum::V1: - out_ << " PWR, 1, " << choose_sig_name(&lnk) << endl; - break; - case verinum::Vz: - break; - default: - x_bits += 1; - if (x_bits == 1) - cerr << "xnf: error: Unknown (x) const bit value" - << " assigned to " << choose_sig_name(&lnk) - << endl; - break; - } - } - - return x_bits == 0; -} - -/* - * The logic gates I know so far can be translated directly into XNF - * standard symbol types. This is a fairly obvious transformation. - */ -void target_xnf::logic(const NetLogic*net) -{ - // The XNF-LCA attribute overrides anything I might guess - // about this object. - string lca = net->attribute(perm_string::literal("XNF-LCA")).as_string(); - if (lca != "") { - draw_sym_with_lcaname(out_, lca, net); - return; - } - - out_ << "SYM, " << mangle(net->name()) << ", "; - switch (net->type()) { - case NetLogic::AND: - out_ << "AND"; - break; - case NetLogic::BUF: - out_ << "BUF"; - break; - case NetLogic::NAND: - out_ << "NAND"; - break; - case NetLogic::NOR: - out_ << "NOR"; - break; - case NetLogic::NOT: - out_ << "INV"; - break; - case NetLogic::OR: - out_ << "OR"; - break; - case NetLogic::XNOR: - out_ << "XNOR"; - break; - case NetLogic::XOR: - out_ << "XOR"; - break; - case NetLogic::BUFIF0: - case NetLogic::BUFIF1: - out_ << "TBUF"; - break; - default: - cerr << "internal error: XNF: Unhandled logic type." << endl; - break; - } - out_ << ", LIBVER=2.0.0" << endl; - - /* All of these kinds of devices have an output on pin 0. */ - draw_pin(out_, "O", net->pin(0)); - - /* Most devices have inputs called I for all the remaining - pins. The TBUF devices are slightly different, but - essentially the same structure. */ - switch (net->type()) { - - case NetLogic::BUFIF0: - assert(net->pin_count() == 3); - draw_pin(out_, "I", net->pin(1)); - draw_pin(out_, "~T", net->pin(2)); - break; - - case NetLogic::BUFIF1: - assert(net->pin_count() == 3); - draw_pin(out_, "I", net->pin(1)); - draw_pin(out_, "T", net->pin(2)); - break; - - default: - if (net->pin_count() == 2) { - draw_pin(out_, "I", net->pin(1)); - } else for (unsigned idx = 1; idx < net->pin_count(); idx += 1) { - string name = "I"; - assert(net->pin_count() <= 11); - name += (char)('0'+idx-1); - draw_pin(out_, name, net->pin(idx)); - } - break; - } - - out_ << "END" << endl; -} - -bool target_xnf::bufz(const NetBUFZ*net) -{ - static int warned_once=0; - if (!warned_once) { - cerr << "0:0: internal warning: BUFZ objects found " - << "in XNF netlist." << endl; - cerr << "0:0: : I'll make BUFs for them." - << endl; - warned_once=1; - } - out_ << "SYM, " << mangle(net->name()) << ", BUF, LIBVER=2.0.0" << endl; - assert(net->pin_count() == 2); - draw_pin(out_, "O", net->pin(0)); - draw_pin(out_, "I", net->pin(1)); - out_ << "END" << endl; - - return true; -} - -void target_xnf::udp(const NetUDP*net) -{ - string lca = net->attribute(perm_string::literal("XNF-LCA")).as_string(); - - // I only know how to draw a UDP if it has the XNF-LCA - // attribute attached to it. - if (lca == "") { - cerr << "I don't understand this UDP." << endl; - return; - } - - draw_sym_with_lcaname(out_, lca, net); -} - -static target_xnf target_xnf_obj; - -extern const struct target tgt_xnf = { "xnf", &target_xnf_obj }; - -/* - * $Log: t-xnf.cc,v $ - * Revision 1.52 2004/02/20 18:53:36 steve - * Addtrbute keys are perm_strings. - * - * Revision 1.51 2004/02/18 17:11:58 steve - * Use perm_strings for named langiage items. - * - * Revision 1.50 2003/11/10 20:59:04 steve - * Design::get_flag returns const char* instead of string. - * - * Revision 1.49 2003/07/05 20:42:08 steve - * Fix some enumeration warnings. - * - * Revision 1.48 2003/06/24 01:38:03 steve - * Various warnings fixed. - * - * Revision 1.47 2003/01/30 16:23:08 steve - * Spelling fixes. - * - * Revision 1.46 2003/01/14 21:16:18 steve - * Move strstream to ostringstream for compatibility. - * - * Revision 1.45 2002/08/12 01:35:01 steve - * conditional ident string using autoconfig. - * - * Revision 1.44 2002/05/23 03:08:52 steve - * Add language support for Verilog-2001 attribute - * syntax. Hook this support into existing $attribute - * handling, and add number and void value types. - * - * Add to the ivl_target API new functions for access - * of complex attributes attached to gates. - * - * Revision 1.43 2001/07/25 03:10:50 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.42 2001/06/30 20:11:15 steve - * typo in CYMODE=EXAMINE-CI string. - * - * Revision 1.41 2001/03/27 03:31:06 steve - * Support error code from target_t::end_design method. - * - * Revision 1.40 2001/02/10 03:22:49 steve - * Report errors when XNF code has constant X values. (PR#128) - * - * Revision 1.39 2000/11/29 23:15:54 steve - * More informative BUFZ warning. - * - * Revision 1.38 2000/11/29 02:54:49 steve - * Add XNF support for NE comparators. - * - * Revision 1.37 2000/11/29 01:34:17 steve - * Typo writing I pins to AND gates in compare. - * - * Revision 1.36 2000/11/22 21:18:20 steve - * Connect the CE if it is linked at all. - * - * Revision 1.35 2000/08/14 04:39:57 steve - * add th t-dll functions for net_const, net_bufz and processes. - * - * Revision 1.34 2000/08/09 03:43:45 steve - * Move all file manipulation out of target class. - * - * Revision 1.33 2000/08/08 01:50:42 steve - * target methods need not take a file stream. - * - * Revision 1.32 2000/07/14 06:12:58 steve - * Move inital value handling from NetNet to Nexus - * objects. This allows better propogation of inital - * values. - * - * Clean up constant propagation a bit to account - * for regs that are not really values. - * - * Revision 1.31 2000/06/28 18:38:54 steve - * Use nexus type to get nexus name. - * - * Revision 1.30 2000/06/25 19:59:42 steve - * Redesign Links to include the Nexus class that - * carries properties of the connected set of links. - * - * Revision 1.29 2000/05/14 17:55:04 steve - * Support initialization of FF Q value. - * - * Revision 1.28 2000/05/08 05:29:43 steve - * no need for nobufz functor. - * - * Revision 1.27 2000/05/07 04:37:56 steve - * Carry strength values from Verilog source to the - * pform and netlist for gates. - * - * Change vvm constants to use the driver_t to drive - * a constant value. This works better if there are - * multiple drivers on a signal. - * - * Revision 1.26 2000/04/23 23:03:13 steve - * automatically generate macro interface code. - * - * Revision 1.25 2000/04/23 21:15:07 steve - * Emit code for the bufif devices. - * - * Revision 1.24 2000/04/20 02:34:47 steve - * Generate code for identity compare. Use gates. - * - * Revision 1.23 2000/02/23 02:56:55 steve - * Macintosh compilers do not support ident. - * - * Revision 1.22 1999/12/17 03:38:46 steve - * NetConst can now hold wide constants. - * - * Revision 1.21 1999/12/16 18:54:32 steve - * Capture the carry out of carry-chain addition. - * - * Revision 1.20 1999/12/16 02:42:15 steve - * Simulate carry output on adders. - * - * Revision 1.19 1999/12/05 19:30:43 steve - * Generate XNF RAMS from synthesized memories. - * - * Revision 1.18 1999/11/19 03:02:25 steve - * Detect flip-flops connected to opads and turn - * them into OUTFF devices. Inprove support for - * the XNF-LCA attribute in the process. - * - * Revision 1.17 1999/11/17 18:52:09 steve - * Add algorithm for choosing nexus name from attached signals. - * - * Revision 1.16 1999/11/17 01:31:28 steve - * Clean up warnings that add_sub got from Alliance - * - * Revision 1.15 1999/11/06 04:51:42 steve - * Support writing some XNF things into an NCF file. - * - * Revision 1.14 1999/11/05 18:43:12 steve - * fix syntax of EQN record. - * - * Revision 1.13 1999/11/05 07:10:45 steve - * Include the obvious XOR gates in the adders. - * - * Revision 1.12 1999/11/05 04:40:40 steve - * Patch to synthesize LPM_ADD_SUB from expressions, - * Thanks to Larry Doolittle. Also handle constants - * in expressions. - * - * Synthesize adders in XNF, based on a patch from - * Larry. Accept synthesis of constants from Larry - * as is. - * - * Revision 1.11 1999/11/04 03:53:26 steve - * Patch to synthesize unary ~ and the ternary operator. - * Thanks to Larry Doolittle . - * - * Add the LPM_MUX device, and integrate it with the - * ternary synthesis from Larry. Replace the lpm_mux - * generator in t-xnf.cc to use XNF EQU devices to - * put muxs into function units. - * - * Rewrite elaborate_net for the PETernary class to - * also use the LPM_MUX device. - * - * Revision 1.10 1999/11/02 04:55:34 steve - * Add the synthesize method to NetExpr to handle - * synthesis of expressions, and use that method - * to improve r-value handling of LPM_FF synthesis. - * - * Modify the XNF target to handle LPM_FF objects. - * - * Revision 1.9 1999/08/25 22:22:08 steve - * handle bufz in XNF backend. - * - * Revision 1.8 1999/08/18 04:00:02 steve - * Fixup spelling and some error messages. - * - * Revision 1.7 1999/07/17 03:39:11 steve - * simplified process scan for targets. - * - * Revision 1.6 1998/12/09 02:43:19 steve - * Fix 2pin logic gates. - * - * Revision 1.5 1998/12/07 04:53:17 steve - * Generate OBUF or IBUF attributes (and the gates - * to garry them) where a wire is a pad. This involved - * figuring out enough of the netlist to know when such - * was needed, and to generate new gates and signales - * to handle what's missing. - * - * Revision 1.4 1998/12/02 04:37:13 steve - * Add the nobufz function to eliminate bufz objects, - * Object links are marked with direction, - * constant propagation is more careful will wide links, - * Signal folding is aware of attributes, and - * the XNF target can dump UDP objects based on LCA - * attributes. - * - * Revision 1.3 1998/11/23 00:20:24 steve - * NetAssign handles lvalues as pin links - * instead of a signal pointer, - * Wire attributes added, - * Ability to parse UDP descriptions added, - * XNF generates EXT records for signals with - * the PAD attribute. - * - * Revision 1.2 1998/11/18 04:25:22 steve - * Add -f flags for generic flag key/values. - * - * Revision 1.1 1998/11/16 05:03:53 steve - * Add the sigfold function that unlinks excess - * signal nodes, and add the XNF target. - * - */ - diff --git a/targets.cc b/targets.cc index 7b2adb9f9..8df415cf3 100644 --- a/targets.cc +++ b/targets.cc @@ -16,68 +16,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: targets.cc,v 1.12 2004/12/11 02:31:28 steve Exp $" -#endif # include "config.h" # include "target.h" extern const struct target tgt_dll; -#ifdef WITH_T_XNF -extern const struct target tgt_xnf; -#endif const struct target *target_table[] = { &tgt_dll, -#ifdef WITH_T_XNF - &tgt_xnf, -#endif 0 }; - -/* - * $Log: targets.cc,v $ - * Revision 1.12 2004/12/11 02:31:28 steve - * Rework of internals to carry vectors through nexus instead - * of single bits. Make the ivl, tgt-vvp and vvp initial changes - * down this path. - * - * Revision 1.11 2002/08/12 01:35:01 steve - * conditional ident string using autoconfig. - * - * Revision 1.10 2002/08/11 23:39:33 steve - * Remove VVM option. - * - * Revision 1.9 2002/02/16 03:18:54 steve - * Make vvm optional, normally off. - * - * Revision 1.8 2001/07/25 03:10:50 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.7 2000/12/02 04:50:32 steve - * Make the null target into a loadable target. - * - * Revision 1.6 2000/08/12 16:34:37 steve - * Start stub for loadable targets. - * - * Revision 1.5 2000/02/23 02:56:56 steve - * Macintosh compilers do not support ident. - * - * Revision 1.4 1999/05/01 02:57:53 steve - * Handle much more complex event expressions. - * - * Revision 1.3 1999/01/24 01:35:36 steve - * Support null target for generating no output. - * - * Revision 1.2 1998/11/16 05:03:53 steve - * Add the sigfold function that unlinks excess - * signal nodes, and add the XNF target. - * - * Revision 1.1 1998/11/03 23:29:07 steve - * Introduce verilog to CVS. - * - */ - diff --git a/xnf-s.conf b/xnf-s.conf deleted file mode 100644 index ffcd9ae6c..000000000 --- a/xnf-s.conf +++ /dev/null @@ -1,6 +0,0 @@ -functor:synth -functor:syn-rules -functor:xnfio -functor:cprop -functor:nodangle --t:xnf diff --git a/xnf.conf b/xnf.conf deleted file mode 100644 index ffcd9ae6c..000000000 --- a/xnf.conf +++ /dev/null @@ -1,6 +0,0 @@ -functor:synth -functor:syn-rules -functor:xnfio -functor:cprop -functor:nodangle --t:xnf diff --git a/xnf.txt b/xnf.txt deleted file mode 100644 index 483bab0ab..000000000 --- a/xnf.txt +++ /dev/null @@ -1,298 +0,0 @@ - -WHAT IS XNF - -XNF is the Xilinx Netlist Format. This is somewhat specific to the -Xilinx tool chain, but it is sufficiently ubiquitous that it's still -worth it. This format can be fed to place and route tools and -simulators. Since some third party simulators accept XNF, the format -may be useful even independent of Xilinx parts. - -Icarus Verilog supports XNF as specified by the Xilinx Netlist Format -Specification, Version 6.1. - -GENERATE XNF OUTPUT -- THE SHORT STORY - -The easiest way to compile for XNF output is with the "verilog" -command (man verilog) and the -X switch: - - % iverilog -fpart=4010e -fncf=prog.ncf -txnf prog.v - -This generates from the prog.v Verilog source file the prog.xnf output -and the prog.ncf netlist constraints file. The Verilog program -arranges to call the preprocessor and the ivl compiler with all the -correct switches for generating XNF. - -GENERATING XNF MACROS - -Icarus Verilog can be used to generate XNF implementations of devices -that are written in Verilog and used by schematic editors such as -OrCAD. The trick here is that the code generator automatically notices -ports to the root module and generates the PIN= attributes needed so -that external tools can link to the generated XNF. - -Icarus Verilog chooses a name for the pin. The name it chooses is the -port name of the module. If the port is a vector, a pin is generated -for all the bits of the vector with the bit number appended. For -example: - - module foo(in); - input [3:0] in; - -causes the single bit ports ``in0'' through ``in3'' be -generated. Internally, the XNF file uses the bussed names instead of -the pin name. - -The implication of this is that there is a chance of name collision -with the generated XNF macro if the port names are chosen badly. It is -best to not end a port name with decimal digits, as that can cause -trouble at link time. Also, XNF is not case sensitive and that should -be accounted for as well. - -XNF PADS IN VERILOG SOURCE - -You can assign wires to pads using the Icarus Verilog $attribute -extension. Attach to a scalar signal (wire or register) the PAD -attribute with the value that specifies the direction and pin -number. For example: - - wire foo, bar, bid; - $attribute(foo, "PAD", "i1"); // Input pad on pin 1 - $attribute(bar, "PAD", "o2"); // Output pad on pin 2 - $attribute(bid, "PAD", "b3"); // Bi-directional pad on pin 3 - -The XNFIO function uses these attributes to locate signals that are -connected to pads, and generates XNF I/O block devices to connect to -the pad to do the FPGA pin buffering that is needed. So the Verilog -programmer need not in general specify the IBUF/OBUF buffers. - -If the programmer does connect buffers to pads, the compiler will -notice them and convert them to I/OBUFs automatically. For example: - - buf b1 (sig, foo); - -connects to pad foo, so will be converted into an XNF IBUF -device. Also: - - bufif1 bt (bar, value, en); - -connects to pad bar so will automatically be converted into an OBUFT -device. Icarus Verilog understands OBUF, IBUF and OBUFT (with optionally -inverted enable) devices and will convert Verilog devices from the -source, or generate missing devices. - -In addition, the Verilog programmer may explicitly declare a device as -an I/OBUF by attaching an attribute to the device, like so: - - buf b1 (sig, foo); - $attribute(b1, "XNF-LCA", "OBUF:O,I"); - -This latter feature is not entirely recommended as it expects that the -programmer really knows how the pins of the XNF device are to be -connected. It also bypasses the efforts of the compiler, so is not -checked for correctness. - -XNF STORAGE ELEMENTS - -Storage elements in XNF include flip-flops, latches and CLB -rams. These devices are generated from the LPM equivalents that the --Fsynth functor synthesizes from behavioral descriptions. - -Flip-flops, or more specifically DFF devices, are generated to -implement behavioral code like this: - - reg Q; - always @(posedge clk) Q <= ; - -The edge can be positive or negative, and the expression can be any -synthesizable expression. Furthermore, the register "Q" can have -width, which will cause the appropriate number of flip-flops to be -created. A clock enable expression can also be added like so: - - reg Q; - always @(posedge clk) if () Q <= ; - -The expression can be any synthesizable expression. - -With or without the CE, the generated DFF devices are written into the -XNF output one bit at a time, with the clock input inverted if necessary. - -Xilinx parts also support CLB circuitry as synchronous RAMS. These -devices are created from Verilog memories if the properties are -right. The behavioral description that the -Fsynth functor matches to -get a synchronous RAM looks very similar to that for a DFF: - - reg [15:0] M; - always @(posedge clk) if () M[] <= ; - -Note that in this case the l-value of the assignment is an addressed -memory. This statement models writes into the memory. Reads from the -device can be modeled with ordinary structural code, i.e.: - - assign foo <= M[]; - -For the memory to be synthesizable in the XNF target, the address -lines for writes and reads must be connected. This corresponds to the -limitations of the real hardware. - -OTHER XNF SPECIAL DEVICES - -There are certain special devices in XNF that Verilog does not -naturally represent, although there are similar more generic Verilog -devices. The most obvious and useful example is the clock driver, -otherwise known as the global buffer BUFG. As with pads, Icarus -Verilog uses the $attribute extension to allow you to specify special -devices. - -The $attribute statement can be applied to devices much the same way -one applies them to wires. For example, to turn a buffer into a clock -buffer: - - wire iclk, clk; - buf BUFG (clk, iclk); - $attribute(iclk, "PAD", "i1"); - $attribute(BUFG, "XNF-LCA", "BUFG:O,I"); - -The above statements cause the buffer BUFG to be emitted in the XNF -output as a BUFG device with the first signal called "O" and the -second called "I". The rest of this example connects the input of the -BUFG to a signal from the input pin #1 and connects the output to the -internal wire "clk". Incidentally, this example will cause an IBUF to -be generated to connect the iclk signal to input pin #1. - -SUMMARY OF IVL SUPPORT FOR XNF - -Icarus Verilog has a code generator and synthesis functions that -support generation of XNF netlists. The XNF modules also allow the -programmer to use $attributes to control certain aspects of code -generation. - -XNF code generation is enabled with the ``-t xnf'' flag on the command -line. The code generator needs to know the type of part to generate -code for, so the ``-fpart='' flag is also needed. For example, -to generate code for the 4010E the command line might start out as: - - ivl -txnf -fpart=4010e -Fsynth -Fnodangle -Fxnfio [...] - -Icarus Verilog includes the functions ``synth'' and ``xnfio'' to -perform transformations and optimizations on the design before code is -generated. The ``synth'' function matches certain behavioral constructs -to structural components, and the xnfio function generates pads and -fills the IOBs. - -SUPPORTED FLAGS - - -fpart= - Specify the type of part to target. This string is written - literally into the PART, record of the XNF, and may also be - used to control synthesis and placement. - - -fncf= - Cause the code generator to write into the netlist - constraints needed for controlling placement and timing. This - switch is required if pin assignments are assigned in the - Verilog source. - -THE SYNTH FUNCTION - -This function does synthesis transformations on the entered design, -making it possible to generate XNF netlist components from certain -behavioral constructs. This is needed in Verilog for example to model -some of the synchronous components of the XNF library. - -It is a bit much to expect a Verilog compiler in general to generate -components from arbitrary behavioral descriptions, so the synth -function works by matching statements that have some documented -structure, and substituting them for the equivalent XNF component. A -fully synthesize-able design, then, is one where the behavioral -statements can all be matched and substituted by the synth function. - -THE XNFIO FUNCTION - -The "xnfio" function transforms the netlist where the IOBs are -concerned. The signals with PAD attributes are checked, and -surrounding circuitry generated to conform to the logic available in -the IOB. - -If the pad is an OPAD, the function will look for an existing buf or -not gate connected to the PAD signal. If the gate is appropriately -connected, the buf or not gate will be turned into an OBUF. This pulls -the buf or inverter into the IOB, freeing a CLB and providing the -required pin circuitry. - -If the pad is an IPAD, the function will look for a buf, and convert -that to an IBUF. Since Xilinx IOBs cannot invert the output from an -IBUF, NOT gates cannot be absorbed as in the OPAD case. - - -/* - * Copyright (c) 1998-1999 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 - */ - - - $Log: xnf.txt,v $ - Revision 1.16 2003/07/15 03:49:22 steve - Spelling fixes. - - Revision 1.15 2003/01/30 16:23:08 steve - Spelling fixes. - - Revision 1.14 2000/08/01 21:32:40 steve - Use the iverilog command in documentation. - - Revision 1.13 2000/08/01 02:48:42 steve - Support <= in synthesis of DFF and ram devices. - - Revision 1.12 2000/07/25 22:49:32 steve - memory is not a data type in verilog. - - Revision 1.11 2000/04/23 23:03:13 steve - automatically generate macro interface code. - - Revision 1.10 1999/12/05 19:30:43 steve - Generate XNF RAMS from synthesized memories. - - Revision 1.9 1999/11/18 03:52:20 steve - Turn NetTmp objects into normal local NetNet objects, - and add the nodangle functor to clean up the local - symbols generated by elaboration and other steps. - - Revision 1.8 1999/11/06 04:51:42 steve - Support writing some XNF things into an NCF file. - - Revision 1.7 1999/11/03 05:18:18 steve - XNF synthesis now uses the synth functor. - - Revision 1.6 1999/11/02 01:43:55 steve - Fix iobuf and iobufif handling. - - Revision 1.5 1999/10/09 17:52:27 steve - support XNF OBUFT devices. - - Revision 1.4 1999/08/14 22:48:21 steve - Mention the sigfold function. - - Revision 1.3 1999/07/22 02:05:20 steve - is_constant method for PEConcat. - - Revision 1.2 1999/07/18 21:17:51 steve - Add support for CE input to XNF DFF, and do - complete cleanup of replaced design nodes. - - Revision 1.1 1999/05/01 02:57:11 steve - XNF target documentation. - diff --git a/xnf2pcf.sh b/xnf2pcf.sh deleted file mode 100644 index abac1aa9c..000000000 --- a/xnf2pcf.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -# xnf2pcf - -# Converts perfectly good EXT records from an XNF file to -# a .pcf file for the "par" step of the Xilinx toolchain. -# Why on earth is this needed? Oh, well, the joys of working -# with black-box-ware. - -# Usage: xnf2pcf design.pcf - -# Refer to the resulting .pcf file in the invocation of "par", syntax: -# par [options] infile[.ncd] outfile pcf_file[.pcf] - -# Tested (successfully!) with XNF from Icarus Verilog, see -# http://www.geda.seul.org/tools/verilog/index.html -# and Xilinx back end tools from Foundation 1.5 - -# Author: Larry Doolittle -# Date: August 19, 1999 - -echo "SCHEMATIC START ;" -echo "SCHEMATIC END ;" -echo - -awk '/^EXT/{gsub(",",""); printf("COMP \"%s\" LOCATE = SITE \"P%s\" ;\n", $2, $4)}' diff --git a/xnfio.cc b/xnfio.cc deleted file mode 100644 index 9bf99c727..000000000 --- a/xnfio.cc +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright (c) 1998-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 - */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: xnfio.cc,v 1.30 2007/03/22 16:08:18 steve Exp $" -#endif - -# include "config.h" - -# include - -# include "functor.h" -# include "netlist.h" -# include "netmisc.h" - -class xnfio_f : public functor_t { - - public: - void signal(Design*des, NetNet*sig); - void lpm_compare(Design*des, NetCompare*dev); - - private: - bool compare_sideb_const(Design*des, NetCompare*dev); -}; - -static bool is_a_pad(const NetNet*net) -{ - if (net->attribute(perm_string::literal("PAD")) == verinum()) - return false; - - return true; -} - -/* - * The xnfio function looks for the PAD signals in the design, and - * generates the needed IOB devices to handle being connected to the - * actual FPGA PAD. This will add items to the netlist if needed. - * - * FIXME: If there is a DFF connected to the pad, try to convert it - * to an IO DFF instead. This would save a CLB, and it is - * really lame to not do the obvious optimization. - */ - -static NetLogic* make_obuf(Design*des, NetNet*net) -{ - NetScope* scope = net->scope(); - assert(scope); - - assert(net->pin_count() == 1); - - /* FIXME: If there is nothing internally driving this PAD, I - can connect the PAD to a pullup and disconnect it from the - rest of the circuit. This would save routing resources. */ - if (count_outputs(net->pin(0)) <= 0) { - cerr << net->get_line() << ":warning: No outputs to OPAD: " - << net->name() << endl; - return 0; - } - - assert(count_outputs(net->pin(0)) > 0); - - /* Look for an existing OBUF connected to this signal. If it - is there, then no need to add one. */ - Nexus*nex = net->pin(0).nexus(); - for (Link*idx = nex->first_nlink() - ; idx ; idx = idx->next_nlink()) { - NetLogic*tmp; - if ((tmp = dynamic_cast(idx->get_obj())) == 0) - continue; - - // Try to use an existing BUF as an OBUF. This moves the - // BUF into the IOB. - if ((tmp->type() == NetLogic::BUF) - && (count_inputs(tmp->pin(0)) == 0) - && (count_outputs(tmp->pin(0)) == 1) - && (idx->get_pin() == 0) ) { - tmp->attribute(perm_string::literal("XNF-LCA"), - verinum("OBUF:O,I")); - return tmp; - } - - // Try to use an existing INV as an OBUF. Certain - // technologies support inverting the input of an OBUF, - // which looks just like an inverter. This uses the - // available resources of an IOB to optimize away an - // otherwise expensive inverter. - if ((tmp->type() == NetLogic::NOT) - && (count_inputs(tmp->pin(0)) == 0) - && (count_outputs(tmp->pin(0)) == 1) - && (idx->get_pin() == 0) ) { - tmp->attribute(perm_string::literal("XNF-LCA"), - verinum("OBUF:O,~I")); - return tmp; - } - - // Try to use an existing bufif1 as an OBUFT. Of course - // this will only work if the output of the bufif1 is - // connected only to the pad. Handle bufif0 the same - // way, but the T input is inverted. - if ((tmp->type() == NetLogic::BUFIF1) - && (count_inputs(tmp->pin(0)) == 0) - && (count_outputs(tmp->pin(0)) == 1) - && (idx->get_pin() == 0) ) { - tmp->attribute(perm_string::literal("XNF-LCA"), - verinum("OBUFT:O,I,~T")); - return tmp; - } - - if ((tmp->type() == NetLogic::BUFIF0) - && (count_inputs(tmp->pin(0)) == 0) - && (count_outputs(tmp->pin(0)) == 1) - && (idx->get_pin() == 0) ) { - tmp->attribute(perm_string::literal("XNF-LCA"), - verinum("OBUFT:O,I,T")); - return tmp; - } - } - - // Can't seem to find a way to rearrange the existing netlist, - // so I am stuck creating a new buffer, the OBUF. - NetLogic*buf = new NetLogic(scope, scope->local_symbol(), - 2, NetLogic::BUF); - des->add_node(buf); - - buf->attribute(perm_string::literal("XNF-LCA"), verinum("OBUF:O,I")); - - // Put the buffer between this signal and the rest of the - // netlist. - connect(net->pin(0), buf->pin(1)); - net->pin(0).unlink(); - connect(net->pin(0), buf->pin(0)); - - // It is possible, in putting an OBUF between net and the rest - // of the netlist, to create a ring without a signal. Detect - // this case and create a new signal. - if (count_signals(buf->pin(1)) == 0) { - NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE); - tmp->local_flag(true); - connect(buf->pin(1), tmp->pin(0)); - } - - return buf; -} - -static void absorb_OFF(Design*des, NetLogic*buf) -{ - /* If the nexus connects is not a simple point-to-point link, - then I can't drag it into the IOB. Give up. */ - if (count_outputs(buf->pin(1)) != 1) - return; - if (count_inputs(buf->pin(1)) != 1) - return; - /* For now, only support OUTFF. */ - if (buf->type() != NetLogic::BUF) - return; - - Link*drv = find_next_output(&buf->pin(1)); - assert(drv); - - /* Make sure the device is a FF with width 1. */ - NetFF*ff = dynamic_cast(drv->get_obj()); - if (ff == 0) - return; - if (ff->width() != 1) - return; - if (ff->attribute(perm_string::literal("LPM_FFType")) != verinum("DFF")) - return; - - /* Connect the flip-flop output to the buffer output and - delete the buffer. The XNF OUTFF can buffer the pin. */ - connect(ff->pin_Q(0), buf->pin(0)); - delete buf; - - /* Finally, build up an XNF-LCA value that defines this - devices as an OUTFF and gives each pin an XNF name. */ - char**names = new char*[ff->pin_count()]; - for (unsigned idx = 0 ; idx < ff->pin_count() ; idx += 1) - names[idx] = ""; - - if (ff->attribute(perm_string::literal("Clock:LPM_Polarity")) == verinum("INVERT")) - names[ff->pin_Clock().get_pin()] = "~C"; - else - names[ff->pin_Clock().get_pin()] = "C"; - - names[ff->pin_Data(0).get_pin()] = "D"; - names[ff->pin_Q(0).get_pin()] = "Q"; - - string lname = string("OUTFF:") + names[0]; - for (unsigned idx = 1 ; idx < ff->pin_count() ; idx += 1) - lname = lname + "," + names[idx]; - delete[]names; - - ff->attribute(perm_string::literal("XNF-LCA"), lname); -} - -static void make_ibuf(Design*des, NetNet*net) -{ - NetScope*scope = net->scope(); - assert(scope); - - assert(net->pin_count() == 1); - // XXXX For now, require at least one input. - assert(count_inputs(net->pin(0)) > 0); - - /* Look for an existing BUF connected to this signal and - suitably connected that I can use it as an IBUF. */ - - Nexus*nex = net->pin(0).nexus(); - for (Link*idx = nex->first_nlink() - ; idx ; idx = idx->next_nlink()) { - NetLogic*tmp; - if ((tmp = dynamic_cast(idx->get_obj())) == 0) - continue; - - if (tmp->attribute(perm_string::literal("XNF-LCA")) != verinum()) - continue; - - // Found a BUF, it is only usable if the only input is - // the signal and there are no other inputs. - if ((tmp->type() == NetLogic::BUF) && - (count_inputs(tmp->pin(1)) == 1) && - (count_outputs(tmp->pin(1)) == 0)) { - tmp->attribute(perm_string::literal("XNF-LCA"), verinum("IBUF:O,I")); - return; - } - - } - - // I give up, create an IBUF. - NetLogic*buf = new NetLogic(scope, scope->local_symbol(), - 2, NetLogic::BUF); - des->add_node(buf); - - buf->attribute(perm_string::literal("XNF-LCA"), verinum("IBUF:O,I")); - - // Put the buffer between this signal and the rest of the - // netlist. - connect(net->pin(0), buf->pin(0)); - net->pin(0).unlink(); - connect(net->pin(0), buf->pin(1)); - - // It is possible, in putting an OBUF between net and the rest - // of the netlist, to create a ring without a signal. Detect - // this case and create a new signal. - if (count_signals(buf->pin(0)) == 0) { - NetNet*tmp = new NetNet(scope, - scope->local_symbol(), - NetNet::WIRE); - connect(buf->pin(0), tmp->pin(0)); - } -} - -void xnfio_f::signal(Design*des, NetNet*net) -{ - if (! is_a_pad(net)) - return; - - assert(net->pin_count() == 1); - string pattr = net->attribute(perm_string::literal("PAD")).as_string(); - - switch (pattr[0]) { - case 'i': - case 'I': - make_ibuf(des, net); - break; - case 'o': - case 'O': { - NetLogic*buf = make_obuf(des, net); - if (buf == 0) break; - absorb_OFF(des, buf); - break; - } - - // FIXME: Only IPAD and OPAD supported. Need to - // add support for IOPAD. - default: - assert(0); - break; - } -} - -/* - * Attempt some XNF specific optimizations on comparators. - */ -void xnfio_f::lpm_compare(Design*des, NetCompare*dev) -{ - if (compare_sideb_const(des, dev)) - return; - - return; -} - -bool xnfio_f::compare_sideb_const(Design*des, NetCompare*dev) -{ - /* Even if side B is all constant, if there are more than 4 - signals on side A we will not be able to fit the operation - into a function unit, so we might as well accept a - comparator. Give up. */ - if (dev->width() > 4) - return false; - - NetScope*scope = dev->scope(); - - verinum side (verinum::V0, dev->width()); - - /* Is the B side all constant? */ - for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) { - - if (! dev->pin_DataB(idx).nexus()->drivers_constant()) - return false; - - side.set(idx, dev->pin_DataB(idx).nexus()->driven_value()); - } - - /* Handle the special case of comparing A to 0. Use an N-input - NOR gate to return 0 if any of the bits is not 0. */ - if ((side.as_ulong() == 0) && (count_inputs(dev->pin_AEB()) > 0)) { - NetLogic*sub = new NetLogic(scope, dev->name(), dev->width()+1, - NetLogic::NOR); - connect(sub->pin(0), dev->pin_AEB()); - for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) - connect(sub->pin(idx+1), dev->pin_DataA(idx)); - delete dev; - des->add_node(sub); - return true; - } - - /* Handle the special case of comparing A to 0. Use an N-input - NOR gate to return 0 if any of the bits is not 0. */ - if ((side.as_ulong() == 0) && (count_inputs(dev->pin_ANEB()) > 0)) { - NetLogic*sub = new NetLogic(scope, dev->name(), dev->width()+1, - NetLogic::OR); - connect(sub->pin(0), dev->pin_ANEB()); - for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) - connect(sub->pin(idx+1), dev->pin_DataA(idx)); - delete dev; - des->add_node(sub); - return true; - } - - return false; -} - -void xnfio(Design*des) -{ - xnfio_f xnfio_obj; - des->functor(&xnfio_obj); -} - -/* - * $Log: xnfio.cc,v $ - * Revision 1.30 2007/03/22 16:08:18 steve - * Spelling fixes from Larry - * - * Revision 1.29 2004/02/20 18:53:36 steve - * Addtrbute keys are perm_strings. - * - * Revision 1.28 2004/02/18 17:11:58 steve - * Use perm_strings for named langiage items. - * - * Revision 1.27 2003/06/24 01:38:03 steve - * Various warnings fixed. - * - * Revision 1.26 2003/03/06 00:28:42 steve - * All NetObj objects have lex_string base names. - * - * Revision 1.25 2003/01/30 16:23:08 steve - * Spelling fixes. - * - * Revision 1.24 2003/01/14 21:16:18 steve - * Move strstream to ostringstream for compatibility. - * - * Revision 1.23 2002/08/12 01:35:01 steve - * conditional ident string using autoconfig. - * - * Revision 1.22 2002/06/25 01:33:22 steve - * Cache calculated driven value. - * - * Revision 1.21 2002/06/24 01:49:39 steve - * Make link_drive_constant cache its results in - * the Nexus, to improve cprop performance. - * - * Revision 1.20 2002/05/23 03:08:52 steve - * Add language support for Verilog-2001 attribute - * syntax. Hook this support into existing $attribute - * handling, and add number and void value types. - * - * Add to the ivl_target API new functions for access - * of complex attributes attached to gates. - * - * Revision 1.19 2001/10/20 05:21:51 steve - * Scope/module names are char* instead of string. - * - * Revision 1.18 2001/07/25 03:10:50 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.17 2000/11/20 00:58:40 steve - * Add support for supply nets (PR#17) - * - * Revision 1.16 2000/10/07 19:45:43 steve - * Put logic devices into scopes. - * - * Revision 1.15 2000/06/25 19:59:42 steve - * Redesign Links to include the Nexus class that - * carries properties of the connected set of links. - * - * Revision 1.14 2000/05/07 04:37:56 steve - * Carry strength values from Verilog source to the - * pform and netlist for gates. - * - * Change vvm constants to use the driver_t to drive - * a constant value. This works better if there are - * multiple drivers on a signal. - * - * Revision 1.13 2000/05/02 00:58:12 steve - * Move signal tables to the NetScope class. - * - * Revision 1.12 2000/04/20 00:28:03 steve - * Catch some simple identity compareoptimizations. - * - * Revision 1.11 2000/02/23 02:56:56 steve - * Macintosh compilers do not support ident. - * - * Revision 1.10 1999/12/11 05:45:41 steve - * Fix support for attaching attributes to primitive gates. - * - * Revision 1.9 1999/11/27 19:07:58 steve - * Support the creation of scopes. - * - * Revision 1.8 1999/11/19 05:02:15 steve - * Handle inverted clock into OUTFF. - * - * Revision 1.7 1999/11/19 03:02:25 steve - * Detect flip-flops connected to opads and turn - * them into OUTFF devices. Inprove support for - * the XNF-LCA attribute in the process. - * - * Revision 1.6 1999/11/18 02:58:37 steve - * Handle (with a warning) unconnected opads. - * - * Revision 1.5 1999/11/02 04:55:01 steve - * repair the sense of T from bufif01 - * - * Revision 1.4 1999/11/02 01:43:55 steve - * Fix iobuf and iobufif handling. - * - * Revision 1.3 1999/10/09 17:52:27 steve - * support XNF OBUFT devices. - * - * Revision 1.2 1999/07/17 22:01:14 steve - * Add the functor interface for functor transforms. - * - * Revision 1.1 1998/12/07 04:53:17 steve - * Generate OBUF or IBUF attributes (and the gates - * to garry them) where a wire is a pad. This involved - * figuring out enough of the netlist to know when such - * was needed, and to generate new gates and signales - * to handle what's missing. - * - */ - From e4411777ed855f09a6bdf30c69aeb75804dceb68 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 2 Sep 2008 18:38:04 -0700 Subject: [PATCH 10/12] Remove unused net_force.cc source file. --- Makefile.in | 2 +- net_force.cc | 82 ---------------------------------------------------- 2 files changed, 1 insertion(+), 83 deletions(-) delete mode 100644 net_force.cc diff --git a/Makefile.in b/Makefile.in index c5432c351..6fb8b38d1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -104,7 +104,7 @@ elab_lval.o elab_net.o elab_pexpr.o elab_scope.o \ elab_sig.o emit.o eval.o eval_attrib.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ load_module.o netlist.o netmisc.o net_assign.o \ -net_design.o net_event.o net_expr.o net_force.o net_func.o \ +net_design.o net_event.o net_expr.o net_func.o \ net_link.o net_modulo.o net_nex_input.o net_nex_output.o \ net_proc.o net_scope.o net_tran.o net_udp.o pad_to_width.o \ parse.o parse_misc.o pform.o pform_analog.o pform_disciplines.o \ diff --git a/net_force.cc b/net_force.cc deleted file mode 100644 index 3707bab39..000000000 --- a/net_force.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2000-2004 Stephen Williams (steve@picturel.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 - */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: net_force.cc,v 1.13 2004/12/11 02:31:26 steve Exp $" -#endif - -# include "config.h" -# include "compiler.h" - -/* - * This file contains implementation of the NetForce, NetRelease, - * NetCAssign and NetDeassign classes. These are similar or related in - * that they handle the procedural continuous assign and force - * statements. - */ - -# include "netlist.h" -# include - - -/* - * $Log: net_force.cc,v $ - * Revision 1.13 2004/12/11 02:31:26 steve - * Rework of internals to carry vectors through nexus instead - * of single bits. Make the ivl, tgt-vvp and vvp initial changes - * down this path. - * - * Revision 1.12 2004/02/18 17:11:56 steve - * Use perm_strings for named langiage items. - * - * Revision 1.11 2003/03/06 00:28:41 steve - * All NetObj objects have lex_string base names. - * - * Revision 1.10 2003/01/27 05:09:17 steve - * Spelling fixes. - * - * Revision 1.9 2002/08/19 00:06:12 steve - * Allow release to handle removal of target net. - * - * Revision 1.8 2002/08/12 01:34:59 steve - * conditional ident string using autoconfig. - * - * Revision 1.7 2002/01/19 19:02:08 steve - * Pass back target errors processing conditionals. - * - * Revision 1.6 2001/11/14 03:28:49 steve - * DLL target support for force and release. - * - * Revision 1.5 2001/10/31 05:24:52 steve - * ivl_target support for assign/deassign. - * - * Revision 1.4 2001/10/28 01:14:53 steve - * NetObj constructor finally requires a scope. - * - * Revision 1.3 2001/07/25 03:10:49 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.2 2000/05/12 01:22:41 steve - * NetCAssign needs to incr_eref its lval to lock it down. - * - * Revision 1.1 2000/05/11 23:37:27 steve - * Add support for procedural continuous assignment. - * - */ - From 60169f6353479897e4fe82ffe1af2fc2a5a18f5e Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 3 Sep 2008 17:59:39 -0700 Subject: [PATCH 11/12] Get generate block scope from generate case. The generate block is a placeholder for the generate items, and it is the items themselves that can specify the name of the generate block that is created. --- elab_scope.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elab_scope.cc b/elab_scope.cc index 5df05b7bc..8e104b5da 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -621,9 +621,6 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container) return false; } - // The name of the scope to generate, whatever that item is. - hname_t use_name (scope_name); - if (debug_scopes) cerr << get_fileline() << ": debug: Generate case " << "switch value=" << case_value_co->value() << endl; @@ -673,6 +670,9 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container) << "Generate case matches item at " << item->get_fileline() << endl; + // The name of the scope to generate, whatever that item is. + hname_t use_name (item->scope_name); + NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); From 7beb059d90bc4b465db4fa00ed775c62f71b2a69 Mon Sep 17 00:00:00 2001 From: Cary R Date: Wed, 3 Sep 2008 16:05:12 -0700 Subject: [PATCH 12/12] Add blocking repeat event control, make repeat sign aware This patch adds blocking repeat event controls and also makes the base repeat statement sign aware. If the argument to repeat is negative (it must be a signed variable) then this is treated just like an argument of 0 (there is no looping). Doing this allows us to model the repeat event control as follows. lhs = repeat(count) @(event) rhs; is translated to: begin temp = rhs; repeat (count) @(event); lhs = temp; end This patch also pushes the non-blocking event control information to the elaboration phase where it will report they are not currently supported. --- Statement.cc | 57 +++++------------------- Statement.h | 11 ++++- elaborate.cc | 100 +++++++++++++++++++++++++++++++++++------- parse.y | 13 ++---- pform_dump.cc | 39 +++++++++++++--- tgt-vvp/vvp_process.c | 5 ++- 6 files changed, 144 insertions(+), 81 deletions(-) diff --git a/Statement.cc b/Statement.cc index 02680d322..a8c9b9627 100644 --- a/Statement.cc +++ b/Statement.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2008 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 @@ -16,9 +16,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $" -#endif # include "config.h" @@ -30,19 +27,19 @@ Statement::~Statement() } PAssign_::PAssign_(PExpr*lval, PExpr*ex) -: event_(0), lval_(lval), rval_(ex) +: event_(0), count_(0), lval_(lval), rval_(ex) { delay_ = 0; } PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex) -: event_(0), lval_(lval), rval_(ex) +: event_(0), count_(0), lval_(lval), rval_(ex) { delay_ = de; } -PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex) -: event_(ev), lval_(lval), rval_(ex) +PAssign_::PAssign_(PExpr*lval, PExpr*cnt, PEventStatement*ev, PExpr*ex) +: event_(ev), count_(cnt), lval_(lval), rval_(ex) { delay_ = 0; } @@ -63,8 +60,8 @@ PAssign::PAssign(PExpr*lval, PExpr*d, PExpr*ex) { } -PAssign::PAssign(PExpr*lval, PEventStatement*d, PExpr*ex) -: PAssign_(lval, d, ex) +PAssign::PAssign(PExpr*lval, PExpr*cnt, PEventStatement*d, PExpr*ex) +: PAssign_(lval, cnt, d, ex) { } @@ -82,6 +79,11 @@ PAssignNB::PAssignNB(PExpr*lval, PExpr*d, PExpr*ex) { } +PAssignNB::PAssignNB(PExpr*lval, PExpr*cnt, PEventStatement*d, PExpr*ex) +: PAssign_(lval, cnt, d, ex) +{ +} + PAssignNB::~PAssignNB() { } @@ -298,38 +300,3 @@ PWhile::~PWhile() delete cond_; delete statement_; } - -/* - * $Log: Statement.cc,v $ - * Revision 1.30 2007/05/24 04:07:11 steve - * Rework the heirarchical identifier parse syntax and pform - * to handle more general combinations of heirarch and bit selects. - * - * Revision 1.29 2004/02/18 17:11:54 steve - * Use perm_strings for named langiage items. - * - * Revision 1.28 2002/08/12 01:34:58 steve - * conditional ident string using autoconfig. - * - * Revision 1.27 2002/04/21 22:31:02 steve - * Redo handling of assignment internal delays. - * Leave it possible for them to be calculated - * at run time. - * - * Revision 1.26 2002/04/21 04:59:07 steve - * Add support for conbinational events by finding - * the inputs to expressions and some statements. - * Get case and assignment statements working. - * - * Revision 1.25 2001/12/03 04:47:14 steve - * Parser and pform use hierarchical names as hname_t - * objects instead of encoded strings. - * - * Revision 1.24 2001/11/22 06:20:59 steve - * Use NetScope instead of string for scope path. - * - * Revision 1.23 2001/07/25 03:10:48 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - */ - diff --git a/Statement.h b/Statement.h index 5bca41739..bcc033937 100644 --- a/Statement.h +++ b/Statement.h @@ -93,7 +93,7 @@ class PAssign_ : public Statement { public: explicit PAssign_(PExpr*lval, PExpr*ex); explicit PAssign_(PExpr*lval, PExpr*de, PExpr*ex); - explicit PAssign_(PExpr*lval, PEventStatement*de, PExpr*ex); + explicit PAssign_(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex); virtual ~PAssign_() =0; const PExpr* lval() const { return lval_; } @@ -104,6 +104,7 @@ class PAssign_ : public Statement { PExpr* delay_; PEventStatement*event_; + PExpr* count_; private: PExpr* lval_; @@ -115,7 +116,7 @@ class PAssign : public PAssign_ { public: explicit PAssign(PExpr*lval, PExpr*ex); explicit PAssign(PExpr*lval, PExpr*de, PExpr*ex); - explicit PAssign(PExpr*lval, PEventStatement*de, PExpr*ex); + explicit PAssign(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex); ~PAssign(); virtual void dump(ostream&out, unsigned ind) const; @@ -129,6 +130,7 @@ class PAssignNB : public PAssign_ { public: explicit PAssignNB(PExpr*lval, PExpr*ex); explicit PAssignNB(PExpr*lval, PExpr*de, PExpr*ex); + explicit PAssignNB(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex); ~PAssignNB(); virtual void dump(ostream&out, unsigned ind) const; @@ -333,6 +335,9 @@ class PEventStatement : public Statement { void set_statement(Statement*st); virtual void dump(ostream&out, unsigned ind) const; + // Call this with a NULL statement only. It is used to print + // the event expression for inter-assignment event controls. + virtual void dump_inline(ostream&out) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; @@ -348,6 +353,8 @@ class PEventStatement : public Statement { Statement*statement_; }; +ostream& operator << (ostream&o, const PEventStatement&obj); + class PForce : public Statement { public: diff --git a/elaborate.cc b/elaborate.cc index f2927719e..e693f45d5 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1803,6 +1803,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const if (rv == 0) return 0; assert(rv); + if (count_) assert(event_); /* Rewrite delayed assignments as assignments that are delayed. For example, a = # b; becomes: @@ -1855,19 +1856,58 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const /* Generate the delay statement with the final assignment attached to it. If this is an event delay, elaborate the PEventStatement. Otherwise, create the - right NetPDelay object. */ + right NetPDelay object. For a repeat event control + repeat the event and then do the final assignment. */ NetProc*st; if (event_) { - st = event_->elaborate_st(des, scope, a2); - if (st == 0) { - cerr << event_->get_fileline() << ": error: " - "unable to elaborate event expression." - << endl; - des->errors += 1; - return 0; - } - assert(st); + if (count_) { + NetExpr*count = elab_and_eval(des, scope, count_, -1); + if (count == 0) { + cerr << get_fileline() << ": Unable to " + "elaborate repeat expression." << endl; + des->errors += 1; + return 0; + } + st = event_->elaborate(des, scope); + if (st == 0) { + cerr << event_->get_fileline() << ": error: " + "unable to elaborate event expression." + << endl; + des->errors += 1; + return 0; + } + // If the expression is a constant, handle + // certain special iteration counts. + if (NetEConst*ce = dynamic_cast(count)) { + long val = ce->value().as_long(); + // We only need the real statement. + if (val <= 0) { + delete count; + delete st; + st = 0; + + // We don't need the repeat statement. + } else if (val == 1) { + delete count; + + // We need a repeat statement. + } else { + st = new NetRepeat(count, st); + } + } else { + st = new NetRepeat(count, st); + } + } else { + st = event_->elaborate_st(des, scope, a2); + if (st == 0) { + cerr << event_->get_fileline() << ": error: " + "unable to elaborate event expression." + << endl; + des->errors += 1; + return 0; + } + } } else { NetPDelay*de = new NetPDelay(delay, a2); de->set_line(*this); @@ -1877,7 +1917,8 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const /* And build up the complex statement. */ NetBlock*bl = new NetBlock(NetBlock::SEQU, 0); bl->append(a1); - bl->append(st); + if (st) bl->append(st); + if (count_) bl->append(a2); return bl; } @@ -1948,6 +1989,34 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const if (delay_ != 0) delay = elaborate_delay_expr(delay_, des, scope); + if (count_ != 0 || event_ != 0) { + NetExpr*count = 0; + if (count_ != 0) { + assert(event_ != 0); + count = elab_and_eval(des, scope, count_, -1); + if (count == 0) { + cerr << get_fileline() << ": Unable to elaborate " + "repeat expression." << endl; + des->errors += 1; +// return 0; + } + } + + NetProc* event = event_->elaborate(des, scope); + if (event == 0) { + cerr << get_fileline() << ": unable to elaborate " + "event expression." << endl; + des->errors += 1; +// return 0; + } + + cerr << get_fileline() << ": sorry: non blocking "; + if (count_) cerr << "repeat "; + cerr << "event controls are not supported." << endl; + des->errors += 1; + return 0; + } + /* All done with this node. Mark its line number and check it in. */ NetAssignNB*cur = new NetAssignNB(lv, rv); cur->set_delay(delay); @@ -3195,17 +3264,14 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const // If the expression is a constant, handle certain special // iteration counts. if (NetEConst*ce = dynamic_cast(expr)) { - verinum val = ce->value(); - switch (val.as_ulong()) { - case 0: + long val = ce->value().as_long(); + if (val <= 0) { delete expr; delete stat; return new NetBlock(NetBlock::SEQU, 0); - case 1: + } else if (val == 1) { delete expr; return stat; - default: - break; } } diff --git a/parse.y b/parse.y index 015034559..4f02bafc7 100644 --- a/parse.y +++ b/parse.y @@ -3648,28 +3648,23 @@ statement $$ = tmp; } | lpvalue '=' event_control expression ';' - { PAssign*tmp = new PAssign($1,$3,$4); + { PAssign*tmp = new PAssign($1,0,$3,$4); FILE_NAME(tmp, @1); $$ = tmp; } | lpvalue '=' K_repeat '(' expression ')' event_control expression ';' - { PAssign*tmp = new PAssign($1,$7,$8); + { PAssign*tmp = new PAssign($1,$5,$7,$8); FILE_NAME(tmp,@1); tmp->set_lineno(@1.first_line); - yyerror(@3, "sorry: repeat event control not supported."); - delete $5; $$ = tmp; } | lpvalue K_LE event_control expression ';' - { yyerror(@1, "sorry: Event controls not supported here."); - PAssignNB*tmp = new PAssignNB($1,$4); + { PAssignNB*tmp = new PAssignNB($1,0,$3,$4); FILE_NAME(tmp, @1); $$ = tmp; } | lpvalue K_LE K_repeat '(' expression ')' event_control expression ';' - { yyerror(@1, "sorry: Event controls not supported here."); - delete $5; - PAssignNB*tmp = new PAssignNB($1,$8); + { PAssignNB*tmp = new PAssignNB($1,$5,$7,$8); FILE_NAME(tmp, @1); $$ = tmp; } diff --git a/pform_dump.cc b/pform_dump.cc index 2d3cc5fd1..cb35237e8 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -40,6 +40,12 @@ ostream& operator << (ostream&out, const PExpr&obj) return out; } +ostream& operator << (ostream&out, const PEventStatement&obj) +{ + obj.dump_inline(out); + return out; +} + ostream& operator << (ostream&o, const PDelays&d) { d.dump_delays(o); @@ -554,16 +560,20 @@ void AContrib::dump(ostream&out, unsigned ind) const void PAssign::dump(ostream&out, unsigned ind) const { - out << setw(ind) << ""; - out << *lval() << " = " << delay_ << " " << *rval() << ";"; - out << " /* " << get_fileline() << " */" << endl; + out << setw(ind) << "" << *lval() << " = "; + if (delay_) out << "#" << *delay_ << " "; + if (count_) out << "repeat(" << *count_ << ") "; + if (event_) out << *event_ << " "; + out << *rval() << ";" << " /* " << get_fileline() << " */" << endl; } void PAssignNB::dump(ostream&out, unsigned ind) const { - out << setw(ind) << ""; - out << *lval() << " <= " << delay_ << " " << *rval() << ";"; - out << " /* " << get_fileline() << " */" << endl; + out << setw(ind) << "" << *lval() << " <= "; + if (delay_) out << "#" << *delay_ << " "; + if (count_) out << "repeat(" << *count_ << ") "; + if (event_) out << *event_ << " "; + out << *rval() << ";" << " /* " << get_fileline() << " */" << endl; } void PBlock::dump(ostream&out, unsigned ind) const @@ -713,6 +723,23 @@ void PEventStatement::dump(ostream&out, unsigned ind) const } } +void PEventStatement::dump_inline(ostream&out) const +{ + assert(statement_ == 0); + + if (expr_.count() == 0) { + out << "@* "; + + } else { + out << "@(" << *(expr_[0]); + if (expr_.count() > 1) + for (unsigned idx = 1 ; idx < expr_.count() ; idx += 1) + out << " or " << *(expr_[idx]); + + out << ")"; + } +} + void PForce::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "force " << *lval_ << " = " << *expr_ diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 41220c832..302c1e3c4 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -1402,10 +1402,11 @@ static int show_stmt_repeat(ivl_statement_t net, ivl_scope_t sscope) unsigned lab_top = local_count++, lab_out = local_count++; ivl_expr_t exp = ivl_stmt_cond_expr(net); struct vector_info cnt = draw_eval_expr(exp, 0); + char *sign = ivl_expr_signed(exp) ? "s" : "u"; /* Test that 0 < expr */ - fprintf(vvp_out, "T_%u.%u %%cmp/u 0, %u, %u;\n", thread_count, - lab_top, cnt.base, cnt.wid); + fprintf(vvp_out, "T_%u.%u %%cmp/%s 0, %u, %u;\n", thread_count, + lab_top, sign, cnt.base, cnt.wid); clear_expression_lookaside(); fprintf(vvp_out, " %%jmp/0xz T_%u.%u, 5;\n", thread_count, lab_out); /* This adds -1 (all ones in 2's complement) to the count. */