You will see something like this if you try to use Icarus Verilog to synthesize a design that contains a latch. As Steve Williams said on 2005-06-28, "Icarus Verilog doesn't know how to synthesize latches."

As I said in a previous blog item, I am working on that.

libm.so.2 provides the functions required by those standards supported by the Solaris 10 OS (including C99), so moving to Solaris 10 got me past the Icarus Verilog developer problem I reported earlier. I purchased a system configured to meet development needs, a Sun Fire V210 Server with Solaris 10 pre-installed. After some system administration to get the new server configured the way I wanted it, I successfully compiled

vvp/vthread.cc

on 2006-12-18. That was the file with the call to lround that was giving me trouble.

I then synchronized with the latest work of Steve Williams and committed to doing so daily. (At this point, this is a one-way synchronization, from his CVS repository to mine. Once I have something that is clearly an improvement, I will offer him a patch.) This daily merge is followed by verifying that the merge didn't break anything and then committing. There are many steps involved, so I wrote a procedure. Naturally, the procedure screamed for automation, so I translated the procedure into a pair of Perl programs. The merge program is executed by cron nightly, which sends me an email with the output. After inspecting the output, I manually install the new Icarus Verilog. Finally, I manually launch a second Perl program to verify and commit. Automation is often a very good time investment. This has been no exception.

To help me to understand Steve's synthesis code, I created a table that covers all combinations of branches taken or not taken, for those branches that were important to understand. Some code is not reached by the OpenSPARC T1 chip design that I am using as a test case, and I have asked Steve for some additional test cases to reach the Icarus Verilog code that I do not yet fully understand. Although I am motivated by OpenSPARC, I want to be sure that I do not break anything for anyone else.

I have added some synthesis code to help Icarus Verilog to recognize when a latch is inferred. And I have made the error messages go away. That's not enough, of course.

I purchased a copy of the Library of Parameterized Modules (LPM) standard and used it to create a stub of the NetLatch C++ class. This is a sibling of Steve's NetFF class. They share a common base class, NetNode.

To help me to visualize the large object-oriented design that Icarus Verilog is, I created a partial UML class diagram, and I add to it as I discover aspects of the design that are important to the task at hand.

I took some time off in December and January to become a Sun Certified Programmer for the Java 2 Platform, Standard Edition 5.0. I did not need the distraction of C++ (or Verilog) at that time.

In February, more time was lost to a networking problem, a 40 second delay in name service on my local network. This was related to the new server on the network. The solution is related to that server too. (The solution came to me as I was lying in bed waiting to fall asleep. The brain never stops.) Now perhaps I can call myself a network administrator. I had to learn a lot to solve that problem. It was really a combination of problems. Hopefully, I have forgotten much of what I learned. I will never need that knowledge. Seriously, sometimes I wish that Cosmic Horizon had a network administrator, and a system administrator, and a Web designer, and a GUI programmer, and a tax consultant ...

But I digress.

As I was looking at Steve's synthesis code, near the procedural assignment lvalue that needs to become a latch, I became displeased with the way a branch was going. The cause of my displeasure was that a NetMemory object had not been created. Had it been created, the branch would have gone in the direction I wanted. Furthermore, a latch is a memory element, so I reasoned that a NetMemory object was needed. I went off looking for where it had been decided that the NetMemory object would not be created.

In the midst of that search, I was bitten for the last time by Steve's use of the CVS Log keyword, and decided to solve that problem once and for all. Log keyword substitutions are problematic at merge time. Turning of keyword substitution entirely works for me, and prevents future problems. The bulk of the work was actually the creation of a Perl program to recurse over all of the Icarus Verilog source directories to clean up dozens of files. It is not something that I wanted to do manually. When my CVS learning curve required me to run that Perl program multiple times, I was very pleased with myself that I had taken the time to write it.

Back to the decision against NetMemory instantiation, it had been made during the Verilog elaboration phase. Now that I have pinpointed that decision, I am all but certain that my reasoning about needing that instantiation was incorrect. It seems that NetMemory is intended for Verilog one-dimensional arrays with elements of type reg, something entirely different than a latch.

Since I have done the work of pinpointing the decision code, I might as well use what I have learned there to solidify my understanding of what Verilog calls a "memory". This time investment will be small compared with the debugging effort to pinpoint the elaboration code. I am translating Sputnik's integer register file to Verilog (almost done) so that I can watch Icarus Verilog deal with it.

Then I will get back to the synthesis code.

Rest assured. I am spending time and money on this.