0

I'm designing a relatively simple memory arbiter, with two states.

  • State 1: Port 1 is connected to the memory (default state)
  • State 2: Port 2 is connected to the memory (only if there are requests)

The simulation in ModelSim works just fine and proves that my arbiter operates as required. However I was told that code I've written is not synthesizable. I've included the relevant process' code below.

The enable signal goes high upon request, and setting the enable signal low acknowledges that port has been served. Requirement is that if there are two simultaneous requests, port 2 should be connected. However if port 1 is already connected due to previous request, the port 2 should wait until port 1 has been served.

My questions are:

  1. What are problems with the code that I've written (and why)?
  2. What would be your approach for making this code synthesizable (not aksing for final solution, but hopefully for useful hints)

the relevant process' code

Because of the problem with formatting the code part of this post I've included code as image as well.

transition: process (clk)
begin
        if rising_edge(clk) then

           if reset = '1' then    
              state <=  port1;
           else
               if (state = port1) and (req_p2.enable='1') and 
                  (req_p1.enable='0' or rising_edge(req_p1.enable)) then
                  state <= port2;

               elsif(state = port2) and (req_p2.enable='0') then
                  state <= port1;
               end if;
           end if;

        end if;
end process;
balboa
  • 951
  • 8
  • 20
  • 1
    Looks synthesisable to me. Synthesise it and report any real problems (not "I've been told") here. I'm assuming something actually *uses* `state` otherwise, after synthesis, it'll be optimised away to nothing. –  Nov 22 '16 at 18:43

1 Answers1

2

This line of your code is not synthesisable:

rising_edge(req_p1.enable)

To make it synthesisable you need to replace the rising_edge function with some actual logic that detects a rising edge - a synchronous rising edge detector. Something along the lines of this should work (I don't know your requirements):

sync_rising_edge: process (clk)
begin
  if rising_edge(clk) then
     if reset = '1' then    
        req_p1_enable_d <=  '0';
     else
        req_p1_enable_d <= req_p1.enable;
     end if;
  end if;
end process;

transition: process (clk)
begin
        if rising_edge(clk) then

           if reset = '1' then    
              state <=  port1;
           else
               if (state = port1) and (req_p2.enable='1') and 
                  (req_p1.enable='0' or (req_p1_enable_d = '0' and req_p1.enable = '1')) then
                  state <= port2;

               elsif(state = port2) and (req_p2.enable='0') then
                  state <= port1;
               end if;
           end if;

        end if;
end process;

The rising_edge function is synthesisable if there it is used in the conventional way inside a clocked process. See my answer here.

Community
  • 1
  • 1
Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
  • 1
    To clarify, `rising_edge(req_p1.enable)` is synthesisable in its own right, but what the question has is `if rising_edge(clk) then if (rising_edge(req_p1.enable)) then`, i.e. two nested edge sensitive cases, and it's this that is not synthesisable (commenting for the benefit of the asker) – scary_jeff Nov 23 '16 at 09:15
  • Thank you @scary_jeff. I'll clarify my answer. – Matthew Taylor Nov 23 '16 at 09:50