Design Technology | High Level Synthesis | How Does Synthagate work | Funcmi.vhd

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

entity Funcmi is
    port (
        bit0          : in std_logic;
        clk           : in std_logic;
        codcomplete   : out std_logic;
        decodcomplete : out std_logic;
        dma           : in std_logic;
        ext_adr       : in std_logic_vector(15 downto 0);
        ext_in        : out std_logic_vector(7 downto 0);
        ext_out       : in std_logic_vector(7 downto 0);
        ext_rdwr      : in std_logic;
        idle          : out std_logic;
        m             : in std_logic;
        nelem         : in std_logic_vector(15 downto 0);
        rst           : in std_logic;
        rwrite2m2     : out std_logic_vector(15 downto 0);
        rwrite2m3     : out std_logic_vector(15 downto 0);
        s             : in std_logic
    );
end Funcmi;

architecture ARC_Funcmi of Funcmi is

    type FSMStates is (
        a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, 
        a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, 
        a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, 
        a46, a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, 
        a61, a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, 
        a76, a77
    );
    type m1_type is array (integer range 0 to 65535) of std_logic_vector(7 downto 0);
    type m2_type is array (integer range 0 to 65535) of std_logic_vector(7 downto 0);
    type m3_type is array (integer range 0 to 65535) of std_logic_vector(7 downto 0);

    signal bitcnt : std_logic_vector(3 downto 0);
    signal br : std_logic_vector(7 downto 0);
    signal cnt : std_logic_vector(7 downto 0);
    signal cnt_elem : std_logic_vector(15 downto 0);
    signal cnt_m1_m3 : std_logic_vector(15 downto 0);
    signal cnt_m2 : std_logic_vector(15 downto 0);
    signal currentState : FSMStates;
    signal m1 : m1_type;
    signal m2 : m2_type;
    signal m3 : m3_type;
    signal mac1 : std_logic_vector(15 downto 0);
    signal mac2 : std_logic_vector(15 downto 0);
    signal rbyte : std_logic_vector(7 downto 0);
    signal rd : std_logic_vector(7 downto 0);
    signal relem : std_logic_vector(15 downto 0);
    signal rfilelength : std_logic_vector(15 downto 0);
    signal rlengthd : std_logic_vector(7 downto 0);
    signal rmask : std_logic_vector(7 downto 0);
    signal rmax : std_logic_vector(7 downto 0);
    signal rmin : std_logic_vector(7 downto 0);
    signal rt1 : std_logic_vector(7 downto 0);
    signal rt2 : std_logic_vector(7 downto 0);
    signal rtemp1 : std_logic_vector(15 downto 0);
    signal shcnt : std_logic_vector(7 downto 0);

begin

    process (clk , rst)

        variable m1_address : std_logic_vector(15 downto 0);
        variable m2_address : std_logic_vector(15 downto 0);
        variable m3_address : std_logic_vector(15 downto 0);

    procedure proc_Funcmi is 
    begin


    case currentState is
    when a1 =>
        if (s and dma and ext_rdwr) = '1' then
            m1_address := ext_adr;
            m1(to_integer(unsigned(m1_address))) <= ext_out;
            currentState <= a2;

        elsif (s and dma and not ext_rdwr and m) = '1' then
            m3_address := ext_adr;
            currentState <= a3;

        elsif (s and dma and not ext_rdwr and not m) = '1' then
            m2_address := ext_adr;
            currentState <= a4;

        elsif (s and not dma and bit0) = '1' then
            decodcomplete <= '0';
            currentState <= a5;

        elsif (s and not dma and not bit0) = '1' then
            relem <= nelem;
            codcomplete <= '0';
            currentState <= a6;

        else
            currentState <= a1;
            idle <= '1';

        end if;

    when a2 =>
        
            cnt_m1_m3 <= std_logic_vector(unsigned(cnt_m1_m3) + 1);
            currentState <= a1;
            idle <= '1';

    when a3 =>
        
            m3_address := ext_adr;
            ext_in <= m3(to_integer(unsigned(m3_address)));
            currentState <= a1;
            idle <= '1';

    when a4 =>
        
            m2_address := ext_adr;
            ext_in <= m2(to_integer(unsigned(m2_address)));
            currentState <= a1;
            idle <= '1';

    when a5 =>
        
            mac2 <= (others => '0');
            decodcomplete <= '0';
            currentState <= a7;

    when a6 =>
        
            mac2 <= (others => '0');
            br <= x"ff";
            cnt <= (others => '0');
            cnt_m2 <= (others => '0');
            currentState <= a8;

    when a7 =>
        
            m2_address := mac2;
            currentState <= a9;

    when a8 =>
        
            m2_address := mac2;
            m2(to_integer(unsigned(m2_address))) <= br;
            cnt_m2 <= std_logic_vector(unsigned(cnt_m2) + 1);
            currentState <= a10;

    when a9 =>
        
            br <= m2(to_integer(unsigned(m2_address)));
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a11;

    when a10 =>
        
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a12;

    when a11 =>
        if (br = x"ff") then
            m2_address := mac2;
            currentState <= a13;

        else
            m2_address := mac2;
            currentState <= a9;

        end if;

    when a12 =>
        if (cnt = x"03") then
            rfilelength <= cnt_m1_m3;
            currentState <= a14;

        else
            cnt <= std_logic_vector(unsigned(cnt) + 1);
            currentState <= a8;

        end if;

    when a13 =>
        
            br <= m2(to_integer(unsigned(m2_address)));
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a15;

    when a14 =>
        
            cnt_elem <= (others => '0');
            rtemp1 <= mac1;
            currentState <= a16;

    when a15 =>
        if (br = x"ff") then
            m2_address := mac2;
            currentState <= a17;

        else
            m2_address := mac2;
            currentState <= a9;

        end if;

    when a16 =>
        
            m1_address := mac1;
            currentState <= a18;

    when a17 =>
        
            br <= m2(to_integer(unsigned(m2_address)));
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a19;

    when a18 =>
        
            br <= m1(to_integer(unsigned(m1_address)));
            mac1 <= std_logic_vector(unsigned(mac1) + 1);
            currentState <= a20;

    when a19 =>
        if (br = x"ff") then
            m2_address := mac2;
            currentState <= a21;

        else
            m2_address := mac2;
            currentState <= a9;

        end if;

    when a20 =>
        
            rmax <= br;
            rmin <= br;
            cnt_elem <= std_logic_vector(unsigned(cnt_elem) + 1);
            currentState <= a22;

    when a21 =>
        
            br <= m2(to_integer(unsigned(m2_address)));
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a23;

    when a22 =>
        
            m1_address := mac1;
            currentState <= a24;

    when a23 =>
        if (br = x"ff") then
            mac1 <= (others => '0');
            shcnt <= (others => '0');
            currentState <= a25;

        else
            m2_address := mac2;
            currentState <= a9;

        end if;

    when a24 =>
        
            br <= m1(to_integer(unsigned(m1_address)));
            mac1 <= std_logic_vector(unsigned(mac1) + 1);
            currentState <= a26;

    when a25 =>
        
            m2_address := mac2;
            currentState <= a27;

    when a26 =>
        if (br >= rmax) then
            rmax <= br;
            currentState <= a28;

        elsif (not (br >= rmax) and br <= rmin) then
            rmin <= br;
            currentState <= a28;

        elsif (not (br >= rmax) and not (br <= rmin) and cnt_elem = std_logic_vector(unsigned(relem) - x"0001")) then
            br <= rmin;
            currentState <= a29;

        else
            cnt_elem <= std_logic_vector(unsigned(cnt_elem) + 1);
            currentState <= a22;

        end if;

    when a27 =>
        
            br <= m2(to_integer(unsigned(m2_address)));
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a30;

    when a28 =>
        if (cnt_elem = std_logic_vector(unsigned(relem) - x"0001")) then
            br <= rmin;
            currentState <= a29;

        else
            cnt_elem <= std_logic_vector(unsigned(cnt_elem) + 1);
            currentState <= a22;

        end if;

    when a29 =>
        
            m2_address := mac2;
            m2(to_integer(unsigned(m2_address))) <= br;
            cnt_m2 <= std_logic_vector(unsigned(cnt_m2) + 1);
            currentState <= a31;

    when a30 =>
        
            rmin <= br;
            currentState <= a32;

    when a31 =>
        
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a33;

    when a32 =>
        
            m2_address := mac2;
            currentState <= a34;

    when a33 =>
        
            rd <= std_logic_vector(unsigned(rmax) - unsigned(rmin));
            currentState <= a35;

    when a34 =>
        
            br <= m2(to_integer(unsigned(m2_address)));
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a36;

    when a35 =>
        
            cnt_elem <= (others => '0');
            cnt <= (others => '0');
            currentState <= a37;

    when a36 =>
        
            rlengthd <= br;
            rmask <= x"80";
            shcnt <= (others => '0');
            currentState <= a38;

    when a37 =>
        if (rd = x"00") then
            br <= cnt;
            rlengthd <= cnt;
            currentState <= a39;

        else
            rd <= std_logic_vector(unsigned(rd) srl 1);
            currentState <= a40;

        end if;

    when a38 =>
        
            cnt_elem <= (others => '0');
            currentState <= a41;

    when a39 =>
        
            m2_address := mac2;
            m2(to_integer(unsigned(m2_address))) <= br;
            cnt_m2 <= std_logic_vector(unsigned(cnt_m2) + 1);
            currentState <= a42;

    when a40 =>
        
            cnt <= std_logic_vector(unsigned(cnt) + 1);
            currentState <= a37;

    when a41 =>
        if (rlengthd = x"00") then
            br <= rmin;
            currentState <= a43;

        else
            m2_address := mac2;
            currentState <= a44;

        end if;

    when a42 =>
        
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a45;

    when a43 =>
        
            m3_address := mac1;
            m3(to_integer(unsigned(m3_address))) <= br;
            cnt_m1_m3 <= std_logic_vector(unsigned(cnt_m1_m3) + 1);
            currentState <= a46;

    when a44 =>
        
            br <= m2(to_integer(unsigned(m2_address)));
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a47;

    when a45 =>
        if (rlengthd = x"00") then
            cnt_m1_m3 <= std_logic_vector(unsigned(cnt_m1_m3) - unsigned(relem));
            currentState <= a48;

        else
            shcnt <= (others => '0');
            mac1 <= rtemp1;
            rmask <= x"01";
            currentState <= a49;

        end if;

    when a46 =>
        
            mac1 <= std_logic_vector(unsigned(mac1) + 1);
            currentState <= a50;

    when a47 =>
        
            rt2 <= br;
            currentState <= a51;

    when a48 =>
        if (cnt_m1_m3 = x"0000") then
            codcomplete <= '1';
            rwrite2m2 <= cnt_m2;
            currentState <= a1;
            idle <= '1';

        else
            cnt_elem <= (others => '0');
            rtemp1 <= mac1;
            currentState <= a16;

        end if;

    when a49 =>
        if (shcnt = std_logic_vector(unsigned(rlengthd) - x"01")) then
            m1_address := mac1;
            currentState <= a52;

        else
            rmask <= std_logic_vector(unsigned(rmask) sll 1);
            shcnt <= std_logic_vector(unsigned(shcnt) + 1);
            currentState <= a49;

        end if;

    when a50 =>
        
            cnt_elem <= std_logic_vector(unsigned(cnt_elem) + 1);
            currentState <= a53;

    when a51 =>
        
            bitcnt <= (others => '0');
            currentState <= a54;

    when a52 =>
        
            br <= m1(to_integer(unsigned(m1_address)));
            mac1 <= std_logic_vector(unsigned(mac1) + 1);
            currentState <= a55;

    when a53 =>
        if (cnt_elem = relem and cnt_m1_m3 = rfilelength) then
            decodcomplete <= '1';
            rwrite2m3 <= cnt_m1_m3;
            currentState <= a1;
            idle <= '1';

        elsif (cnt_elem = relem and not (cnt_m1_m3 = rfilelength)) then
            m2_address := mac2;
            currentState <= a27;

        else
            br <= rmin;
            currentState <= a43;

        end if;

    when a54 =>
        
            rt1 <= std_logic_vector(unsigned(rmask) and unsigned(rt2));
            currentState <= a56;

    when a55 =>
        
            rt1 <= br;
            currentState <= a57;

    when a56 =>
        
            rt2 <= std_logic_vector(unsigned(rt2) sll 1);
            currentState <= a58;

    when a57 =>
        
            rt2 <= std_logic_vector(unsigned(rt1) - unsigned(rmin));
            cnt_m1_m3 <= std_logic_vector(unsigned(cnt_m1_m3) - 1);
            currentState <= a59;

    when a58 =>
        
            rbyte <= std_logic_vector(unsigned(rbyte) sll 1);
            currentState <= a60;

    when a59 =>
        
            shcnt <= (others => '0');
            currentState <= a61;

    when a60 =>
        if (rt1 = x"00") then
            shcnt <= std_logic_vector(unsigned(shcnt) + 1);
            bitcnt <= std_logic_vector(unsigned(bitcnt) + 1);
            currentState <= a62;

        else
            rbyte(0) <= '1';
            currentState <= a63;

        end if;

    when a61 =>
        
            rt1 <= std_logic_vector(unsigned(rmask) and unsigned(rt2));
            currentState <= a64;

    when a62 =>
        if (shcnt = rlengthd) then
            br <= std_logic_vector(unsigned(rbyte) + unsigned(rmin));
            shcnt <= (others => '0');
            currentState <= a65;

        elsif (not (shcnt = rlengthd) and bitcnt = x"8" and cnt_elem = relem and cnt_m1_m3 = rfilelength) then
            decodcomplete <= '1';
            rwrite2m3 <= cnt_m1_m3;
            currentState <= a1;
            idle <= '1';

        elsif (not (shcnt = rlengthd) and bitcnt = x"8" and cnt_elem = relem and not (cnt_m1_m3 = rfilelength)) then
            m2_address := mac2;
            currentState <= a27;

        elsif (not (shcnt = rlengthd) and bitcnt = x"8" and not (cnt_elem = relem)) then
            m2_address := mac2;
            currentState <= a44;

        else
            rt1 <= std_logic_vector(unsigned(rmask) and unsigned(rt2));
            currentState <= a56;

        end if;

    when a63 =>
        
            shcnt <= std_logic_vector(unsigned(shcnt) + 1);
            bitcnt <= std_logic_vector(unsigned(bitcnt) + 1);
            currentState <= a62;

    when a64 =>
        
            rt2 <= std_logic_vector(unsigned(rt2) sll 1);
            currentState <= a66;

    when a65 =>
        
            m3_address := mac1;
            m3(to_integer(unsigned(m3_address))) <= br;
            cnt_m1_m3 <= std_logic_vector(unsigned(cnt_m1_m3) + 1);
            currentState <= a67;

    when a66 =>
        
            rbyte <= std_logic_vector(unsigned(rbyte) sll 1);
            currentState <= a68;

    when a67 =>
        
            mac1 <= std_logic_vector(unsigned(mac1) + 1);
            currentState <= a69;

    when a68 =>
        if (rt1 = x"00") then
            shcnt <= std_logic_vector(unsigned(shcnt) + 1);
            bitcnt <= std_logic_vector(unsigned(bitcnt) + 1);
            currentState <= a70;

        else
            rbyte(0) <= '1';
            currentState <= a71;

        end if;

    when a69 =>
        
            rbyte <= x"00";
            cnt_elem <= std_logic_vector(unsigned(cnt_elem) + 1);
            currentState <= a72;

    when a70 =>
        if (bitcnt = x"8") then
            br <= rbyte;
            currentState <= a73;

        elsif (not (bitcnt = x"8") and shcnt = rlengthd and cnt_elem = std_logic_vector(unsigned(relem) - x"0001") and cnt_m1_m3 = x"0000") then
            codcomplete <= '1';
            rwrite2m2 <= cnt_m2;
            currentState <= a1;
            idle <= '1';

        elsif (not (bitcnt = x"8") and shcnt = rlengthd and cnt_elem = std_logic_vector(unsigned(relem) - x"0001") and not (cnt_m1_m3 = x"0000")) then
            cnt_elem <= (others => '0');
            rtemp1 <= mac1;
            currentState <= a16;

        elsif (not (bitcnt = x"8") and shcnt = rlengthd and not (cnt_elem = std_logic_vector(unsigned(relem) - x"0001"))) then
            cnt_elem <= std_logic_vector(unsigned(cnt_elem) + 1);
            currentState <= a74;

        else
            rt1 <= std_logic_vector(unsigned(rmask) and unsigned(rt2));
            currentState <= a64;

        end if;

    when a71 =>
        
            shcnt <= std_logic_vector(unsigned(shcnt) + 1);
            bitcnt <= std_logic_vector(unsigned(bitcnt) + 1);
            currentState <= a70;

    when a72 =>
        if (bitcnt = x"8" and cnt_elem = relem and cnt_m1_m3 = rfilelength) then
            decodcomplete <= '1';
            rwrite2m3 <= cnt_m1_m3;
            currentState <= a1;
            idle <= '1';

        elsif (bitcnt = x"8" and cnt_elem = relem and not (cnt_m1_m3 = rfilelength)) then
            m2_address := mac2;
            currentState <= a27;

        elsif (bitcnt = x"8" and not (cnt_elem = relem)) then
            m2_address := mac2;
            currentState <= a44;

        else
            rt1 <= std_logic_vector(unsigned(rmask) and unsigned(rt2));
            currentState <= a56;

        end if;

    when a73 =>
        
            m2_address := mac2;
            m2(to_integer(unsigned(m2_address))) <= br;
            cnt_m2 <= std_logic_vector(unsigned(cnt_m2) + 1);
            currentState <= a75;

    when a74 =>
        
            m1_address := mac1;
            currentState <= a52;

    when a75 =>
        
            mac2 <= std_logic_vector(unsigned(mac2) + 1);
            currentState <= a76;

    when a76 =>
        
            bitcnt <= (others => '0');
            rbyte <= x"00";
            currentState <= a77;

    when a77 =>
        if (shcnt = rlengthd and cnt_elem = std_logic_vector(unsigned(relem) - x"0001") and cnt_m1_m3 = x"0000") then
            codcomplete <= '1';
            rwrite2m2 <= cnt_m2;
            currentState <= a1;
            idle <= '1';

        elsif (shcnt = rlengthd and cnt_elem = std_logic_vector(unsigned(relem) - x"0001") and not (cnt_m1_m3 = x"0000")) then
            cnt_elem <= (others => '0');
            rtemp1 <= mac1;
            currentState <= a16;

        elsif (shcnt = rlengthd and not (cnt_elem = std_logic_vector(unsigned(relem) - x"0001"))) then
            cnt_elem <= std_logic_vector(unsigned(cnt_elem) + 1);
            currentState <= a74;

        else
            rt1 <= std_logic_vector(unsigned(rmask) and unsigned(rt2));
            currentState <= a64;

        end if;

    end case;
    end proc_Funcmi;

    begin
        if (rst = '1') then
            bitcnt <= (others => '0');
            br <= (others => '0');
            cnt <= (others => '0');
            cnt_elem <= (others => '0');
            cnt_m1_m3 <= (others => '0');
            cnt_m2 <= (others => '0');
            codcomplete <= '0';
            decodcomplete <= '0';
            ext_in <= (others => '0');
            idle <= '0';
            mac1 <= (others => '0');
            mac2 <= (others => '0');
            rbyte <= (others => '0');
            rd <= (others => '0');
            relem <= (others => '0');
            rfilelength <= (others => '0');
            rlengthd <= (others => '0');
            rmask <= (others => '0');
            rmax <= (others => '0');
            rmin <= (others => '0');
            rt1 <= (others => '0');
            rt2 <= (others => '0');
            rtemp1 <= (others => '0');
            rwrite2m2 <= (others => '0');
            rwrite2m3 <= (others => '0');
            shcnt <= (others => '0');

            currentState <= a1;
            idle <= '1';

        elsif (clk'event and clk = '1') then
            idle <= '0';
            proc_Funcmi;
        end if;
    end process;

end ARC_Funcmi;