• 0

# PmodCLP - Sample project timing errors

## Question

https://reference.digilentinc.com/reference/pmod/pmodclp/start

Specifically, the

code.

Since I'm using an Artix Arty board, I had to modify the pins used, and the reset is reversed (on the arty the ck_rst is 1 when pressed), but after that things worked fine. The Arty, like the Nexys 3 has a 100MHz clock.

In looking at the code, however, I noticed two errors that make the code quite confusing:

1) In the first always block:

```    // This process counts to 100, and then resets.  It is used to divide the clock signal.
// This makes oneUSClock peak aprox. once every 1microsecond
always @(posedge CLK) begin

if(clkCount == 7'b1100100) begin
clkCount <= 7'b0000000;
oneUSClk <= ~oneUSClk;
end
else begin
clkCount <= clkCount + 1'b1;
end

end```

Note that it is flipping the oneUsClk once per 100 clocks at the 100MHz input rate. That results in a full cycle every 200 clocks, not 100. To get a 1MHz clock that has a rising edge every 1μs, you need to flip the clock every 0.5μs or 50 clock edges of the 100Mhz clock. But replacing the 100 with 50 won't be correct either, you can't get 100 clock edges by counting from 0 to 100, that's 101 edges. And you can't get 50 edges by counting from 0 to 50,  the correct code need to count from 0 to 49 to get 50 edges.

The second issue is that the delays are all based on this oneUsClk, while the delay counts are expressed in terms of the original 100MHz clock ticks. You can see that in this combinatorial logic:

```    // Determines when count has gotten to the right number, depending on the state.
assign delayOK = (
((stCur == stPowerOn_Delay) && (count == 21'b111101000010010000000)) ||                // 2000000         -> 20 ms
((stCur == stFunctionSet_Delay) && (count == 21'b000000000111110100000)) ||        // 4000             -> 40 us
((stCur == stDisplayCtrlSet_Delay) && (count == 21'b000000000111110100000)) ||    // 4000             -> 40 us
((stCur == stDisplayClear_Delay) && (count == 21'b000100111000100000000)) ||        // 160000         -> 1.6 ms
((stCur == stCharDelay) && (count == 21'b000111111011110100000))                        // 260000        -> 2.6 ms - Max Delay for character writes and shifts
) ? 1'b1 : 1'b0;```

The delay for the stPowerOn_Delay is 2,000,000. That's correct for a 100MHz clock.  For a 1MHz clock with a rising edge every 1μs, you only want a count of 20,000 not 2,000,000. All of the times are off by this same factor of 100. You can see in the block that increments the count variable that this is being incremented each posedge of the oneUSClk, not the 100MHz CLK:

```    // This process increments the count variable unless delayOK = 1.
always @(posedge oneUSClk) begin

if(delayOK == 1'b1) begin
count <= 21'b000000000000000000000;
end
else begin
count <= count + 1'b1;
end

end```

So the 20ms delay is actually a 2 second delay, 1.6ms is 160ms, etc.

Finally, if you fix this, you will notice that things don't quite work anymore. The LCD display is now flashing and barely legible because it is now executing the final command (shift-left) every 2.6ms, which is far too fast. So, you'll need to alter the delay for the final state stCharDelay when the write is done to be a more appropriate number. I suggest 250,000μs which means 4 characters scroll by per second which is very legible. This is most easily done by adding an additional condition check for the final state delay like:

```    // Determines when count has gotten to the right number, depending on the state.
assign delayOK = (
((stCur == stPowerOn_Delay) &&              (count == 21'd020000)) ||	// -> 20 ms
((stCur == stFunctionSet_Delay) &&          (count == 21'd000040)) ||	// -> 40 us
((stCur == stDisplayCtrlSet_Delay) &&       (count == 21'd000040)) ||	// -> 40 us
((stCur == stDisplayClear_Delay) &&         (count == 21'd001600)) ||	// -> 1.6 ms
((stCur == stCharDelay && !writeDone) &&    (count == 21'd002600)) ||	// -> 2.6 ms - Max Delay for character writes and shifts
((stCur == stCharDelay && writeDone) &&     (count == 21'd250000))      // -> 250 ms - 1/4 second delay for shifts
) ? 1'b1 : 1'b0;```

where the delay before all the characters are written is 2.6ms and it jumps to 250ms once they are all written.

I have attached a file which reflects the corrections I outlined above.

Edited by inflector
typo

## Recommended Posts

• 1

Hi @inflector,

Thank you for posting potential issues and suggested fixes with the Verilog code. I have pass on this thread to our content team.

cheers,

Jon