VHDL arbiter – part III

This is the third part of a series of articles on VHDL arbiters.

In the first part, we talked about what a VHDL arbiter is.

In the second part, we saw the VHDL code for a fixed-priority VHDL arbiter.

When I talked about what a VHDL arbiter is, I gave the example of the single car we had at home, and how I had to decide who gets to use the car next Friday evening. In a typical situation, if both children ask for the car, the first thing they will account for is, who got the car the last time.

The fixed priority arbiter is the equivalent of always giving your car to the same child. It will, no doubts, create problems. If you don’t want to create problems, you will make a balanced assignment of the valued resource between the solicitors.

And again, in HW is just the same. If several intelligent devices want to reach a common bus or a common memory, in most cases you will want to give them equal access. The arbiter we present in this part of the series does just that. It enables all solicitors to get equal access. It does that using what is called a round-robin strategy.

The round-robin strategy is best illustrated in an ‘all begging’ situation. Imagine that each time the arbiter decides to give the resource to one solicitor, all of them are claiming it. The first time, the arbiter gives the resource to master 0. The next time it has to decide, all masters ask for the resource, but this time, the round-robin arbiter gives the resource to master 1. On the next arbitration opportunity, to master 2. Etc.

Enough talk, let’s see the code and simulation.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity arbiter_rr is
	port (
		clk: 		in std_logic;
		rstn: 		in std_logic;
		
		-- inputs
		req:		in std_logic_vector;
		
		-- outputs
		gnt:		out std_logic_vector
	);
end arbiter_rr;

architecture rtl of arbiter_rr is

	signal double_req : unsigned(2*req'left+1 downto 0);
	signal double_gnt : unsigned(2*req'left+1 downto 0);
	signal priority : unsigned(req'left downto 0);
	signal last_req : std_logic_vector(req'left downto 0);
	
	begin 

double_req	<= unsigned(req & req);
double_gnt  <= double_req and not (double_req-priority);	

arbiter_pr: process (clk) 
	begin 
    if (rising_edge(clk)) then
      if (rstn = '0') then 
        priority(req'left downto 1) <= (others => '0');
        priority(0)	<= '1';
        last_req	  <= (others => '0');
        gnt			    <= (others => '0');
      elsif (last_req /= req) then
        priority(req'left downto 1) <= priority(req'left-1 downto 0);
        priority(0) <= priority(req'left);
        last_req	  <= req;
        gnt 		    <= std_logic_vector(double_gnt(req'left downto 0) or double_gnt(2*req'left+1 downto req'left+1));
      end if;	
    end if;
end process arbiter_pr;

end rtl;

A core signal for the implementation of the round-robin strategy is priority. This array tells the arbiter where to start looking for in the queue of solicitors. As you can see on lines 39 and 40 of the VHDL source code, when the arbiter makes a new decision, it rotates the priority array. By rotating the priority array, each master goes one step further into the queue. The master that had the highest priority, goes to the tail of the queue.

Another key of the algorithm is on line 28. The logic of this line ensures that double_gnt will have only one bit asserted. You are invited to analyze by yourself two scenarios:

  • What is the value of double_gnt when the request signal is asserted for the same master currently elected on the priority array?
  • And what is the value of double_gnt when the request signal currently elected on the priority array is not asserted?

The priority mechanism takes into account only the masters that are asserting their req lines. Even if a master is at the tail of the queue, if it is the only one asking for the resource, it will get it. The priority mechanism is important only when there are several masters with req asserted. The master with the highest priority requesting the resource will receive gnt.

In the simulation below we can see several situations where more than one master asserts their request lines. The first marker (@670ns) indicates a situation where master 2 and master 1 ask for the resource, and it is given to master 2. Later on (second marker @830ns), both masters assert their req lines again, but this time, it is granted to master 1.

The VHDL source and testbench files for the round-robin arbiter are available on GitHub

In part IV of this tutorial, we will talk about advanced simulation

Leave a Reply

Your email address will not be published. Required fields are marked *