⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.vhd

📁 Vhdl cod for a bus.For sp2e
💻 VHD
📖 第 1 页 / 共 5 页
字号:
    SHARED VARIABLE mast_mem         : MemArray := (OTHERS=> 0);    -- write pointer    SHARED VARIABLE s_p              : INTEGER RANGE 0 TO MemSize := 0;    -- read pointer    SHARED VARIABLE s_p_rd           : INTEGER RANGE 0 TO MemSize := 0;    SHARED VARIABLE m_p              : INTEGER RANGE 0 TO MemSize := 0;----------------------------------------------------------------------------------------------------------------------------------------------------------------FUNCTIONS AND PROCEDURES-------------------------------------------------------------------------------    PROCEDURE Drive(                           SIGNAL SDA_zd : INOUT std_logic;                           VARIABLE num  : INOUT NATURAL                   ) IS    BEGIN        SDA_zd <= buff(num);        --i := ((i-1)+8) MOD 8;        num := (num+7) MOD 8;    END Drive;    PROCEDURE Drive_slave_addr(                           SIGNAL SDA_zd     : INOUT std_logic;                           SIGNAL slave_addr : IN std_logic_vector(9 downto 0);                           VARIABLE num      : INOUT NATURAL                   ) IS    VARIABLE num_local : INTEGER := 0;    BEGIN    num_local := num - 1;    -- only slave_addr(7 downto 0) are output        IF num_local < 0 THEN        -- B bit            SDA_zd <= '1';        ELSE            SDA_zd <= slave_addr(num_local);        END IF;        num := (num+7) MOD 8;    END Drive_slave_addr;    PROCEDURE Drive_slave(                           SIGNAL SDA_zd : INOUT std_logic;                           VARIABLE num  : INOUT NATURAL                   ) IS    VARIABLE tmp_buff : std_logic_vector(7 downto 0);    BEGIN        tmp_buff := to_slv(slv_mem(s_p_rd), 8);        out_num := num;        out_buff := tmp_buff;        SDA_zd <= tmp_buff(num);        --i := ((i-1)+8) MOD 8;        IF num = 0 THEN            s_p_rd := (s_p_rd +1) MOD (MemSize+1);        END IF;        num := (num+7) MOD 8;    END Drive_slave;    PROCEDURE Drive_rdy(                           SIGNAL rdy       : INOUT std_logic;                           SIGNAL clk_cnt   : IN INTEGER                   ) IS    BEGIN        IF clk_cnt = 8 THEN            rdy <= '1';        ELSE            rdy <= '0';        END IF;    END Drive_rdy;    PROCEDURE Store(                  VARIABLE Load_buf  : INOUT std_logic_vector(7 downto 0);                  CONSTANT master    : BOOLEAN--                  SIGNAL load_addr_l : INOUT std_logic                   ) IS    BEGIN        IF master = TRUE THEN            mast_mem(m_p) := to_nat(Load_buf);            m_p := (m_p+1) MOD (MemSize+1);        ELSE            slv_mem(s_p) := to_nat(Load_buf);            s_p := (s_p+1) MOD (MemSize+1);        END IF;    END Store;    PROCEDURE SetSDA(                     SIGNAL SDA_zd : INOUT std_logic                   ) IS    BEGIN        IF next_req = '1' THEN        -- prepare for RESTART            SDA_zd <= '1';        ELSE        -- prepare for STOP            SDA_zd <= '0';        END IF;    END SetSDA;    --------------------------------------------------------------------------    -- PROCEDURE to select TC    --------------------------------------------------------------------------    PROCEDURE   Pick_TC        (         VARIABLE ts_cnt   :  INOUT NATURAL RANGE 1 TO 30;         VARIABLE tc_cnt   :  INOUT NATURAL RANGE 0 TO 30 )    IS    BEGIN        IF TC_cnt < tc(TS_cnt) THEN            TC_cnt := TC_cnt+1;        ELSE            TC_cnt:=1;            IF TS_cnt < 30 THEN                TS_cnt := TS_cnt+1;            ELSE                -- end test                WAIT;            END IF;        END IF;    END PROCEDURE Pick_TC;   ---------------------------------------------------------------------------    --procedure to decode commands into specific MASTER/SLAVE command sequence    ---------------------------------------------------------------------------    PROCEDURE command_decode        (   command                   :   IN  cmd_rec;            VARIABLE current_time     : IN TIME;            SIGNAL buff               : INOUT std_logic_vector(7 downto 0);            SIGNAL end_of_write       : INOUT std_logic;            SIGNAL next_req           : INOUT std_logic;            SIGNAL load_rd_cnt        : INOUT std_logic;            SIGNAL rd_value           : INOUT NATURAL;            SIGNAL delay_value        : INOUT time;            SIGNAL en_sl_resp         : INOUT std_logic;            SIGNAL address_some_slave : INOUT BOOLEAN            )    IS    VARIABLE tmp      :std_logic_vector(7 downto 0) := (OTHERS => '0');    VARIABLE tmp_time : TIME;    VARIABLE i        : NATURAL := 0;    BEGIN            IF command.cmd = idle AND               (command.device_id(7 downto 1) = "all_dev" OR                command.device_id = Device_id)                THEN                --IF my_bus = '1' THEN                --    WAIT UNTIL rdy = '1' OR my_bus = '0';--AND rdy'EVENT;                --END IF;                tmp_time := NOW;                next_req <= '0';                end_of_write <= '1';                en_sl_resp <= '1';                WAIT FOR (command.wtime - tmp_time);--current_time);            END IF;        IF  command.device_id = Device_id THEN            rd_value <= 1;            delay_value <= 0 ns;                next_req <= '0';            CASE command.cmd IS            WHEN    none        =>                IF my_bus = '1' THEN                    WAIT UNTIL rdy = '1' OR my_bus = '0';--AND rdy'EVENT;                END IF;                next_req <= '1';                end_of_write <= '1';                IF my_bus = '1' THEN                    WAIT UNTIL rdy = '1' OR my_bus = '0';--AND rdy'EVENT;                END IF;            WHEN    req_bus        =>            IF my_bus = '1' OR busy = '0' THEN                --IF my_bus = '1' THEN                --    WAIT UNTIL rdy = '1' OR my_bus = '0';--AND rdy'EVENT;                --END IF;                tmp := to_slv(command.wr_byte,8);                -- not HS mode request                IF  (tmp(7 downto 3) /= HS_MODE_C) THEN                    address_some_slave <= (                        (tmp(7 downto 4)) /= "0000" AND                        (tmp(7 downto 4)) /= "1111"                        );                    next_req <= '1';                    IF HARD_MASTER_gen = TRUE THEN                    -- general call procedure                        buff <= "00000000";                    ELSE                        buff <= to_slv(command.wr_byte,8);                    END IF;                    end_of_write <= '1';                load_rd_cnt <= '1', '0' AFTER 1 ns;                rd_value <= 1;--command.rd_byte_num;                -- HS mode request                ELSIF HS_MODE_gen = TRUE THEN                    address_some_slave <= NOT(                        (buff(7 downto 4)) = "0000" OR                        (buff(7 downto 4)) = "1111"                        );                    next_req <= '1';                    buff <= MASTER_CODE_gen;                    end_of_write <= '0';                END IF;                wait for command.wtime;                WAIT UNTIL ((rdy = '1' AND rdy'EVENT) OR my_bus = '0');                IF command.rd_byte_num = 1 THEN                    WAIT UNTIL ((rdy = '1' AND rdy'EVENT) OR my_bus = '0');                END IF;            END IF;            WHEN    write        =>            IF my_bus = '1' OR busy = '0' THEN                IF (                    (buff(7 downto 4)) = "0000" OR                    (buff(7 downto 4)) = "1111"                    ) THEN                    address_some_slave <= FALSE;                ELSE                    address_some_slave <= TRUE;                END IF;                buff <= to_slv(command.wr_byte,8);                next_req <= '0';                end_of_write <= '0';                WAIT UNTIL ((rdy = '1' AND rdy'EVENT) OR my_bus = '0');            END IF;            WHEN    read        =>            IF my_bus = '1' OR busy = '0' THEN                --buff <= to_slv(command.wr_byte,8);                next_req <= '0';                load_rd_cnt <= '1', '0' AFTER 1 ns;                rd_value <= command.rd_byte_num;                end_of_write <= '1';                FOR i IN 0 TO command.rd_byte_num-1 LOOP                --WHILE i < (command.rd_byte_num) LOOP                    WAIT UNTIL ((rdy = '1' AND rdy'EVENT) OR my_bus = '0');                  --  i := i+1;                END LOOP;            END IF;            WHEN    delay_clk        =>                --buff <= to_slv(command.wr_byte,8);                next_req <= '0';                load_rd_cnt <= '1', '0' AFTER 1 ns;                rd_value <= command.rd_byte_num;                delay_value <= command.wtime;                end_of_write <= '1';            WHEN    dis_sl_resp        =>                tmp := to_slv(command.wr_byte, 8);                --tmp_time := NOW;                --WAIT FOR (command.wtime - tmp_time);--current_time);                en_sl_resp <= tmp(0);                end_of_write <= '1';                WAIT FOR command.wtime;            WHEN OTHERS => null;           END CASE;        END IF;    END PROCEDURE command_decode;    BEGIN        hard_addr <= '1', '0' AFTER 1 ns;--WHEN GENERAL_CALL_gen = FALSE ELSE                     --'0';        hs_mode <= hs_mode_m OR hs_mode_s;        mode <= 's' WHEN (T_LOW_gen >= 4.7 us AND T_HIGH_gen >= 4.0 us) ELSE                'f' WHEN (T_LOW_gen >= 1.3 us AND T_HIGH_gen >= 0.6 us) ELSE                --Cp = 100 pF                'h';-- WHEN (T_LOW_gen >= 160 ns AND T_HIGH_gen >= 60 ns)        SDA_in <= '1' AFTER tdevice_tgsp WHEN SDA /= '0' ELSE                  '0' AFTER tdevice_tgsp;        SCL_in <= '1' AFTER tdevice_tgsp WHEN SCL /= '0' ELSE                  '0' AFTER tdevice_tgsp;   ----------------------------------------------------------------------------    --Power Up time 100 ns;    -----------------------------------------------------------------------------    PoweredUp <= '1' AFTER 100 ns;--    RST <= RESETNeg AFTER 500 ns;    ---------------------------------------------------------------------------    -- VITAL Timing Checks Procedures    ---------------------------------------------------------------------------    VITALTimingCheck: PROCESS(SDA, SCL)         -- Timing Check Variables        VARIABLE TD_SCL_SDA               : VitalTimingDataType;        VARIABLE Tviol_SLC_SDA            : X01 := '0';        VARIABLE TD_SCL_SDA_negedge       : VitalTimingDataType;        VARIABLE Tviol_SCL_SDA_negedge    : X01 := '0';        VARIABLE TD_SDA_SCL_negedge       : VitalTimingDataType;        VARIABLE Tviol_SDA_SCL_negedge    : X01 := '0';        VARIABLE TD_SDA_SCL_posedge       : VitalTimingDataType;        VARIABLE Tviol_SDA_SCL_posedge    : X01 := '0';        VARIABLE TD_SCL_SDA_posedge       : VitalTimingDataType;        VARIABLE Tviol_SCL_SDA_posedge    : X01 := '0';        VARIABLE PD_SCL      : VitalPeriodDataType := VitalPeriodDataInit;        VARIABLE Pviol_SCL                : X01 := '0';        VARIABLE Violation                : X01 := '0';    BEGIN    ----------------------------------------------------------    -- Timing Check Section    ---------------------------------------------------------------------------    IF (TimingChecksOn) THEN        -- tHD;STA 4us, 0.6us, 160ns        VitalSetupHoldCheck (            TestSignal      => SCL,            TestSignalName  => "SCL",            RefSignal       => SDA,            RefSignalName   => "SDA",            HoldHigh        => thold_SCL_SDA,            -- always enabled in HS mode            CheckEnabled    => mode = 'h' OR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -