Search code examples
vhdl

How do I reduce redundancy in state logic for repeated processes (handshakes)?


I'm working with an IP that uses the AXI Lite protocol. The read/write handshakes take up a few states in my state diagram. The problem is that I have to create the same set of state for each handshake in the state diagram, which is really redundant. Is there a way I can reduce redundancy?

I have tried writing the handshakes into a function. However, because I'm setting and reading signals from within the function, the code will not synthesize. I've considered turning the handshakes into separate processes and using a flag to denote whether they are busy or not.

Sample Read Handshake:

case state is
    when 0 =>
        if arready = '0' then
            arvalid <= '1';
            rready <= '1';
            araddr <= SOME_ADDRESS
        else
            arvalid <= '0';
            state := 1;
    when 1 =>
        if rvalid = '1' then
            SOME_SIGNAL_STD_LOGIC_VECTOR <= rdata;
            rready <= '0';
            state := THE_NEXT_STATE;



Solution

  • I ended up using a master-slave FSM as suggested by Matthew Taylor in the comments: How do I reduce redundancy in state logic for repeated processes (handshakes)?.

    The redundant code was stored in a separate 'slave' process. The redundant code runs only when the 'master' kickstarts the slave process (ie asserting a slave_start signal low -> high).

    Here's a generic overview I came up with to facilitate the master-slave configuration:

    1. The master FSM sets any appropriate signals used in the slave process, asserts a slave_start signal high, and waits for the slave process.
    2. The slave reads the slave_start as high and begins to process data.
    3. The slave asserts a slave_done signal high.
    4. The master reads the slave_done as high and asserts slave_start low. The master moves on to the next state in the FSM.
    5. The slave asserts slave_done low to get ready for next 'kickstart.'