"And hopefully I will have the good sense to excuse myself [from building and testing Icarus Verilog on 64bit Solaris/SPARC] if this work detracts my attention too much from Cosmic Horizon's OpenSPARC objectives."

Let me take you from my last Icarus Verilog blog item up to the present.

I installed autoconf only to find that autom4te was needed too. That is

jesus% ./autoconf.sh
Autoconf in root...
/usr/local/bin/autoconf: /usr/local/bin/autom4te: not found
...

But

jesus% which autom4te
/usr/local/bin/autom4te
jesus%

That seems just a little bit contradictory.

Note the shebang in /usr/local/bin/autom4te:
#! /usr/local/bin/perl -w

There was no Perl there, so I created a symbolic link. That got me further.

jesus% ./autoconf.sh
Autoconf in root...
autom4te: need GNU m4 1.4 or later: /usr/local/bin/m4
...

To solve that, I got m4-1.4.12-sol10-sparc-local.gz (and its dependencies) from sunfreeware.com.

jesus% ./autoconf.sh
Autoconf in root...
...
Autoconf in cadpli...
Precompiling lexor_keyword.gperf
./autoconf.sh: gperf: not found
jesus%

To solve that, I got gperf-3.0.3-sol10-sparc-local.gz from sunfreeware.com.

And that allowed me to get through autoconf.sh!

jesus% ./configure –without-ipal
configure: WARNING: you should use --build, --host, --target
configure: WARNING: invalid host type: –without-ipal
checking build system type... Invalid configuration `–without-ipal': machine `–without' not recognized
configure: error: /bin/bash ./config.sub –without-ipal failed
jesus%

At that point, I had only restored my local Git repository from tape and wondered which branch I was on. It was time to install Git.

I got git-1.6.2.1-sol10-sparc-local.gz (and its dependencies) from sunfreeware.com. That put me in Git dependency hell for a while. And along the way, I had some SSH configuration to perform. I'll spare you the details (you probably think I never do that).

It was 2010-01-18 before I was able to attempt posing the question, "Which branch am I on?"

jesus% git branch
ld.so.1: git: fatal: libiconv.so.2: open failed: No such file or directory
Killed
jesus%

I still had some Git dependency issues to solve. Fast-forward.

jesus% git branch
fatal: Not a git repository (or any of the parent directories): .git
jesus%

Your repository in git is stored right alongside your working tree in a directory called .git. The git init command sets up a directory called .git that stores all the repository metadata and
~/git/icarus_verilog/
serves as the working tree of code you have checked out from the repository.

jesus% pwd
/home/alan/git/icarus_verilog
jesus% ls -ald .git
.git: No such file or directory
jesus%

So I needed to restore the .git directory from tape.

jesus% git branch
* (no branch)
master
v0_8-branch
v0_9-branch
jesus%

That's better.

Before telling Steve Williams "no" and getting back to OpenSPARC, I needed to find out where I was and deliver what I had so far.

jesus% git checkout v0_9-branch
Previous HEAD position was 95a0fac... Minor portability fixes from Alan Feldstein.
error: You have local changes to 'autoconf.sh'; cannot switch branches.
jesus% git status
# Not currently on any branch.
# Changed but not updated:
# (use "git add/rm ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# deleted: .gitignore
# modified: autoconf.sh
…

First, I restored the hidden .gitignore file from tape. As for autoconf.sh

jesus% git diff
sh: less: not found
jesus%

That was yet another thing to install and more dependency hell.

jesus% git diff
diff --git a/autoconf.sh b/autoconf.sh
old mode 100644
new mode 100755
jesus%

Steve had previously elected not to accept my addition of execute permission to the shell program, autoconf.sh. So to discard changes in the working directory

jesus% git checkout -- autoconf.sh
jesus%

jesus% git checkout v0_9-branch
Previous HEAD position was 95a0fac... Minor portability fixes from Alan Feldstein.
Checking out files: 100% (489/489), done.
Switched to branch "v0_9-branch"
Your branch and 'origin/v0_9-branch' have diverged,
and have 3 and 3 different commit(s) each, respectively.
jesus%

I needed to get in sync with the Icarus Verilog project so I could ultimately offer a patch.

jesus% git pull
remote: Counting objects: 1757, done.
remote: Compressing objects: 100% (1359/1359), done.
remote: Total 1359 (delta 1087), reused 0 (delta 0)
Receiving objects: 100% (1359/1359), 242.83 KiB | 16 KiB/s, done.
Resolving deltas: 100% (1087/1087), completed with 197 local objects.
From git://icarus.com/~steve-icarus/verilog
4d57ede..9fbb12d master -> origin/master
95a0fac..90d65ae v0_8-branch -> origin/v0_8-branch
9c09394..9afa95d v0_9-branch -> origin/v0_9-branch
0a72df2..0b2ce7a vvp-net-out-rework -> origin/vvp-net-out-rework
From git://icarus.com/~steve-icarus/verilog
* [new tag] pei20090916 -> pei20090916
* [new tag] s20090916 -> s20090916
* [new tag] s20090923 -> s20090923
* [new tag] v0_9_2 -> v0_9_2

*** Please tell me who you are.

Run

git config --global user.email "you@example.com"
git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident not allowed
jesus%

I did that and tried again.

jesus% git pull
Auto-merging Makefile.in
CONFLICT (content): Merge conflict in Makefile.in
Auto-merging configure.in
Auto-merging driver/Makefile.in
Removing version_base.in
Automatic merge failed; fix conflicts and then commit the result.
jesus%

They and I had made changes in the same area. I fixed the conflicts.

jesus% git commit
*
* You have some suspicious patch lines:
*
* In tgt-vhdl/scope.cc
* trailing whitespace (line 778)
...

There was a lot of noise like that.

jesus% git commit --no-verify
…
[v0_9-branch 333f594] Merge branch 'v0_9-branch' of git://icarus.com/~steve-icarus/verilog into v0_9-branch
jesus%

The Makefiles use some GNU extensions, so I got make-3.81-sol10-sparc-local.gz, the GNU version of make. Installation of <SMCmake> was successful.

jesus% gmake distclean
...
checking for gcc... gcc
checking whether the C compiler works... no
configure: error: in `/home/alan/git/icarus_verilog':
configure: error: C compiler cannot create executables
...

Of course gcc couldn't create executables. It wasn't installed. (That was the whole point. See My Big Mouth and I.) Why was it selected?

I added some debug output to a copy of configure and found that
$CC is gcc

That report came at the very beginning of the shell program, configure.

While creating a backup copy of config.status, I had accidentally changed the date of the original. That changed what would be done.

After fixing that, config.status still reported that “$CC is gcc”, but
gmake distclean
completed successfully (and config.status no longer existed).

jesus% ./configure
checking build system type... sparc-sun-solaris2.10
checking host system type... sparc-sun-solaris2.10
checking for gcc... cc
checking whether the C compiler works... yes
...
checking for flex... no
*** Error: No suitable flex found. ***
Please install the 'flex' package.
jesus%

Here we go again.

I got flex-2.5.35-sol10-sparc-local.gz, the GNU version of lex (a program that generates lexical analyzers). Installation of <SMCflex> was successful.

jesus% ./configure
...
checking for flex... flex
checking for bison... no
*** Error: No suitable bison found. ***
Please install the 'bison' package.
jesus%

Does this ever end?

I got bison-2.4.1-sol10-sparc-local.gz, a replacement for YACC (a parser generator; "Yet Another Compiler Compiler"). Installation of <SMCbison> was successful.

jesus% ./configure
...
checking for bison... bison
...
checking whether __SUNPRO_C is declared... yes
checking whether __SUNPRO_CC is declared... yes
checking whether __SUNPRO_CC is declared... (cached) yes
...
checking for leading underscores... ./configure: line 6803: nm: command not found
no
checking for trailing underscores... ./configure: line 6832: nm: command not found
no
...
jesus%

But I already had nm.

jesus% ls -l /usr/ccs/bin/nm
-r-xr-xr-x 1 root bin 28224 Apr 7 2008 /usr/ccs/bin/nm
jesus%

I needed to add
/usr/ccs/bin
to PATH.

jesus% ./configure
...
checking for leading underscores... no
checking for trailing underscores... no
...

I was cleanly through configure!

jesus% gmake
mkdir dep
CC -DHAVE_CONFIG_H -I. -I. -g -xMD -c main.cc -o main.o
mv main.d dep/main.d
...

Note the -xMD. That's the way Sun Studio 12 wants it.

...
CC -DHAVE_CONFIG_H -I. -I. -g -xMD -c net_scope.cc -o net_scope.o
"net_scope.cc", line 228: Error: __rwstd::__rb_tree, __rwstd::__select1st, perm_string>, std::less, std::allocator>>::iterator::iterator(__rwstd::__rb_tree, __rwstd::__select1st, perm_string>, std::less, std::allocator>>::__rb_tree_node*) is not accessible from NetScope::find_parameter(perm_string).
1 Error(s) detected.
make: *** [net_scope.o] Error 1
jesus%

See the iverilog-devel email archive for the presentation of the above failure and the discussion that ensued. The short story is that that's as far as I'm going to go. That's what I meant by telling Steve "no".

It was time to submit a patch (adding some C/C++ compiler choice support for Icarus Verilog developers) to the Icarus Verilog project and then get back to OpenSPARC.

On 2009-09-04, Cary R. had confirmed that "V0.8 is [still] best for synthesis." And on 2009-11-30, Steve had made some comments about synthesis. So on 2010-01-24, I switched back to v0_8-branch.

Although I have stated this in the past, let me reiterate that your interest in synthesis using Icarus Verilog may be different from mine. Nevertheless, you may benefit from my contributions. Previously provided was a "path from Verilog to ... JHDL". This path involves synthesis using Icarus Verilog. That is Cosmic Horizon's interest. By "widening" the preexisting path to support OpenSPARC, it will be possible to automatically translate these SPARC-V9 implementations to JHDL. Thus, we remove a barrier to the use of FSS in the functional verification of existing designs written in Verilog.

Back on v0_8-branch, my first task was to add the compiler choice support there as well. It's added, but when I saw error messages while compiling this branch using Sun Studio 12, I quickly lost patience and got gcc.

I got gcc-3.4.6-sol10-sparc-local.gz. Installation of <SMCgcc> was successful, as was compilation of Icarus Verilog (gmake DEBUGFLAGS=-DDEBUG).


It was time to take OpenSPARC for a spin.

jesus% source ~/Sun/OpenSPARC/OpenSPARCT1.1.6/OpenSPARCT1.cshrc
/home/alan/Sun/OpenSPARC/OpenSPARCT1.1.6/OpenSPARCT1.cshrc: No such file or directory
jesus%

Of course, I had to go get it again, so I got OpenSPARCT1.1.7.tar.bz2.

jesus% source ~/Sun/OpenSPARC/OpenSPARCT1.1.7/OpenSPARCT1.cshrc
jesus% cd $DV_ROOT/design/sys/iop/rtl/
/home/johndoe/OpenSPARCT1/design/sys/iop/rtl/: No such file or directory
jesus%

OpenSPARCT1.cshrc required some customization.

jesus% cd $DV_ROOT/design/sys/iop/rtl/
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
...
gdb /usr/local/lib/ivl-0.8/ivl
sh: gdb: not found
jesus%

I got gdb-6.8-sol10-sparc-local.gz. Installation of <SMCgdb> was successful.

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
...
gdb /usr/local/lib/ivl-0.8/ivl
ld.so.1: gdb: fatal: libexpat.so.1: open failed: No such file or directory
Killed
jesus%

But I already had
/usr/sfw/lib/libexpat.so.1

So I used crle to configure the runtime linking environment:

# crle -u -l /usr/sfw/lib
#

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
...
gdb /usr/local/lib/ivl-0.8/ivl
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "sparc-sun-solaris2.10"...
(gdb)

That was a milestone and the date was 2010-01-27.

Next, I installed and configured XEmacs. I'll spare you the details, but it was a nontrivial task, not completed until 2010-02-02. I wish I could hire a system administrator.

Speaking of new people, a former Staff Engineer in hardware verification at Sun Microsystems has agreed to do some work for Cosmic Horizon. Not yet having permission to disclose his identity, I'll call him "Mr. Lippman". In the midst of the XEmacs task, I did some work on VPN for Mr. Lippman. But a complete setup wasn't necessary because Dr. Mishra already uses VPN to connect with Cosmic Horizon.

Then I tried actually running Icarus Verilog (under gdb) to generate Free Netlist Format (FNF) code.

(gdb) run -v -C/tmp/ivrlh153d -C/usr/local/lib/ivl-0.8/fnf.conf -- - Starting program: /usr/local/lib/ivl-0.8/ivl -v -C/tmp/ivrlh153d -C/usr/local/lib/ivl-0.8/fnf.conf -- - warning: Lowest section in /lib/libdl.so.1 is .hash at 000000b4
/usr/local/lib/ivl-0.8/system.sft: Processing System Function Table file.
ERROR: Unable to read config file: /usr/local/lib/ivl-0.8/fnf.conf
...

The Icarus Verilog FNF generator is part of Confluence. There had been no uncommitted changes in my Confluence CVS sandbox at the time of the Solaris upgrade disaster, so it was time to restore the CVS repository from tape and checkout the Confluence project.

The CVS repository was restored on 2010-02-03.

Next, I needed to install the CVS client/server software. When you install CVS on a UNIX server (e.g. jesus), you automatically get both server and client software. I got cvs-1.12.13-sol10-sparc-local.gz. Installation of <SMCcvs> was successful.

jesus% cd ~/cvs/
jesus% cvs -d :ext:alan@jesus:/var/lib/cvsroot checkout confluence
cvs: Command not found
jesus%

After solving that, I tried again to access the "remote" repository. I use the ext method with the SSH protocol and needed to add jesus to the list of known hosts.

...
Password:
cvs checkout: failed to create lock directory for `/var/lib/cvsroot/CVSROOT' (/var/lib/cvsroot/CVSROOT/#cvs.history.lock): Permission denied
cvs checkout: failed to obtain history lock in repository `/var/lib/cvsroot'
...

That was two problems.

The first was that password authentication was being used. Public key authentication is a stronger authentication mechanism than password authentication, because the private key never travels over the network.

ssh-keygen -t rsa

cat $HOME/.ssh/id_rsa.pub | ssh jesus 'cat >> .ssh/authorized_keys && echo "Key copied"'

I like to run a shell in an XEmacs buffer. By default, XEmacs doesn't recognize that

Enter passphrase for key '/home/alan/.ssh/id_rsa':

should be treated like a password prompt. That is, the passphrase should not be displayed when the user types it in at the prompt. From another computer, I copied

$HOME/.xemacs/init.el
$HOME/.xemacs/custom.el

with appropriate modifications.

Back to the "two problems", the second was a permission issue, solved by creating new user "cvs" (group "cvsusers") with ownership of
/var/lib/cvsroot
recursively. Note that I too am a member of cvsusers and that file mode is set appropriately.

I also gave user cvs ownership of executable file cvs.

jesus% cvs -d :ext:alan@jesus:/var/lib/cvsroot checkout confluence
Enter passphrase for key '/home/alan/.ssh/id_rsa':
cvs checkout: Updating confluence
U confluence/INSTALL
...
jesus%

On 2010-02-05, I wrote in my notes, "I don't think there are any more issues with CVS."

cd confluence/src/ivl/
gcc -Wall -O2 -shared -o fnf.tgt -fpic fnf.c

# cp /home/alan/cvs/confluence/src/ivl/fnf.conf /usr/local/lib/ivl-0.8/
# cp /home/alan/cvs/confluence/src/ivl/fnf.tgt /usr/local/lib/ivl-0.8/

(gdb) run -v -C/tmp/ivrlh26d2 -C/usr/local/lib/ivl-0.8/fnf.conf -- - Starting program: /usr/local/lib/ivl-0.8/ivl -v -C/tmp/ivrlh26d2 -C/usr/local/lib/ivl-0.8/fnf.conf -- - warning: Lowest section in /lib/libdl.so.1 is .hash at 000000b4
/usr/local/lib/ivl-0.8/system.sft: Processing System Function Table file.
Using language generation: IEEE1364-2001
PARSING INPUT
... done, 0.19 seconds.
ELABORATING DESIGN
... done, 0.67 seconds.
RUNNING FUNCTORS
-F synth2 ...
-F synth ...
-F syn-rules ...
-F cprop ...
-F nodangle ...
... 1 iterations deleted 3897 dangling signals and 100 events. (count=3206)
... 2 iterations deleted 3897 dangling signals and 100 events. (count=0)
... done, 0.12 seconds.
CODE GENERATION -t dll
... invoking target_design
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Unsupported logic type: 5.
... done, 0.33 seconds.
STATISTICS
lex_string: add_count=8124 hit_count=16420

Program exited normally.
(gdb)

That's where I wanted to be. And I started digging in again. Please take a look at the Verilog source for module bw_u1_scanlg_2x. In particular, I'm interested in the expression
~ck

I set a breakpoint on the line of Icarus Verilog FNF generator code that outputs that NOT gate. I want to follow the output from this NOT gate and reach the gate input of the latch, if all is well. But I previously wrote that "I have reason to suspect that the FNF is wrong", and I'm trying to find out why.

gdb failed to stop on that breakpoint. I needed to recompile the Icarus Verilog FNF generator with debugging information.

gcc -Wall -O2 -shared -o fnf.tgt -fpic -g fnf.c

First, I made sure I was on the correct NOT gate (recall that "nexus id 43015 is driven by the [correct] NOT gate"). From a nexus there are backward references to all the device pins that point to it.

(gdb) print net->pins_[pin]
$3 = (ivl_nexus_t) 0xce1438
(gdb)

The name of this nexus is "_s6".

There are two device pins connected to this nexus, one of type 0 (ivl_signal_t) and another of type 1 (ivl_net_logic_t). The latter corresponds to the NOT gate I just came from. What about the former?

(gdb) print *(*(*net->pins_[pin]).ptrs_).l.sig
$15 = {type_ = IVL_SIT_TRI, port_ = IVL_SIP_NONE, width_ = 1, signed_ = 0,
isint_ = 0, local_ = 1, lsb_index = 0, lsb_dist = 1, name_ = {
text_ = 0x361833 "_s6"}, scope_ = 0xce0b40, n = {pin_ = 0xce1438,
pins_ = 0xce1438}, attr = 0x0, nattr = 0}
(gdb)

Signals have pins that connect to the rest of the netlist. IVL_SIP_NONE means that this signal is not a port into the scope that contains it. Here's what we're looking at (from Icarus Verilog's t-dll.h):


struct ivl_signal_s {
ivl_signal_type_t type_;
ivl_signal_port_t port_;

unsigned width_;
unsigned signed_ : 1;
unsigned isint_ : 1;
unsigned local_ : 1;

/* These encode the run-time index for the least significant
bit, and the distance to the second bit. */
signed lsb_index;
signed lsb_dist;

perm_string name_;
ivl_scope_t scope_;

union {
ivl_nexus_t pin_;
ivl_nexus_t*pins_;
} n;

struct ivl_attribute_s*attr;
unsigned nattr;
};


This signal has only 1 pin (width_==1), so the n.pin_ member is valid. Regardless, note the address 0xce1438. It's the same nexus we just came from. There's no place else to go. In other words, this is a dangling output wire. It's not connected to the latch as it should be.

I came to that conclusion on 2010-02-12. That's when I decided to create a Verilog module that contains a NOT gate driving one pin of a flip flop, and compare what Icarus Verilog connects to the NOT output. After some experimentation, I settled on this:


module ff (output so, input sd, ck, se);
reg so_l;
assign so = ~so_l;
not G1 (ck_l, ck);
always @(posedge ck_l)
so_l <= ~(sd & se);
endmodule


This produced the following FNF:


(scope "ff" "ff" (
(input 0 "ck" 1)
(select 1 1 0 0)
(input 2 "sd" 1)
(select 3 1 0 2)
(input 4 "se" 1)
(select 5 1 0 4)
(output 7 "so" 1 6)
(name 9 "so_l" 1 8)
(name 11 "ck_l" 1 10)
(name 13 "_s5" 1 12)
(name 15 "_s6" 1 14)
(name 16 "_s8" 1 12)
(not 6 1 8)
(not 10 1 1)
(and 14 1 3 5)
(not 12 1 14)
(ff 17 1 10 12)
(select 8 1 0 17)
))


My theory is that

(ff 17 1 10 12)

is

(ff q width clock d)


This time, the ivl_nexus_s of interest looks like

(gdb) print *ivl_logic_pin(log, 0)
$6 = {nptr_ = 3, ptrs_ = 0x152f78, name_ = 0x1707d1 "ck_l",
private_data = 0x0}
(gdb)

Note that there are three device pins connected this nexus, which was encouraging. The one not present in OpenSPARC module bw_u1_scanlg_2x is of type 3 (ivl_lpm_t).

(gdb) print *(ivl_logic_pin(log, 0)->ptrs_ + 2)
$12 = {pin_ = 0, type_ = 3, drive0 = 0, drive1 = 0, l = {sig = 0x152f20,
log = 0x152f20, con = 0x152f20, lpm = 0x152f20}}
(gdb)

I guessed that that is the flip-flop and wondered why the latch didn't get connected to the nexus in OpenSPARC.

But first, I would follow
*(ivl_logic_pin(log, 0)->ptrs_ + 2)
to the flip-flop.

*(ivl_logic_pin(log, 0)->ptrs_ + 2)->l.lpm
is an ivl_lpm_s structure. The structure declaration appears in Icarus Verilog's t-dll.h and looks like the following:


struct ivl_lpm_s {
...
union {
struct ivl_lpm_ff_s {
...
} ff;

struct ivl_lpm_latch_s
{
...
} latch;
...
} u_;
};


I was happy to be reminded that I had added the latch union member, but the member list associated with tag ivl_lpm_latch_s is much shorter than that associated with tag ivl_lpm_ff_s. That is likely to be a problem.

(gdb) print *(ivl_logic_pin(log, 0)->ptrs_ + 2)->l.lpm
$3 = {type = IVL_LPM_FF, scope = 0x16ed70, name = {text_ = 0x158508 "_s4"},
attr = 0x153368, nattr = 1, u_ = {ff = {width = 1, swid = 0, scnt = 0,
clk = 0x153488, we = 0x0, aclr = 0x0, aset = 0x0, sclr = 0x0,
sset = 0x0, q = {pins = 0x1533f8, pin = 0x1533f8}, d = {
pins = 0x1534b8, pin = 0x1534b8}, s = {pins = 0x30, pin = 0x30}, a = {
mem = 0x0, decode = 0x0}, aset_value = 0x0, sset_value = 0x0},
latch = {width = 1, gatePtr = 0x0, qPtr = 0x0, dataPtr = 0x153488},
mux = {width = 1, size = 0, swid = 0, d = 0x153488, q = {pins = 0x0,
pin = 0x0}, s = {pins = 0x0, pin = 0x0}}, demux = {width = 1,
awid = 0, size = 0, bit_in = 0x153488, q = 0x0, d = 0x0, a = 0x0},
shift = {width = 1, select = 0, signed_flag = 0, q = 0x153488, d = 0x0,
s = 0x0}, arith = {width = 1, signed_flag = 0, q = 0x0, a = 0x153488,
b = 0x0}, ufunc = {def = 0x1, ports = 0, port_wid = 0x0,
pins = 0x153488}}}
(gdb)

So I had successfully followed
*(ivl_logic_pin(log, 0)->ptrs_ + 2)
to the flip-flop.

As for the differences between ivl_lpm_latch_s and ivl_lpm_ff_s, I could have taken one of two approaches: (1) learn about each member of ivl_lpm_ff_s and add appropriate members to ivl_lpm_latch_s or (2) continue investigating why a latch is not connected to the nexuses at the point of instantiation, which I suspect will involve expansion of the ivl_lpm_latch_s member list anyway.

I chose the second approach.

When is the flip-flop connected to its nexuses? This is certainly before the call to build_hierarchy in the FNF Icarus code generator.

So I started tracing backwards in time using gdb. I would go back to the point where the flip flop disappears.

(gdb) backtrace
#0 build_hierarchy (scope=0x16ed70, cd=0x0) at fnf.c:259
#1 0xff162b7c in target_design (des=0x16ed70) at fnf.c:570
#2 0x000d05d8 in dll_target::end_design (this=0x151ca0) at t-dll.cc:631
#3 0x0006a094 in Design::emit (this=0x16e4e8, tgt=0x151ca0) at emit.cc:411
#4 0x0006a15c in emit (des=0x16e4e8, type=0x1538b8 "dll") at emit.cc:513
#5 0x0003dd3c in main (argc=1500392, argv=0x151800) at main.cc:721
(gdb)

...
Breakpoint 1, Design::emit (this=0x0, tgt=0x151ca0) at emit.cc:381
381 rc = rc && tgt->start_design(this);
(gdb) step
dll_target::start_design (this=0x151ca0, des=0x16e4e8)
at /usr/local/lib/gcc/sparc-sun-solaris2.10/3.4.6/../../../../include/c++/3.4.6/bits/stl_list.h:478
478 : _Base(__a) { }
(gdb) print *des->find_root_scope()->find_signal("ck_l")->pins_->nexus_->list_->node_
$21 = { = {nlist_ = 1, list_ = 0x154084}, = {file_ = 0x0,
lineno_ = 0}, _vptr.NetObj = 0x10a38c, scope_ = 0x16e530, name_ = {
text_ = 0x158508 "_s4"}, pins_ = 0x16ee54, npins_ = 10, delay1_ = 0,
delay2_ = 0, delay3_ = 0}
(gdb)

How do I confirm that the NetObj named “_s4” is a NetFF?

Use run-time type information (RTTI) and dynamic casting, but

(gdb) print dynamic_cast < NetFF * > ( des->find_root_scope()->find_signal("ck_l")->pins_->nexus_->list_->node_ )
No symbol "dynamic_cast" in current context.
(gdb) print typeid( *des->find_root_scope()->find_signal("ck_l")->pins_->nexus_->list_->node_ ).name()
No symbol "typeid" in current context.
(gdb)

Why is gdb doing this to me?

Scott Wood of Freescale Semiconductor says, "Because most developers in GNU-land seem to think that C is perfectly adequate".

Reluctantly, I performed a temporary edit of t-dll.cc to get the information I wanted. This required additional care, such as the use of const member functions with the const Design object and the use of accessors to read private data members.

cout << "Type name of the suspected flip flop is " << typeid( *des->find_root_scopes().front()->find_signal("ck_l")->pin(0U).nexus()->first_nlink()->get_obj() ).name() << endl;

Type name of the suspected flip flop is 5NetFF

Similarly, I continued backward in time.

I reached function main in main.cc, looking before
CODE GENERATION -t dll

When I probed at the start of
RUNNING FUNCTORS
the result was
Type name of the suspected flip flop is 10NetEvProbe

That was too early (i.e. pre-synthesis and haven't yet selected NetFF to implement the Verilog functionality).

Note that NetEvProbe, NetFF and NetLatch all inherit from NetNode.

Which functor connects the NetFF to the design?

RUNNING FUNCTORS
-F synth2 ...
-F synth ...
-F syn-rules ...
-F cprop ...
-F nodangle ...
... 1 iterations deleted 1 dangling signals and 1 events. (count=1)
... 2 iterations deleted 1 dangling signals and 1 events. (count=0)
... done, 0 seconds.

I quickly found that synth2 connects the NetFF to the design.

Going inside functor synth2, I reached


void Design::functor(functor_t*fun)
…
// apply to processes
procs_idx_ = procs_;
while (procs_idx_) {
NetProcTop*idx = procs_idx_;
procs_idx_ = idx->next_;
fun->process(this, idx);
}
…


There is only one process in the ff scope (the same is true of the bw_u1_scanlg_2x scope in OpenSPARC T1), so Icarus Verilog should only iterate once over this loop.

(gdb) step
synth2_f::process (this=0xffbff840, des=0x16e680, top=0x152980)
at StringHeap.h:51
51 perm_string(const char*t) : text_(t) { };
(gdb)

/*
* Look at a process. If it is asynchronous, then synthesize it as an
* asynchronous process and delete the process itself for its gates.
*/

Breakpoint 1, synth2_f::process (this=0xffbff750, des=0x16e680, top=0x152980)
at synth2.cc:2615
2615 if (top->is_synchronous()) do {
(gdb) print top->scope_->module_name_
$1 = {text_ = 0x15866e "ff"}
(gdb) print top->is_synchronous()
$2 = true
(gdb)

Then I wanted to compare with bw_u1_scanlg_2x.

I'm trying to browse the elaborated design, while running functor synth2, in such a way that I don't need to modify my temporary lines of code in Icarus Verilog to switch between the simple flip flop design and the full OpenSPARC T1 (containing latches). Even though much of this browsing has been achieved with the temporary lines of code, I still want to use some gdb features. Debugging optimized code has been problematic, so I decided to

setenv CXXFLAGS '-g -O0'

There are 283 links connected to the nexus to which the ck signal of
OpenSPARCT1.ctu_top_rptr.so_lockup
is attached. How would I find the NOT gate leading toward the latch?

I would walk through the linked list of links connected to the nexus programmatically, printing information about connected objects that fall within the bw_u1_scanlg_2x scope (called "latch scope" below).

...
RUNNING FUNCTORS
-F synth2 ...
Fully qualified hierarchical name is OpenSPARCT1.ctu_top_rptr.so_lockup
Type name of object connected to ck in latch scope is 8NetLogic
Name of nexus on output side of NOT gate is _s6
Type name of object connected to ck in latch scope is 6NetNet
Type name of object connected to ck in latch scope is 10NetEvProbe
-F synth ...
...

Here
is the temporary code (with some context) in functor.cc that produces the output that follows.

RUNNING FUNCTORS
-F synth2 ...
Fully qualified hierarchical name is OpenSPARCT1.ctu_top_rptr.so_lockup
Type name of object connected to ck in latch scope is 8NetLogic
Name of nexus on output side of NOT gate is _s6
Type name of object connected to _s6 is 8NetLatch
Type name of object connected to _s6 is 8NetLogic
Type name of object connected to _s6 is 6NetNet
Type name of object connected to ck in latch scope is 6NetNet
Type name of object connected to ck in latch scope is 10NetEvProbe
-F synth ...
-F syn-rules ...
-F cprop ...
-F nodangle ...
... 1 iterations deleted 3897 dangling signals and 100 events. (count=3206)
... 2 iterations deleted 3897 dangling signals and 100 events. (count=0)
... done, 0.13 seconds.

This was a huge surprise. I expected that the discovery from the simple design (i.e. that NetFF gets connected during synth2) would ultimately lead to an answer about why, in OpenSPARC T1, NetLatch fails to get connected during synth2. But NetLatch doesn't fail to get connected!

Does NetLatch later get disconnected (where NetFF stays connected) or does the FNF Icarus code generator fail to recognize NetLatch (where it recognizes NetFF)?

...
after nodangle
Type name of object connected to ck in latch scope is 8NetLogic
Name of nexus on output side of NOT gate is _s6
Type name of object connected to _s6 is 8NetLatch
Type name of object connected to _s6 is 8NetLogic
Type name of object connected to _s6 is 6NetNet
Type name of object connected to ck in latch scope is 6NetNet
... done, 0.12 seconds.
CODE GENERATION -t dll
…

NetLatch was still there, so I looked later.

...
CODE GENERATION -t dll
... invoking target_design
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Inout ports not supported.
** ERROR: Unsupported logic type: 5.
after CODE GENERATION -t dll
Type name of object connected to ck in latch scope is 8NetLogic
Name of nexus on output side of NOT gate is _s6
Type name of object connected to _s6 is 8NetLatch
Type name of object connected to _s6 is 8NetLogic
Type name of object connected to _s6 is 6NetNet
Type name of object connected to ck in latch scope is 6NetNet
... done, 0.32 seconds.
STATISTICS
lex_string: add_count=8124 hit_count=16420

Program exited normally.
(gdb)

Next, I would focus my attention on code generation. Does the FNF Icarus code generator fail to recognize NetLatch (where it recognizes NetFF)?