handshacking between modules, best practices ?

K

kristoff

Guest
Hi,


Last weekend, I was continueing on my small project to use a FPGA as
DAC. I now use a hardware DAC (tlc5615).


So I have two modules, a top-level module for the DDS and an additional
module to drive the TLC. I have two signal for handshacking ("load" and
"done").
At a certain point, I had the problem that one of the signals wasn't
dropped fast enough, which resulted in a weird timing-issue.

In the end, I managed to fix my particular by adding a state with a
small delay in my FSM, but -looking back- it is probably also possible
to have done this with some additional checks in the state-machine.



Question: are there known "best practices" when designing a
handshacking-protocol between different modules in a FPGA design?
Is there documentation about this? Or text-books?


My question is not about this particular bug but a generic question on
"do-s" and "do not-s" in general.



Kristoff
 
In article <oc0cog$j4c$1@dont-email.me>, kristoff <kristoff@skypro.be> wrote:
Hi,

Question: are there known "best practices" when designing a
handshacking-protocol between different modules in a FPGA design?
Is there documentation about this? Or text-books?


My question is not about this particular bug but a generic question on
"do-s" and "do not-s" in general.

I like the handhaking done in the various AXI like protocol's from ARM -
basically "VALID", "READY" signals. The key to making things work is there's
NO combinational paths between a VALID and a READY port i.e. the protocol is
fully synchronous with all module I/O registered.

Asynch handshaking is another beast altogether. I'm assuming you're not
talking about that.

Do a web search on the AXI protocols. ARM's specific document is titled
"AMBA AXI and ACE Protocol Specification". The handshaking is described
in section A3.2.1

Regards,

Mark
 
Hi Mark,




On 04-04-17 18:03, Mark Curry wrote:
In article <oc0cog$j4c$1@dont-email.me>, kristoff <kristoff@skypro.be> wrote:

Question: are there known "best practices" when designing a
handshacking-protocol between different modules in a FPGA design?
Is there documentation about this? Or text-books?


My question is not about this particular bug but a generic question on
"do-s" and "do not-s" in general.

I like the handhaking done in the various AXI like protocol's from ARM -
basically "VALID", "READY" signals. The key to making things work is there's
NO combinational paths between a VALID and a READY port i.e. the protocol is
fully synchronous with all module I/O registered.
(...)
Do a web search on the AXI protocols. ARM's specific document is titled
"AMBA AXI and ACE Protocol Specification". The handshaking is described
in section A3.2.1

Thanks for the link. Very interesting reading.

Yes, the handshaking protocol I used was syncronised, but I only used
the positive edge of the clock.

The AXI protocol used the positive edge of the clock to set the
control-signals and the negative edge of the clock to clear them.

That's indeed a good idea. I'll try to use this in my handshaking
mechanism to try to make it more robust.


Regards,
Mark
Kristoff
 
On 4/4/2017 11:08 AM, kristoff wrote:
Hi,


Last weekend, I was continueing on my small project to use a FPGA as
DAC. I now use a hardware DAC (tlc5615).


So I have two modules, a top-level module for the DDS and an additional
module to drive the TLC. I have two signal for handshacking ("load" and
"done").
At a certain point, I had the problem that one of the signals wasn't
dropped fast enough, which resulted in a weird timing-issue.

In the end, I managed to fix my particular by adding a state with a
small delay in my FSM, but -looking back- it is probably also possible
to have done this with some additional checks in the state-machine.



Question: are there known "best practices" when designing a
handshacking-protocol between different modules in a FPGA design?
Is there documentation about this? Or text-books?


My question is not about this particular bug but a generic question on
"do-s" and "do not-s" in general.

I've not used handshakes very often. What would be going on that a
handshake is required? Are you talking about clock domain crossing? Or
are you talking about two FSMs talking to each other. In both cases I
use a direct handshake where one signal does not change state until the
other "sees" it and acknowledges the previous change.

0,0 -> 1,0 -> 1,1 -> 0,1 -> 0,0

This has no opportunity for a race or timing problem. Is there
something I am missing?

--

Rick C
 
On 4/4/2017 3:36 PM, kristoff wrote:
On 04-04-17 18:03, Mark Curry wrote:
(...)
Do a web search on the AXI protocols. ARM's specific document is titled
"AMBA AXI and ACE Protocol Specification". The handshaking is described
in section A3.2.1


Thanks for the link. Very interesting reading.

Yes, the handshaking protocol I used was syncronised, but I only used
the positive edge of the clock.

The AXI protocol used the positive edge of the clock to set the
control-signals and the negative edge of the clock to clear them.

That's indeed a good idea. I'll try to use this in my handshaking
mechanism to try to make it more robust.

Looking at section A3.2 I don't see any signals changing state on the
falling edge of the clock. Where do you see this? It is *very* hard to
design synchronous logic that operates on both edges of the clock. The
two sides of an interface can operate on different clock edges, but this
only gives half a clock cycle for timing.

Am I completely missing something?

--

Rick C
 
On 04/04/2017 12:36 PM, kristoff wrote:
Hi Mark,




On 04-04-17 18:03, Mark Curry wrote:
In article <oc0cog$j4c$1@dont-email.me>, kristoff
kristoff@skypro.be> wrote:

Question: are there known "best practices" when designing a
handshacking-protocol between different modules in a FPGA design?
Is there documentation about this? Or text-books?


My question is not about this particular bug but a generic question on
"do-s" and "do not-s" in general.

I like the handhaking done in the various AXI like protocol's from ARM -
basically "VALID", "READY" signals. The key to making things work is
there's
NO combinational paths between a VALID and a READY port i.e. the
protocol is
fully synchronous with all module I/O registered.
(...)
Do a web search on the AXI protocols. ARM's specific document is titled
"AMBA AXI and ACE Protocol Specification". The handshaking is described
in section A3.2.1


Thanks for the link. Very interesting reading.

Yes, the handshaking protocol I used was syncronised, but I only used
the positive edge of the clock.

The AXI protocol used the positive edge of the clock to set the
control-signals and the negative edge of the clock to clear them.

That's indeed a good idea. I'll try to use this in my handshaking
mechanism to try to make it more robust.


Regards,
Mark
Kristoff

NO NO NO STOP STOP STOP.

The AXI handshake protocols DO NOT do that. They are, like all good
synchronous logic should be, sensitive only to the rising edge of the clock.

What the AXI handshake protocol does is use the concept of "mutually
agreed upon". If at the rising clock edge a) the master has already
asserted VALID and b) the slave has already asserted READY, then the
information present on all the rest of the wires is agreed to have been
handed off from the master to the slave. Otherwise, that information
(if available) is still the master's responsibility.

The point is that there's no need for a recovery cycle. The master can
leave VALID asserted and change to new valid data. The slave can leave
READY asserted if it doesn't need to wait while it processes the data
that it just picked up, and the next information can be transferred on
the very next rising edge. But this comes with the requirement that
whether the master's data is valid is entirely uninformed by whether the
slave is ready for it and vice versa.

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 
Hi Rob,

On 04-04-17 22:20, Rob Gaddi wrote:

Yes, the handshaking protocol I used was syncronised, but I only used
the positive edge of the clock.
The AXI protocol used the positive edge of the clock to set the
control-signals and the negative edge of the clock to clear them.

NO NO NO STOP STOP STOP.

The AXI handshake protocols DO NOT do that. They are, like all good
synchronous logic should be, sensitive only to the rising edge of the
clock.

Hum. You are correct (as also noted by Rick). I misread the timing. My
error. My appologies.




What the AXI handshake protocol does is use the concept of "mutually
agreed upon". If at the rising clock edge a) the master has already
asserted VALID and b) the slave has already asserted READY, then the
information present on all the rest of the wires is agreed to have been
handed off from the master to the slave. Otherwise, that information
(if available) is still the master's responsibility.

Well, what I had was a bit like that.

I have a signal "load" (equivalent to "valid" in the AXI handshake) and
"done" (equivalent to "not ready" in AXI).

The master is the top-level module: the DDS module
The slave is a a module that writes out a value to the SPI interface.




The problem I had (at least in the simulator), was a timing-issue:

- In the AXI process, when the slave has received its data, it drops the
"ready" line, indicating that the slave is still working on the data it
has justreceived (in my case, it is still sending it out the SPI interface).


In the simulation of my design, this "drop ready line" event took 1
clock-cyclus. (the slave need to detect this bit-change, clear the
"ready" line and sends this signal back to the master)


- However, by the time that this signal did arrived at the master, the
master module had gone to the next steps in its FSM: "wait for the slave
to indicate it is ready to receive new data (i.e. ready is high), if
ready: continue".


As the "not ready" signal of the slave had not yet arrived, the
top-block happily said "ready line is high, so the slave is ready, so
let's go on".

And, and additional issue, as the FSM of the master had just checked the
"ready" signal, it simply went on to calculate the next DDS value and
then the "trigger the slave to read the next value" stage, all this
without without checking that signal again.



In short, the bug was the result of this assumption:
"When the slave notifies that the master that is not-ready to receive
any more data, this signal arrives in time for the state-machine of the
master to process it correctly."


In my case, that assumpion turned out to be wrong.




In my case, I fixed this with a small delay in the FSM, but I guess it
makes more sence to always do a "check if slave is ready" JUST BEFORE
sending the data to it.


Therefor my question for "do's and dont's" when designing a protocol
that controls dataflow between two modules.

I guess -especially if you are designing modules that get on github and
will be used by others- it is logical to apply more "strict" rules to
these parts of the code that interfaces with code written by other people.



Kristoff
 

Welcome to EDABoard.com

Sponsor

Back
Top