Xilinx Johnson counter Verilog example bug?

Greetings:

I have set out to learn Verilog, and thus to learn to use the ModelSim XE II v5.7c Starter simulation program that comes with Xilink WebPack

5.2i. Yesterday I got the software all installed and ready for today's first venture into my shiny new textbook "A Verilog HDL Primer" by J Bhasker.

I began by making sure I knew how to use the software by compiling and simulating the example jc2_top.v together with jc2_test.tf (the test bench) from the WebPack .../ISEexamples/jc2_ver directory.

The readme for the verilog source says that it should implement a Johnson counter with the pattern (depending on the count direction selected):

left right

0000 0000 0001 1000 0011 1100 0111 1110 1111 1111 1110 0111 1100 0011 1000 0001 0000 0000 (repeats)

But in fact the counter produces the following result in the simulator (initial state not shown, only repeated pattern):

left right

0001 1000 0011 1100 0111 1110 1110 0111 1100 0011 1000 0001 0001 1000 (repeats)

The Verilog they provided is (just counter section within an always @ (posedge clk) begin procedural construct):

//Counter section: if(run) begin if(dir) begin q[3:1] = q[2:0]; //Shift lower bits (Left Shift) q[0] = !q[3]; //Circulate inverted MSB to LSB end else begin q[2:0] = q[3:1]; //Shift upper bits (Right Shift) q[3] = !q[0]; //Circulate inverted LSB to MSB end end

Before knowing anything at all about Verilog, I proceded to tinker with this code. I suspected that this represents stated logic, and so all statements are executed in parallel at each clock edge (which turns out not to be the right assumption, which I learned after reading a bit from my Verilog text).

So I modified the code to be this way to test this hypothesis:

//Counter section: if(run) begin if(dir) begin q[0] = !q[3]; //Circulate inverted MSB to LSB q[3:1] = q[2:0]; //Shift lower bits (Left Shift) end else begin q[3] = !q[0]; //Circulate inverted LSB to MSB q[2:0] = q[3:1]; //Shift upper bits (Right Shift) end end

Which of course produced the following pattern:

left right

0011 1100 0111 1110 1111 1111 1100 0011 1000 0001 0000 0000 0011 1100 (repeats)

This led me to suspect that the code is actually executed sequentially not in parallel. Looking at my new Verilog text confirmed this to be the case.

The questions are thus:

  1. Why did Xilinx incorrectly implement what was described in the README?

  1. Has anyone encountered this screwed up example before?

  2. What is the correct implentation?

Oh no, that's too easy. I'm supposed to be learning this language, so I'll take a crack at it.

After several frustrating attempts to fix the counter code, I realized that there was no conceivable logic with which to determine the value of the q[0] bit *after* copying the q[2:0] bits over the q[3:1] bits, because I need to work with the original q[3] bit (left counting case).

One way would be to put in another register bit, but this would be a kuldgy waste of ffs. At the brink of demoralization (and recognizing that the brick wall was self-imposed by my not knowing how to do anything besides the behavioral style of coding, which forces the sequential execution which I don't want, I finally happened upon the answer to my hopes: a way to assign the bits of the result based on the bits of the previous state, all in parallel. That is the concatenation operation, leading to:

//Counter section: if(run) begin if(dir) begin q[3:0] = {q[2], q[1], q[0], ~q[3]}; end else begin q[3:0] = {~q[0], q[3], q[2], q[1]}; end end

Whew, it works!

What a way to learn a language. This was my first day of Verilog. I planned to start by typing in an example from my textbook, but instead I just couldn't resist trying to fix the Xilinx example. Now off to typing in my first Verilog code from scratch to finish.

Good day!

--
____________________________________
Christopher R. Carlen
Principal Laser/Optical Technologist
Sandia National Laboratories CA USA
crcarle@sandia.gov
Reply to
Chris Carlen
Loading thread data ...

Hi -

Verilog has both a blocking assignment (the type that appears in your code fragment, and which uses the = sign) and a non-blocking assignment, in which "=" is replaced by "

Reply to
Bob Perlman

Jeez. More blocking assignments in clocked always blocks! Further proof of my assertion that models and examples are built by a company's most junior engineers, and that the companies involved don't bother checking anything before throwing it up on the web. The only possible explanation is that they just don't care.

If we can't trust the examples, how can we trust the post-P&R simulation models?

Reply to
Andy Peters

Good points. I guess I will be cautious about using the examples for coding style.

I will be diving in to the text seriously starting Monday when I'm back to work. Hopefully the text will learn me the right way.

Good day and thanks for the input.

--
_____________________
Christopher R. Carlen
crobc@earthlink.net
Suse 8.1 Linux 2.4.19
Reply to
Chris Carlen

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.