3
\$\begingroup\$

I have finished my router and would like your thoughts about my code. I think it works well, but I'm not sure since I'm new to the VHDL world. Could someone please help me? Is my code correct?

enter image description here

enter image description here

SOURCE CODE




library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;


-- -------------------------
-- Entity 
-- -------------------------
entity mini_router is
   port (
         clk       : in  std_logic; 
         reset     : in  std_logic; -- Reset asincrono attivo basso
         data1     : in  std_logic_vector(9 downto 0); 
         req1      : in  std_logic; 
         grant1    : out std_logic;
         data2     : in  std_logic_vector(9 downto 0); 
         req2      : in  std_logic; 
         grant2    : out std_logic;
         data_out  : out std_logic_vector(7 downto 0); 
         valid     : out std_logic
        );
end entity;
  
  
-- -------------------------
-- Architecture 
-- -------------------------    
architecture arch of mini_router is  

-- signal for req control
   signal request    : std_logic_vector (1 downto 0);  
  
-- Signals to check the parity bits
   signal a          : std_logic; -- '1' se A < B altrimenti '0'
   signal b          : std_logic; -- '1' se A = B altrimenti '0'  
   signal c          : std_logic; -- '1' se A > B altrimenti '0'
  
-- Signal for round robin algoritm
   signal r          : std_logic; 
   

-- Comparator to check the parity bits
  component comparator is
     port (
            A           : in std_logic_vector(1 downto 0); 
            B           : in std_logic_vector(1 downto 0); 
            A_less_B    : out std_logic; 
            A_equal_B   : out std_logic;
            A_greater_B : out std_logic         
          );
   end component;
  
 
 begin
  request <= req1&req2;
  
   COMPARATORE: comparator
    port map ( 
      A           => data1 (1 downto 0),
      B           => data2 (1 downto 0),
      A_less_B    => a,
      A_equal_B   => b,
      A_greater_B => c
             );
 
 mini_router: process(clk,reset)
  
 begin

   if reset = '0' then
       data_out    <= (others => '0');
       grant1      <= '0';
       grant2      <= '0';   
       valid       <= '0';
       r           <= '0';
       
       
   elsif rising_edge(clk) then
   
 -- One req high
      if request = "10" then 
      
         data_out <= data1(9 downto 2);
         grant1   <= '1';
         grant2   <= '0';
         valid    <= '1';
    
     elsif request = "01" then 
  
         data_out <= data2(9 downto 2);
         grant1   <= '0';
         grant2   <= '1';
         valid    <= '1';

-- both req signals low     
     elsif request = "00" then  
     
          data_out <= (others => '0');
          grant1   <= '0';
          grant2   <= '0';
          valid    <= '0'; 
  
-- both req signals high
     elsif request = "11" then

-- link 1 has higher priority
        if c='1' then
        
           data_out  <= data1(9 downto 2);
           grant1    <= '1';
           grant2    <= '0';
           valid     <= '1';

-- link 2 has higher priority       
        elsif a='1' then
        
           data_out  <= data2(9 downto 2);
           grant1    <= '0';
           grant2    <= '1';
           valid     <= '1';
 
 -- Data conflict
        elsif b='1' then  
        
--  Round Robin arbiter
           if r = '0' then 
           
              data_out  <= data1(9 downto 2);
              grant1    <= '1';
              grant2    <= '0';
              valid     <= '1';
              r         <= '1';
  
           else 
           
              data_out  <= data2(9 downto 2);
              grant1    <= '0';
              grant2    <= '1';
              valid     <= '1';
              r         <= '0';
              
           end if;

        end if;

      end if; 
    
    end if; 
   
  end process;

end architecture;

TESTBENCH



library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;


-- -------------------------
-- Entity 
-- -------------------------
entity mini_router_tb is   
end mini_router_tb;

-- -------------------------
-- Architecture 
-- -------------------------
architecture arc of mini_router_tb is


    constant T_CLK      : time := 10 ns; 
     

    

    
    signal clk_tb      : std_logic := '0';
    signal reset_tb    : std_logic := '0';  
    signal data1_tb    : std_logic_vector(9 downto 0) := (others => '0');
    signal req1_tb     : std_logic:= '0'; 
    signal grant1_tb   : std_logic;
    signal data2_tb    : std_logic_vector(9 downto 0) := (others => '0');
    signal req2_tb     : std_logic:= '0'; 
    signal grant2_tb   : std_logic;
    signal data_out_tb : std_logic_vector(7 downto 0);
    signal valid_tb    : std_logic;
         
    signal end_sim : std_logic := '1'; 
    
    

    component mini_router is
    port (
         clk       : in  std_logic; 
         reset     : in  std_logic; 
         data1     : in  std_logic_vector(9 downto 0); 
         req1      : in  std_logic; 
         grant1    : out std_logic;
         data2     : in  std_logic_vector(9 downto 0); 
         req2      : in  std_logic; 
         grant2    : out  std_logic;
         data_out  : out std_logic_vector(7 downto 0); 
         valid     : out std_logic
        );
    end component;

  
begin

    clk_tb  <= (not(clk_tb)and(end_sim)) after T_CLK/2;

   -----------------------------------------------------------------------------------
    -- Mini - Router instantiation
    -----------------------------------------------------------------------------------
    DUT : mini_router
    port map ( 
        clk      => clk_tb,
        reset    => reset_tb,
        data1    => data1_tb,
        req1     => req1_tb,
        grant1   => grant1_tb,
        data2    => data2_tb,
        req2     => req2_tb,
        grant2   => grant2_tb,
        data_out => data_out_tb,
        valid    => valid_tb
             );


    stimuli_process: process(clk_tb, reset_tb)
    
         variable t  : integer   := 0;  -- variable used to count clock cicles
         begin  
         if (rising_edge(clk_tb)) then 
         
            case (t) is
                
                -- CASE 1:   
                   --          data1     = 5; req1=1
                   --          data2     = 5; req2=0
                   --          data_out  = 0; valid=0
                   --          grant1 = 0; 
                   --          grant2 = 0; 
            
                when  1     => data1_tb  <= (9 downto 3 => '0') & "101"; 
                               data2_tb  <= (9 downto 4 => '0') & "0101";
                               req1_tb   <= '1' ; req2_tb<= '0';
                               
                -- CASE 2:     
                   --          data1     = 4;  req1=1
                   --          data2     = 13; req2=0
                   --          data_out  = 1; valid=1
                   --          grant1 = 1; 
                   --          grant2 = 0;             
                               
                when  2     => reset_tb  <= '1';  
                               data1_tb  <= (9 downto 3 => '0') & "100"; 
                               data2_tb  <= (9 downto 4 => '0') & "1101";
                               req1_tb   <= '1' ; req2_tb<= '0';
                               
                -- CASE 3:     
                   --          data1     = 4;  req1=0
                   --          data2     = 13; req2=1
                   --          data_out  = 3; valid=1
                   --          grant1 = 0; 
                   --          grant2 = 1;  
                               
                             
                when  3     => data1_tb  <= (9 downto 3 => '0') & "100"; 
                               data2_tb  <= (9 downto 4 => '0') & "1101";
                               req1_tb   <= '0' ; req2_tb<= '1';
                               
                -- CASE 4:     
                --             
                   --          data1     = 7;  req1=1
                   --          data2     = 31; req2=1
                   --          data_out  = 1; valid=1
                   --          grant1 = 1; 
                   --          grant2 = 0;  
                               
                             
                when  4     => data1_tb  <= (9 downto 5 => '0') & "00111"; 
                               data2_tb  <= (9 downto 5 => '0') & "11111";  
                               req1_tb   <= '1' ; req2_tb<= '1';
                               
                -- CASE 5:    
                --             data1 CHOSEN
                   --          data1     = 23; req1=1
                   --          data2     = 29; req2=1
                   --          data_out  = 5; valid=1
                   --          grant1 = 1; 
                   --          grant2 = 0;  
                               
                                
                when  5     => data1_tb  <= (9 downto 5 => '0') & "10111"; 
                               data2_tb  <= (9 downto 5 => '0') & "11101";  
                               req1_tb   <= '1' ; req2_tb<= '1';
                               
                -- CASE 6:     
                --             
                --             data2 chosen
                   --          data1     = 22; req1=1
                   --          data2     = 30; req2=1
                   --          data_out  = 7; valid=1
                   --          grant1 = 0; 
                   --          grant2 = 1;  
                             
                when 6      => data1_tb  <= (9 downto 5 => '0') & "10110"; 
                               data2_tb  <= (9 downto 5 => '0') & "11110"; 
                               req1_tb   <= '1' ; req2_tb<= '1';    
                               
                -- CASE 7:    
                   --          data1     = 7;  req1=0
                   --          data2     = 31; req2=0
                   --          data_out  = 0; valid=0
                   --          grant1 = 0; 
                   --          grant2 = 0; 
                               
                                
                when 7      => data1_tb  <= (9 downto 5 => '0') & "00111"; 
                               data2_tb  <= (9 downto 5 => '0') & "11111"; 
                               req1_tb   <= '0' ; req2_tb<= '0';

                -- CASE 8:    
                --             data2 chosen
                   --          data1     = 28; req1=1
                   --          data2     = 13; req2=1
                   --          data_out  = 3; valid=1
                   --          grant1 = 0; 
                   --          grant2 = 1;                 
                               
                            
                when  8     => data1_tb  <= (9 downto 5 => '0') & "11100"; 
                               data2_tb  <= (9 downto 4 => '0') & "1101"; 
                               req1_tb   <= '1' ; req2_tb <= '1';
                               
                -- CASE 9:     
                --             
                --             data1 chosen
                   --          data1     = 22; req1=1
                   --          data2     = 30; req2=1
                   --          data_out  = 5; valid=1
                   --          grant1 = 1; 
                   --          grant2 = 0; 
                               
                 
                when 9      => data1_tb  <= (9 downto 5 => '0') & "10110"; --data1=22; data_out =5
                               data2_tb  <= (9 downto 5 => '0') & "11110"; -- data2= 30; data_out non assunto=7
                               req1_tb   <= '1' ; req2_tb<= '1';
                               
                -- CASE 10:   
                --             
                --             data2 chosen
                   --          data1     = 22; req1=1
                   --          data2     = 30; req2=1
                   --          data_out  = 7; valid=1
                   --          grant1 = 0; 
                   --          grant2 = 1; 
                               
                
                when 10     => data1_tb  <= (9 downto 5 => '0') & "10110"; --data1=22; data_out non assunto =5
                               data2_tb  <= (9 downto 5 => '0') & "11110"; -- data2= 30; data_out =7
                               req1_tb   <= '1' ; req2_tb<= '1';
                               
                                            
                when 11     => end_sim   <= '0'; -- end of the simulation
                when others => null; 
                         
            end case;

            t := t + 1;
        
          end if;           
     end process;
end architecture;

SOURCE FILE FOR COMPARATOR

  



library IEEE;
use IEEE.std_logic_1164.all;

-- -------------------------
-- Entity 
-- -------------------------
entity comparator is
  port (
         A          : in std_logic_vector(1 downto 0); 
         B          : in std_logic_vector(1 downto 0); 
         A_less_B   : out std_logic; -- '1' IF A < B
         A_equal_B  : out std_logic; -- '1' IF A = B
         A_greater_B: out std_logic  -- '1' IF A > B 
        );
end entity;

-- -------------------------
-- Architecture 
-- -------------------------    
architecture arc of comparator is

  signal aux1: std_logic; 
  signal aux2: std_logic; 
  signal aux3: std_logic; 
  signal aux4: std_logic; 
  signal aux5: std_logic; 
  signal aux6: std_logic; 
  signal aux7: std_logic; 
  signal aux8: std_logic; 

   begin
   
 -- A_equal_B combinational logic circuit
 aux1        <= A(1) xnor B(1);
 aux2        <= A(0) xnor B(0);
 A_equal_B   <= aux1 and aux2;
 
 -- A_less_B combinational logic circuit
 aux3        <= (not A(0)) and (not A(1)) and B(0);
 aux4        <= (not A(1)) and B(1);
 aux5        <= (not A(0)) and B(1) and B(0);
 A_less_B    <= aux3 or aux4 or aux5;
 
 -- A_greater_B combinational logic circuit
 aux6        <= (not B(0)) and (not B(1)) and A(0);
 aux7        <= (not B(1)) and A(1);
 aux8        <= (not B(0)) and A(1) and A(0);
 A_greater_B <= aux6 or aux7 or aux8;
 
end architecture;        
\$\endgroup\$
1
  • \$\begingroup\$ What book is this exercise from? It appears to be a variation of this. \$\endgroup\$
    – Mast
    Nov 29, 2022 at 16:11

1 Answer 1

2
\$\begingroup\$

Testing

The testbench covers a nice variety of input combinations. The next step is to add VHDL code to the testbench to make it self-checking. You could add a process which is triggered on the falling_edge of the clock, when the output signals are stable. It looks like you already have the expected output values in the comments in the case statement.

You could encapsulate each case item into a procedure, where you pass in the input data, the requests and expected output. This way, you can easily add many more input combinations.

Comments

Several of the comments are not needed, such as these:

-- Entity 

-- Architecture 

They just repeat the VHDL keywords of the same name. It would be better to add comments which describe the functionality of the design.

Tabs

The code mixes tab characters with single spaces on the same line. This can cause the code to appear with inconsistent indentation by different code viewers (editors, source code browsers, etc.). Replace the tabs with spaces.

Indentation

Indentation is inconsistent; some lines have 2 spaces, some 3, some 4, etc. I recommend 4 spaces for each level of indentation.

Blank lines

There are too many blank lines in the code. There is no need to use groups of blank lines (2 or more together).

Typo

algoritm should be algorithm:

-- Signal for round robin algoritm

In the testbench, cicles should be cycles.

     variable t  : integer   := 0;  -- variable used to count clock cicles
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.