Monday, March 31, 2014

some basic VHDL syntax

1) entity
library ieee;
use ieee.std_logic_1164.all;
entity dataProcess is
port (
    din  : in std_logic_vector(7 downto 0);
    dout : out std_logic_vector(7 downto 0);
    dio  : inout std_logic
);
end entity dataProcess;
architecture behavioral of dataProcess is
begin
end behavioral;

2) combinational logic
library ieee;
use ieee.std_logic_1164.all;

entity clkGen is
port (
    clk  : in std_logic;
    mode : in std_logic;
    sclk : out std_logic
);
end entity clkGen;
architecture behavioral of clkGen is
signal clk_en : std_logic;
begin

--generate sclk
sclk <= clk when clk_en = '1' else '0';

process(mode)
begin
    case mode is
        when '0' =>
            clk_en <= '0';
        when '1' =>
            clk_en <= '1';
        when others =>
            clk_en <= '0';
    end case;
end process;

end behavioral;

3) timing logic
library ieee;
use ieee.std_logic_1164.all;

entity dff_1 is
port (
    clk   : in std_logic;
    rst_n : in std_logic;
    din   : in std_logic;
    dout  : out std_logic
);
end entity dff_1;
architecture behavioral of dff_1 is
begin

process(clk, rst_n)
begin
    if(rst_n = '0') then
        dout <= '0';
    elsif(clk'event and clk = '1')  then
    -- elsif(rising_edge(clk)) then
        dout <= din;
    end if;
end process;

end behavioral;

4) tristate gate
library ieee;
use ieee.std_logic_1164.all;

entity dataProcess is
port (
    sclk  : in std_logic;
    rst_n : in std_logic;
    rw    : in std_logic;
    sdio  : inout std_logic
);
end entity dataProcess;

architecture behavioral of dataProcess is
signal sdi    : std_logic;
signal sdo    : std_logic;
signal sdo_en : std_logic;
signal data   : std_logic_vector(7 downto 0);
begin
    --generate sdio
    sdio <= sdo when sdo_en = '1' else 'Z';

    sdi  <= sdio;

    process(sclk, rst_n)
    begin
        if(rst_n = '0') then
            data <= (others => '0');
        elsif(rising_edge(sclk)) then
            if(rw = '0') then
                data <= data(6 downto 0) & sdi;
            else
                data <= data(6 downto 0) & '0';
            end if;
        end if;
    end process;

    process(sclk, rst_n)
    begin
        if(rst_n = '0') then
            sdo <= '0';
            sdo_en <= '0';
        elsif(rising_edge(sclk)) then
            if(rw = '1') then
                sdo    <= data(7);
                sdo_en <= '1';
            else
                sdo <= '0';
                sdo_en <= '0';
            end if;
        end if;
    end process;

end behavioral;

5) package with function
-------------------------------------------------------
-- package user_pkg
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

package user_pkg is
function to_stdulogic(V: Boolean) return std_ulogic;

end;

package body user_pkg is
--function to convert boolean to std_logic
function to_stdulogic(V: Boolean) return std_ulogic is
begin
    if V then
        return '1';
    else
        return '0';
    end if;
end to_stdulogic;

end package body;

-------------------------------------------------------
-- entity calling package
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.user_pkg.all;

entity test_package is
port (
    clk       : in  std_logic;
    rst_n     : in  std_logic;
    mode      : in  std_logic;
    mode_trig : out std_logic
);
end entity test_package;

architecture behavioral of test_package is
--signal declaration in architecture
signal mode_ff1    : std_logic;
signal mode_ff2    : std_logic;
signal mode_ff3    : std_logic;

--begin of architecture
begin

process(clk, rst_n)
begin
    if(rst_n = '0') then
        mode_ff1 <= '0';
        mode_ff2 <= '0';
        mode_ff3 <= '0';
    elsif(clk'event and clk = '1') then
        mode_ff1 <= mode;
        mode_ff2 <= mode_ff1;
        mode_ff3 <= mode_ff2;
    end if;
end process;

mode_trig <= to_stdulogic((mode_ff2 = '0') and (mode_ff3 = '1'));

end behavioral;

6) package with procedure
-------------------------------------------------------
-- package user_pkg
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

package user_pkg is
procedure segment_dec (signal bcd: in std_logic_vector(3 downto 0); signal segment : out std_logic_vector(6 downto 0));

end;

package body user_pkg is

procedure segment_dec (
    signal bcd: in std_logic_vector(3 downto 0);
    signal segment : out std_logic_vector(6 downto 0)
) is
begin
    case bcd is
        --decode from bcd to segment
        when x"0" => segment <= b"1000000";
        when x"1" => segment <= b"1111001";
        when x"2" => segment <= b"0100100";
        when x"3" => segment <= b"0110000";
        when x"4" => segment <= b"0011001";
        when x"5" => segment <= b"0010010";
        when x"6" => segment <= b"0000010";
        when x"7" => segment <= b"1111000";
        when x"8" => segment <= b"0000000";
        when x"9" => segment <= b"0010000";
        when others => segment <= b"1000000";
    end case;
end procedure segment_dec;

end package body;

-------------------------------------------------------
-- entity calling package
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.user_pkg.all;

entity bcd2segment is
port (
    bcd     : in std_logic_vector(3 downto 0);
    segment : out std_logic_vector(6 downto 0)
);
end entity bcd2segment;

architecture behavioral of bcd2segment is

begin

process(bcd)
begin
    segment_dec(bcd, segment);
end process;

end behavioral;

7) generic
-----------------------------------------------------------------
--clk dividor
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity clk_div is
generic (
    N: integer := 12499999
);
port (
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    clk_out : out std_logic
);
end entity clk_div;

architecture behavioral of clk_div is
signal clk_cnt     : integer range 0 to N;
signal clk_out_tmp : std_logic;
begin
--counter for half second
process(clk, rst_n)
begin
    if(rst_n = '0')then
        clk_cnt <= 0;
        clk_out_tmp <= '0';
    elsif(clk'event and clk = '1')  then
        --when counter reaches to half second,
        --need to reset the counter to 0
        if(clk_cnt = N) then
            clk_cnt <= 0;
            clk_out_tmp <= not (clk_out_tmp);
        else
            clk_cnt <= clk_cnt + 1;
            clk_out_tmp <= clk_out_tmp;
        end if;
    end if;
end process;

clk_out <= clk_out_tmp;

end behavioral;

-----------------------------------------------------------------
--top
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
generic (
    N: integer := 20
);
port (
    clk      : in  std_logic;
    rst_n    : in  std_logic;
    clk_out  : out std_logic
);
end entity top;

architecture behavioral of top is

component clk_div is
generic (
    N: integer := 12499999
);
port (
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    clk_out : out std_logic
);
end component;

--begin of architecture
begin

--instance clock dividor
u_clk_div: clk_div generic map (
    N => N
) PORT MAP (
    clk     => clk     ,
    rst_n   => rst_n   ,
    clk_out => clk_out
);

end behavioral;
--end of architecture

8) instance component
-----------------------------------------------------------------
--clk dividor
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity clk_div is
port (
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    clk_out : out std_logic
);
end entity clk_div;

architecture behavioral of clk_div is
signal clk_out_tmp : std_logic;
begin
--counter for half second
process(clk, rst_n)
begin
    if(rst_n = '0')then
        clk_out_tmp <= '0';
    elsif(clk'event and clk = '1')  then
        clk_out_tmp <= not clk_out_tmp;
    end if;
end process;

clk_out <= clk_out_tmp;

end behavioral;

-----------------------------------------------------------------
--top
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
port (
    clk      : in  std_logic;
    rst_n    : in  std_logic;
    clk_out  : out std_logic
);
end entity top;

architecture behavioral of top is

component clk_div is
port (
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    clk_out : out std_logic
);
end component;

--begin of architecture
begin

--instance clock dividor
u_clk_div: clk_div PORT MAP (
    clk     => clk     ,
    rst_n   => rst_n   ,
    clk_out => clk_out
);

end behavioral;

9) generate
library ieee;
use ieee.std_logic_1164.all;

entity bcd2segment is
generic (
    M: integer := 7
);
port (
    bcd     : in std_logic_vector(3 downto 0);
    segment : out std_logic_vector(M-1 downto 0)
);
end entity bcd2segment;

architecture behavioral of bcd2segment is

begin

SEGMENT_WITHOUT_DP: if M=7 generate
process(bcd)
begin
    case bcd is
        --decode from bcd to segment
        when x"0" => segment <= b"1111111";
        when x"1" => segment <= b"1111001";
        when x"2" => segment <= b"0100100";
        when x"3" => segment <= b"0110000";
        when x"4" => segment <= b"0011001";
        when x"5" => segment <= b"0010010";
        when x"6" => segment <= b"0000010";
        when x"7" => segment <= b"1111000";
        when x"8" => segment <= b"0000000";
        when x"9" => segment <= b"0010000";
        --when in selector 1, counter should add 1 after each half second
        --for other unknown selectors, set counter to 0
        when others => segment <= b"1111111";
    end case;
end process;

end generate SEGMENT_WITHOUT_DP;

SEGMENT_WITH_DP: if M=8 generate
process(bcd)
begin
    case bcd is
        --decode from bcd to segment
        when x"0" => segment <= b"11111111";
        when x"1" => segment <= b"11111001";
        when x"2" => segment <= b"10100100";
        when x"3" => segment <= b"10110000";
        when x"4" => segment <= b"10011001";
        when x"5" => segment <= b"10010010";
        when x"6" => segment <= b"10000010";
        when x"7" => segment <= b"11111000";
        when x"8" => segment <= b"10000000";
        when x"9" => segment <= b"10010000";
        --when in selector 1, counter should add 1 after each half second
        --for other unknown selectors, set counter to 0
        when others => segment <= b"11111111";
    end case;
end process;

end generate SEGMENT_WITH_DP;

end behavioral;

31) testbench
-----------------------------------------------------------------
--DUT
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

package user_pkg is
procedure new_logic (signal A, B, CIN: in std_logic; signal S, COUT : out std_logic);
end package;

package body user_pkg is

procedure new_logic (
    signal A, B, CIN: in std_logic;
    signal S, COUT : out std_logic
) is
begin
    S <= (A xor B) xor CIN;
    COUT <= (A and B) or ((A xor B) and CIN);
end procedure new_logic;

end package body;

library ieee;
use ieee.std_logic_1164.all;
library work;
use work.user_pkg.all;

entity adder is
port (
    clk    : in  std_logic                    ;
    rst_n  : in  std_logic                    ;
    enable : in  std_logic                    ;
    a      : in  std_logic_vector(3 downto 0) ;
    b      : in  std_logic_vector(3 downto 0) ;
    s      : out std_logic_vector(3 downto 0) ;
    cout   : out std_logic                    
);
end entity adder;

architecture behavioral of adder is
signal c : std_logic_vector(3 downto 0);
signal s_tmp : std_logic_vector(3 downto 0);
signal cout_tmp : std_logic;

begin

c(0) <= '0';
process(a, b, c)
begin
    new_logic(a(0), b(0), c(0), s_tmp(0), c(1));
    new_logic(a(1), b(1), c(1), s_tmp(1), c(2));
    new_logic(a(2), b(2), c(2), s_tmp(2), c(3));
    new_logic(a(3), b(3), c(3), s_tmp(3), cout_tmp);
end process;

process(clk, rst_n)
begin
    if(rst_n = '0') then
        s <= x"0";
        cout <= '0';
    elsif(clk'event and clk = '0') then
        if(enable = '1') then
            s <= s_tmp;
            cout <= cout_tmp;
        end if;
    end if;
end process;

end behavioral;

-----------------------------------------------------------------
--tb
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.all;

entity tb_adder is
end entity tb_adder;

architecture behavioral of tb_adder is
component adder is
port (
    clk    : in  std_logic                    ;
    rst_n  : in  std_logic                    ;
    enable : in  std_logic                    ;
    a      : in  std_logic_vector(3 downto 0) ;
    b      : in  std_logic_vector(3 downto 0) ;
    s      : out std_logic_vector(3 downto 0) ;
    cout   : out std_logic                  
);
end component;

signal clk    : std_logic                    ;
signal rst_n  : std_logic                    ;
signal enable : std_logic                    ;
signal a      : std_logic_vector(3 downto 0) ;
signal b      : std_logic_vector(3 downto 0) ;
signal s      : std_logic_vector(3 downto 0) ;
signal cout   : std_logic                    ;

begin

u_adder: adder port map (
    clk    => clk    ,
    rst_n  => rst_n  ,
    enable => enable ,
    a      => a      ,
    b      => b      ,
    s      => s      ,
    cout   => cout
);

process
begin
    clk <= '0';
    wait for 6.67 ns;
    clk <= '1';
    wait for 6.67 ns;
end process;

process
variable i, j, k: integer;
begin
    rst_n <= '0';
    wait for 600 ns;
    rst_n <= '1';
    wait;
end process;

process
variable i, j, k: integer;
begin
    enable <= '0';
    a <= x"0";
    b <= x"0";
    wait until rst_n'event and rst_n = '1';
    wait until clk'event and clk = '0';
    for i in 0 to 15 loop
        for j in 0 to 15 loop
            wait until clk'event and clk = '0';
            a <= std_logic_vector(to_unsigned(i, a'length));
            b <= std_logic_vector(to_unsigned(j, b'length));
            enable <= '0';
            wait until clk'event and clk = '0';
            enable <= '1';
        end loop;
    end loop;
    wait for 100 ns;
    finish(0);
end process;

end behavioral;

No comments:

Post a Comment