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; 
asked Nov 28, 2022 at 14:42
\$\endgroup\$
1
  • \$\begingroup\$ What book is this exercise from? It appears to be a variation of this. \$\endgroup\$ Commented 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
answered Mar 5, 2024 at 21:56
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.