VHDL coding tips and tricks: Migrating from std_logic_vector to UNSIGNED or SIGNED data types

Saturday, March 27, 2010

Migrating from std_logic_vector to UNSIGNED or SIGNED data types

     Some days before I wrote another article about why the library "numeric_std" is preferred over "std_logic_arith" and others.In that article I have mentioned that use of synopsis IEEE library , such as STD_LOGIC_ARITH , STD_LOGIC_UNSIGNED and the like should be restricted unless you really need std_logic_vector in your design.If you want to know more about it click here.
     But most of the VHDL tutorial sites have examples based on the synopsis libraries.So as far as a beginner is concerned it is difficult for him to migrate suddenly from std_logic_arith to numeric_std.This article is for them.
In the earlier part of this blog I have written a code for BCD to 7- segment converter using the Synopsis IEEE library such as std_logic_arith and std_logic_unsigned.That article can be read here. I have written the same code in this article using the library NUMERIC_STD.There are only minor changes applied to the code,but still I think it will really help beginners.


Given below is the converter code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
---------------------------------
--use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
---------------------------------
use IEEE.NUMERIC_STD.ALL;

entity test is
port (
         clk : in std_logic;
------------------------------------------------------------------
--        bcd : in std_logic_vector(3 downto 0);  
--        segment7 : out std_logic_vector(6 downto 0); 
------------------------------------------------------------------
        bcd : in UNSIGNED(3 downto 0);
        segment7 : out UNSIGNED(6 downto 0)
    );
end test;

architecture Behavioral of test is

begin

process (clk,bcd)
BEGIN
if (clk'event and clk='1') then
case  bcd is
when "0000"=> segment7 <="0000001";
when "0001"=> segment7 <="1001111";
when "0010"=> segment7 <="0010010";
when "0011"=> segment7 <="0000110";
when "0100"=> segment7 <="1001100";
when "0101"=> segment7 <="0100100";
when "0110"=> segment7 <="0100000";
when "0111"=> segment7 <="0001111";
when "1000"=> segment7 <="0000000";
when "1001"=> segment7 <="0000100";
when others=> segment7 <="1111111";
end case;
end if;

end process;

end Behavioral;

The commented part of the code(shown in green colour) is from the original code given here.

The testbench of the above code is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
---------------------------------
--use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
---------------------------------
use IEEE.NUMERIC_STD.ALL;

ENTITY test_tb IS
END test_tb;

ARCHITECTURE behavior OF test_tb IS
   signal clk : std_logic := '0';
------------------------------------------------------------------     
--   signal bcd : std_logic_vector(3 downto 0) := (others => '0');
--   signal segment7 : std_logic_vector(6 downto 0);   
------------------------------------------------------------------
   signal bcd : UNSIGNED(3 downto 0) := (others => '0');
   signal segment7 : UNSIGNED(6 downto 0);
   constant clk_period : time := 1 ns;
BEGIN
   uut: entity work.test PORT MAP (clk,bcd,segment7);

   clk_process :process
   begin
                clk <= '0';
               wait for clk_period/2;
                clk <= '1';
                wait for clk_period/2;
   end process;    

   stim_proc: process
   begin  
------------------------------------------------------------------     
--      for i in 0 to 9  loop
--           bcd <= conv_std_logic_vector(i,4);
--          wait for 2 ns;
--      end loop;
------------------------------------------------------------------             
           bcd <=bcd + 1;
                if(bcd = "1001") then
                        bcd <="0000";
                end if;
          wait for 2 ns;
   end process;

END;

     So I hope, it is not that difficult to migrate to the official IEEE library.You can try changing the counter code given here, your own and see the results.If you have any difficulties doing so please contact me.

1 comment:

  1. For me UNSIGNED makes sense for bcd input but I found STD_LOGIC_VECTOR more appropriate for segment7 output. UNSIGNED does not make sense to me there.

    Thanks for your blog. Really useful many times.

    ReplyDelete