Just as I was getting back into what I want to do with Icarus Verilog, I saw a message thread: [Iverilog-devel] Need Icarus test on a 64 bit machine.

As usual, I'll take you through my recent OpenSPARC/Icarus Verilog work, more or less in chronological order.

In What a Pain in the Ass!, I described my struggles with Git. I usually attend the Austin C/C++ Meetup, so I decided to ask the group "to help get me out of the mud and on my way".

Scott Wood of Freescale Semiconductor did just that.

Recall that I had felt that my local v0_8-branch needed to have my development removed. I had created my-v0_8-branch from this branch. Only then had I removed my development from v0_8-branch.

I had later become dissatisfied that my local v0_8-branch failed to track the central repository. "I began to suspect that the work I did on the local branch, v0_8-branch (i.e. to make it match the remote-tracking branch), was a waste of time and that that branch is not needed."

Scott Wood started by suggesting

git checkout v0_8-branch
git reset --hard my-v0_8-branch
git branch -d my-v0_8-branch

I agreed with his intention (i.e. to put my local v0_8-branch back the way it was before I began to remove my development from it and to then obsolete my-v0_8-branch), but it didn't quite work that way. Continue reading.

As part of the original instructions (i.e. without the benefit of any feedback from me yet), Scott had suggested, "Then, with no uncommited changes, and with your local v0_8-branch checked out, try git pull again." He also pointed out that
git log origin..HEAD
would show me a list of the commits that you have, which do not exist upstream.

It showed me at least one commit which could only have come from upstream. It also showed many commits by me that should have vanished with git-reset. By 2009-08-16, I was forced to conclude that
git reset --hard my-v0_8-branch
hadn't done what I expected.

git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]

"my-v0_8-branch" must not have represented the "<commit>" I was after.

"<commit>" is defined as "Commit to make the current HEAD. If not given defaults to HEAD." There's more in the Git documentation about that, omitted here for brevity.

According to my notes, my-v0_8-branch was created 2009-05-29. I used that date to find the commit to which I wanted to reset.

git reset --hard 222cc57

Building Icarus Verilog then failed with
gmake,1.0: *** No rule to make target `version.h', needed by `main.o'. Stop.


git pull
...
version.h | 4 +
...
create mode 100644 version.h
...


That fixed it. Icarus Verilog successfully compiled. Running "iverilog" looked good too (on the surface).

git log origin..HEAD
a list of the commits that you have, which do not exist upstream?

The commits by me that should have vanished with git-reset were now gone, but I still saw a lot of commits that didn't match the quote. What I really wanted was

git log origin/v0_8-branch..HEAD

That showed a more believable result, but included a surprise:


commit bb88bd2e73f161dabe05c1cf4465f6119dc71d7c
Author: Alan M. Feldstein
Date: Tue Oct 23 12:01:39 2007 -0500

Fixed dangling latch gate inputs.

With -tfnf, observed
(latch 43020 1 43022 43021)
in the output file. That 3rd number is the ID of the gate nexus.
However, it was only found as
(dangle 43022)
The purpose of this patch is to fix that in the common code.


I concluded that Steve Williams had failed to push that commit and accused him of that. He replied, "Your reasoning is not correct, there is no command you can execute to see patches that I did not push. The patch is definitely there on the v0_8-branch as commit 5cae6b64af9bd23ef69ae15dc08172c09fe6f8e8."

After speaking with Scott Wood at the August Austin C/C++ Meetup, I agreed with Steve, whose repository has no knowledge of my commits. All he gets from me are patches, which have that information stripped out.

On 2009-08-19, I submitted a patch of minor portability fixes. In Windows is a Difficult Platform on which to Develop Software, I had mentioned that "I still owe Steve a patch that fixes DEBUG on Windows." That's what this was.

There was something else that I owed Steve. As described in Latch gate patch bugs, Steve had reported almost two years ago that there had been some regressions. He had suspected my latch gate patch.

So I set out to try to reproduce the regression failures.

The regression test suite is the ivtest project. The files are stored in a git repository in github. See the Developer Guide for details on how to access the regression test suite.

jesus% ./vvp_reg.pl
Failed to get version from iverilog -V output at perl-lib/Environment.pm line 86.
jesus% iverilog -V
tmpdir is /tmp
tmpdir is /tmp
Icarus Verilog version 0.8.6 ($Name: $)
Copyright 1998-2003 Stephen Williams
...

I suspected that the problem was the verbosity I had added before the line containing the version number, but for the moment I was confused because I thought I had removed that verbosity.

Next, I performed a git-pull, which resulted in a conflict in driver/main.c. Steve had accepted my changes (i.e. minor portability fixes) but made slight modifications. I accepted his modifications in order to get in sync.

I found that I was not affecting
/usr/local/bin/iverilog
when I install!

Here's the culprit:


git log driver/Makefile.in

commit 146f64992c8d287ed91f17bb0b33ee94875a6545
Author: Stephen Williams
Date: Wed Nov 19 22:39:10 2008 -0800

Create support for the --enable-suffix configuration option.

This configure option causes the installed commands to have
a suffix string that makes them distinct from other versions
that also have a suffix string. This allows for multiple
installed versions of Icarus Verilog.

Also, move installed C/C++ header files into a subdirectory of
their own under the target include directory, to make clearer
the purpose and source of those files.

(cherry picked from commit 4bc90f7cfdcee80e23ddc700959c79ae73aefaa2)


Not only did Steve do that (without telling me), he also made enable-suffix the default. As a result, I have been affecting
/usr/local/bin/iverilog-0.8

Recall that "Synthesis is still pretty much relegated to the 0.8 branch..."

jesus% iverilog-0.8 -v -tfnf -I$DV_ROOT/design/sys/iop/include -cFlist.iop_top -g2 -sOpenSPARCT1 $DV_ROOT/lib/u1/u1.behV $DV_ROOT/design/sys/iop/common/rtl/swrvr_clib.v
Icarus Verilog version 0.8.7

Copyright 1998-2009 Stephen Williams
...
ERROR: Unable to read config file: /usr/local/lib/ivl-0.8/fnf.conf
...

Note the newer version and copyright, but now there was a minor issue with the FNF Icarus code generator, caused by the enable-suffix default.

I ensured that I could still checkout Confluence from the Cosmic Horizon CVS repository, and that I could build its FNF Icarus code generator from source. Solving the above problem was then simply a matter of copying fnf.conf and fnf.tgt to the ivl-0.8 directory.

Now it seemed that I had returned to the leading edge of progress.

jesus% ./vvp_reg.pl --suffix=-0.8

The Perl program hung. Analysis of related processes revealed that gdb had been launched. The root cause of this problem was
gmake DEBUGFLAGS=-DDEBUG

That is, building Icarus Verilog with DEBUG defined is incompatible with the regression test suite because that type of build (my usual mode of operation) loads ivl into gdb and stops at the (gdb) prompt.

Once I got the regression running, I saw some differences between the output file "regression_report.txt" and the "regression_report-v0.8.txt" file, but not the same differences that Steve had reported two years ago. For several tests, I updated ivtest/regression_report-v0.8.txt to be consistent with ivtest/regress.list. Then, I debugged two test failures (fdisplay_fail_fd and fdisplay_fail_mcd) down to a suspicious commit by Cary R that led me communicate with him about missing gold files. He fixed that and more.

Rerunning the regression, I still found a few differences and on 2009-08-29, I submitted a patch to Steve Williams to fix those.

But what ever happened to the differences reported by Steve on 2007-10-26? I reviewed those tests and found that their results matched current expectations. So I sent email to Steve stating that I must conclude that you have no further issues with my 2007-10-23 patch.

What now? I reviewed past milestones to figure that out:


2007-04-11: Asynchronous if statement is missing the else clause.

looking at Steve's synthesis code, near the procedural
assignment lvalue that needs to become a latch

the decision against NetMemory instantiation, it had
been made during the Verilog elaboration phase
... pinpointed that decision

get back to the synthesis code

2007-07-08:

(latch 43020 1 43022 43021)

That 3rd number is the ID of the gate nexus. However,
it is only found as
(dangle 43022)

2007-07-18: OpenSPARC progress toward FSS

There is likely more work to be done on the common
Icarus Verilog code to get good FNF. If so, you should see
another Icarus Verilog contribution from me in the future.

2007-07-19:

Look at emitting nodes for a latch in detail.

2007-07-23:

I'm not doing enough in function
dll_target::lpm_latch

Set the gate signal to point to the nexus, and the
nexus to point back to this device.

2007-10-23:

Fixed-dangling-latch-gate-inputs.patch


On 2009-08-31, I wrote the following reasoning in my notes:


At this point, I have two choices. I could either take a low-level approach or a high-level one.

A low-level approach would start with understanding
(latch 43020 1 43022 43021)
I must have understood it at one time. With this approach, I'd be digging for a problem that may or may not exist. I don't recall that FNF semantics are documented anywhere. Of course, it would be useful to understand its semantics, but I'm not thrilled about the method of gaining that understanding. Besides, that understanding may not be timely. Why do I need to know now? For completeness however, creation of a latch synthesis regression test for Icarus Verilog makes sense. How do I know that doesn't already exist? Such a regression test would need to avoid FNF, giving me the choice of using a target that doesn't interest me, or verifying Icarus Verilog after ELABORATING DESIGN but before CODE GENERATION. What about RUNNING FUNCTORS? See
/usr/local/lib/ivl-0.8/fnf.conf

A high-level approach would start with the error messages, which now have nothing to do with latch synthesis (whose known issues have been eliminated). In other words, I'd definitely be moving forward. This would get me quicker to Nathan Cain built an a FNF-to-JHDL translator. It comes with the last release of Confluence (0.10.6). Once translated to JHDL, either the latches work or they don't. This approach is appealing because it gets me to the fun stuff quicker.

Fun is not a good reason for choosing one approach over another. I wish I could create a regression test that involves FNF. I really feel that the right thing to do is to (1) satisfy myself that the FNF is correct and (2) create a latch synthesis regression test for Icarus Verilog that avoids FNF and avoids any target that doesn't interest me.


As I wrote in [Iverilog-devel] OpenSPARC T1 Verilog RTL, the latch in OpenSPARC T1 I've been examining is in module bw_u1_scanlg_2x, which may be found in OpenSPARCT1.1.6 at
$DV_ROOT/lib/u1/u1.behV:3858


/////////////// Scan data lock up latch ///////////////

module bw_u1_scanlg_2x (so, sd, ck, se);
output so;
input sd, ck, se;

reg so_l;

assign so = ~so_l;
always @ ( ck or sd or se )
if (~ck) so_l <= ~(sd & se) ;

endmodule


The FNF Icarus code generator currently produces


(scope "bw_u1_scanlg_2x" "so_lockup" (
(name 43009 "ck" 1 2438)
(name 43010 "sd" 1 42881)
(name 43011 "se" 1 18650)
(name 43012 "so" 1 29150)
(name 43014 "so_l" 1 43013)
(name 43016 "_s6" 1 43015)
(name 43017 "_s9" 1 2437)
(name 43019 "_s11" 1 43018)
(not 29150 1 43013)
(not 43015 1 2438)
(not 43018 1 2437)
(latch 43020 1 43022 43021)
(select 43023 1 0 43020)
))


On 2007-05-24, I had drawn the following diagram:

diagram from FNF

Note, for example, that _s6 does not appear to be connected to the latch gate. I have reason to suspect that the FNF is wrong, so I was right to take this low-level approach.

My intention is to follow the ck signal in, and find out why it doesn't reach the latch. I started by examining function build_hierarchy in the FNF Icarus code generator and concluded that nexus id 43015 is driven by the not gate.

On 2009-09-02, I wanted to use gdb and thought it might be nice to have the documentation open for reference. I had gdb 6.6 installed, but GNU makes only one version of the manual easy to find, presumably for the latest version (6.8). So I wanted to update gdb. To build gdb, I was advised to set the CC environment variable if I have more than one compiler installed. Preferring to use Sun Studio, I found that I have Sun Studio 11 installed. The latest is Sun Studio 12, Update 1. However, the release notes for Sun Studio 12 Update 1 state that Solaris 10 1/06 or later is required. My development platform currently has Solaris 10 3/05. Not having a compelling reason to update the operating system, I decided to put Sun Studio 12 Update 1 on the back burner.

By deciding that, I was deciding to build gdb 6.8 with Sun Studio 11. (By the way, I understand that gdb 6.6 probably includes documentation, but I wanted to benefit from any improvements that come with gdb 6.8.) I ran into some trouble with undefined symbols and found help here. Removal of package SMCncurs allowed for a successful build of gdb 6.8.

I got gdb to stop at a breakpoint on an interesting line of code inside function build_hierarchy, but then...

Now that I'm once again spending a reasonable amount of time on OpenSPARC (or Icarus Verilog depending on your point of view), I'm subscribed to the iverilog-devel forum. There, a discussion of Need Icarus test on a 64 bit machine caught my eye. That's when I opened my big mouth: "I have Solaris/SPARC machines available. That's a 64-bit platform."

Rather than take me up on my VPN offer, words from other members of the Icarus Verilog development community were of the following nature: "Building and testing on 64bit Solaris/SPARC would be a good thing ... If we were going to use a SPARC [perhaps] Alan was going to take care of this." This was followed by guidance about how I might go about taking care of this.

The plan is to create a procedure for regression testing, then to convert the procedure into automation (e.g. a Perl program initiated by cron at times when system utilization is typically low). And hopefully I will have the good sense to excuse myself if this work detracts my attention too much from Cosmic Horizon's OpenSPARC objectives.

Switching to v0_9-branch, the first problem was that Makefile tries to send -Wall to the Sun Studio 11 C compiler. (Recall that I had set the CC environment variable to build gdb.) Of course, I could easily make this problem go away. But my style favors solving problems rather than working around them. Besides, the stated goal of the Icarus Verilog development community is "building and testing on 64bit Solaris/SPARC". Sun Studio is not atypical on this development platform.

In order to improve the Icarus Verilog build system so that it doesn't make such severe assumptions about the compiler, it was necessary for me to learn more about GNU Autoconf. I started by ordering GNU Autoconf, Automake and Libtool. While waiting for that book to arrive, I dug in with the documentation and drew a picture.

I also set the CXX environment variable to point to the Sun Studio 11 C++ compiler. And I fixed -Wall for both compilers.

I don't know why there was no complaint from Sun Studio 11 about the apparently undocumented -MD option, but there is -xM in Sun Studio to output makefile dependency information.

jesus% gmake
mkdir dep
/space/opt/SUNWspro/bin/CC -DHAVE_CONFIG_H -I. -I. -g -xM -c main.cc -o main.o
CC: Suffix mismatch between -o and produced file (should produce .i)
gmake: *** [main.o] Error 1
jesus%

I would call this a bug in Sun Studio 11. The documentation does not suggest that -xM implies -E (run only the preprocessor). New options in Sun Studio 12 seem to fix the bug:

-xMD Generates makefile dependencies, including compilation.
-xMF Specifies a filename for makefile-dependency output.

The Sun Studio 12, Update 1 release notes state that Solaris OS 10 1/06 and subsequent updates is required. As I said, my development platform currently has Solaris 10 3/05. Now I have a compelling reason to update the operating system. I already have the Solaris 10 10/08 media, so that's the plan.

I had to do some work (and spend a little money) to get a reliable ASCII terminal connected to the serial management port of the development machine (a Sun Fire V210 server). While awaiting the arrival of some hardware, I went back to what I had been doing.

I had gotten gdb to stop at a breakpoint on an interesting line of code inside function build_hierarchy.

But Git wouldn't let me go back to v0_8-branch without first dealing with the local changes that I had made for v0_9-branch to support Sun Studio. I chose to add and commit, guessing (can't fully test yet) what will be needed for Sun Studio 12.

Back on v0_8-branch


jesus% gmake DEBUGFLAGS=-DDEBUG
mkdir dep
/space/opt/SUNWspro/bin/CC -DHAVE_CVS_IDENT=1 -DHAVE_CONFIG_H -I. -I. -Wall -Wall -g -O0 -MD -c main.cc -o main.o -DDEBUG
CC: Warning: Option -Wall passed to ld, if ld is invoked, ignored otherwise
CC: Warning: Option -Wall passed to ld, if ld is invoked, ignored otherwise
mv main.d dep/main.d
mv: cannot stat `main.d': No such file or directory
gmake: *** [main.o] Error 1
jesus%

At this point, v0_8-branch was in worse shape than v0_9-branch with respect to Sun Studio. So I used
git cherry-pick
to get some specific commits. There were some conflicts, which I resolved.

I then needed to remove the definitions of CC and CXX from
$HOME/.login
until I have Sun Studio 12 installed.

Before running configure, I've been setting environment variable CXXFLAGS to
-Wall -g -O0
I think I might want to stop doing that. For one thing, I was often seeing -Wall twice on command lines. Also, note that configure.in uses the AC_PROG_CXX macro. According the Autoconf manual, this macro causes the following behavior:

If using the GNU C++ compiler, set shell variable GXX to yes. If output variable CXXFLAGS was not already set, set it to -g -O2 for the GNU C++ compiler (-O2 on systems where G++ does not accept -g), or -g for other compilers.

I think I was trying to override
-Wall -g -O2
with
-Wall -g -O0

If I would just leave CXXFLAGS alone, I would get the default behavior. Perhaps I shouldn't be so afraid of -O2 for debugging. At least, it's worth another try.

As for -Wall, I guess something (CXXFLAGS?) was previously including the -Wall and I was simply preserving it. This theory suggests that "something" no longer includes -Wall by default, so I need not preserve it. The -Wall seems to come from elsewhere, so my attempt at preservation actually causes duplication.

I'll leave CXXFLAGS alone.

Once again, I had gotten gdb to stop at a breakpoint on an interesting line of code inside function build_hierarchy. On 2009-09-18, I was doing that again, and using a conditional breakpoint to ensure that I was on the right Verilog module, bw_u1_scanlg_2x. The first breakpoint hit landed on the wrong NOT gate. The second hit was right. I wanted the NOT gate corresponding to "~ck". From what I can tell, the nexus connected to the output of that NOT gate has ID 43015 and name "_s6". Most important is the question of where that nexus connects downstream. It should connect to the latch's gate.

I was studying the structure declaration with tag "ivl_nexus_ptr_s" in t-dll.h when the ASCII terminal hardware arrived. By 2009-09-22, I had in place what seems to be a reliable terminal.

In preparation for a Solaris upgrade of my development platform (jesus), I backed up to tape.

I shut down Solaris and attempted to boot from the Solaris 10 10/08 DVD. jesus doesn't see the external DVD-ROM drive, which is connected to USB. Without Solaris running, the USB driver is absent. So I ordered the internal DVD-ROM drive option from Sun. The expected arrival date is 2009-10-14.

While awaiting that hardware, I returned to gdb and my study of ivl_nexus_ptr_s.