📄 i2c.vhd
字号:
---------------------------------------------------------------------------------------------------------------------------------------------------------- Copyright (C) 2004 Free Model Foundry; http://www.FreeModelFoundry.com/---- This program is free software; you can redistribute it and/or modify-- it under the terms of the GNU General Public License version 2 as-- published by the Free Software Foundation.----------------------------------------------------------------------------- -- -- Company : HDL Design House, Serbia and Montenegro-- Project : I2C-- Module :---- Date : 05.03.2004-- Ver. : 1.0---- Author : J.Bogosavljevic-- Email : J-Bogosavljevic@hdl-dh.com-- Phone : +381 11 344 23 59---- Customer :--------------------------------------------------------------------------------- Functional description of the module:-- I2C bus VITAL model------------------------------------------------------------------------------------------------------------------------------------------------------------LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.VITAL_timing.ALL; USE IEEE.VITAL_primitives.ALL; USE STD.textio.ALL;LIBRARY FMF; USE FMF.gen_utils.all; USE FMF.conversions.all;LIBRARY work;USE work.i2c_drive_ms_pkg.all;--------------------------------------------------------------------------------- ENTITY DECLARATION-------------------------------------------------------------------------------ENTITY i2c_device IS GENERIC ( -- tipd delays: interconnect path delays tipd_SDA : VitalDelayType01 := VitalZeroDelay01; tipd_SCL : VitalDelayType01 := VitalZeroDelay01; --tpd, tsetup, thold delays -- tHD;STA 4us, 0.6us, 160ns thold_scl_sda : VitalDelayType := UnitDelay; -- tSU;STA 4.7us, 0.6us, 160ns tsetup_scl_sda_noedge_negedge : VitalDelayType := UnitDelay; -- tHD;DAT 300ns, 300ns, -->20 ns (3mA current source and 400 pF load) --> 10 ns (load 10-100 pF) thold_sda_scl : VitalDelayType := UnitDelay; -- tSU;DAT 250ns, 100ns, 10ns tsetup_sda_scl : VitalDelayType := UnitDelay; -- tSU;STO 4.0us, 0.6us, 160ns tsetup_scl_sda_noedge_posedge : VitalDelayType := UnitDelay; tpw_SCL_negedge: VitalDelayType := UnitDelay; tpw_SCL_posedge: VitalDelayType := UnitDelay; -- tdevice values: values for internal delays -- 1.3 us for fast mode -- 4.7 us for fast mode tdevice_tbuff : VitalDelayType := 1.3 us; -- glitch suppresion tdevice_tgsp : VitalDelayType := 1.3 us; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel; --i2c specific generics Device_id : STRING := "none"; -- if device can be master MASTER_gen : BOOLEAN := TRUE; -- true if device can be slave SLAVE_gen : BOOLEAN := TRUE; -- if device is hadrware master HARD_MASTER_gen : BOOLEAN := TRUE; -- true if device will response on general call procedure GENERAL_CALL_gen : BOOLEAN := TRUE; -- slave addresse SLAVE_ADDR_gen : std_logic_vector(9 downto 0):= (OTHERS => 'U'); -- zero if slave address is not programable -- else number of programable bits PROGRAMABLE_S_A_gen : INTEGER := 0; -- programable part of slave address PPART_SLAVE_ADDR_gen: std_logic_vector(9 downto 0) := (OTHERS => 'U'); Listen_hard_master_gen : BOOLEAN := FALSE; -- CLK high pulse width T_high_gen : time := 4 us ; -- CLK low pulse width T_low_gen : time := 4.7 us; -- true if device can work in HS mode HS_mode_gen : BOOLEAN := TRUE; -- true if device can work in CBUS mode CBUS_mode_gen : BOOLEAN := FALSE; -- master code if device can work in HS mode MASTER_CODE_gen : std_logic_vector(7 downto 0) := "00001XXX"; --RESET signal pulse width, general call proc t_reset : time := 1 ns ); PORT ( SDA : INOUT std_ulogic := 'U'; SCL : INOUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of i2c_device : ENTITY IS TRUE;END i2c_device;--------------------------------------------------------------------------------- ARCHITECTURE DECLARATION-------------------------------------------------------------------------------ARCHITECTURE vhdl_behavioral of i2c_device IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT PartID : STRING := "i2c";--and SLAVE_ADDR --other CONSTANTS CONSTANT GEN_CALL : std_logic_vector(7 downto 0) := "00000000"; CONSTANT START_BYTE : std_logic_vector(7 downto 0) := "00000001"; CONSTANT CBUS_MODE : std_logic_vector(6 downto 0) := "0000001"; CONSTANT HS_MODE_C : std_logic_vector(4 downto 0) := "00001"; CONSTANT BIT10_ADDR_C : std_logic_vector(4 downto 0) := "11110"; --size of slave memory CONSTANT MemSize : INTEGER := 15; -- interconnect path delay signals SIGNAL SDA_ipd : std_ulogic := 'U'; SIGNAL SCL_ipd : std_ulogic := 'U'; --- internal delays SIGNAL tbuff_in : std_ulogic := '0'; SIGNAL tbuff_out : std_ulogic := '0';BEGIN --------------------------------------------------------------------------- -- Internal Delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays TBUFF : VitalBuf(tbuff_out, tbuff_in, (tdevice_tbuff, UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_0 : VitalWireDelay (SDA_ipd, SDA, tipd_SDA); w_1 : VitalWireDelay (SCL_ipd, SCL, tipd_SCL); END BLOCK; --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK PORT ( SDAin : IN std_logic := 'U'; SCLin : IN std_logic := 'U'; SDAout : OUT std_ulogic := 'Z'; SCLout : OUT std_ulogic := 'Z' ); PORT MAP ( SDAin => SDA_ipd, SCLin => SCL_ipd, SDAout => SDA, SCLout => SCL ); -- State Machine for master : State_Type_m TYPE state_type_m IS ( IDLE, M_INIT, M_SECOND,-- second byte for general call M_BIT10_ADDR,-- second byte for 10 bit addressing --M_CBUS,-- device in CBUS mode M_WRITE,-- write slave M_READ--read slave ); -- State Machine for slave: State_Type_s TYPE state_type_s IS ( IDLE, S_INIT,-- init slave S_BIT10_ADDR, S_SECOND,-- general call proc S_WRITTEN,-- slave is written by master S_READ-- slave is written by master ); --other types TYPE MemArray IS ARRAY (0 TO MemSize) OF INTEGER RANGE 0 TO 16#FF#; -- states SIGNAL current_state_m : state_type_m; SIGNAL next_state_m : state_type_m; SIGNAL current_state_s : state_type_s; SIGNAL next_state_s : state_type_s; --zero delay signals SIGNAL SDA_zd : std_logic := 'Z'; SIGNAL SDA_zd_m : std_logic := 'Z'; SIGNAL SDA_zd_s : std_logic := 'Z'; SIGNAL SCL_zd : std_logic := 'Z'; SIGNAL SDA_z : std_logic := 'Z'; SIGNAL SCL_z : std_logic := 'Z'; -- delayed SDA SIGNAL SDA_d : std_logic := 'Z'; SIGNAL SDA_in : std_logic := '1'; SIGNAL SCL_in : std_logic := '1'; --FSM and device control signals SIGNAL bit10_addr_m : std_logic := '0'; SIGNAL hs_mode_m : std_logic := '0'; SIGNAL bit10_addr_s : std_logic := '0'; SIGNAL hs_mode_s : std_logic := '0'; SIGNAL cs : std_logic := '0'; SIGNAL start : std_logic := '0'; SIGNAL stop : std_logic := '0'; SIGNAL my_bus : std_logic := '0'; SIGNAL arb_lost : std_logic := '0'; SIGNAL busy : std_logic := '0'; SIGNAL slave_addr : std_logic_vector(9 downto 0) := (OTHERS => 'U'); SIGNAL RESET : std_logic := '0'; --SIGNAL t_RESET : time := ; -- control signals to restore slave address (hardware, software or dump) SIGNAL hard_addr : std_logic := '0'; SIGNAL soft_addr : std_logic := '0'; SIGNAL load_addr : std_logic := '0'; SIGNAL mode : CHARACTER := 's'; SIGNAL hs_mode : std_logic := '0'; -- if device is hardware master that is in slave-receiver mode -- after power-up, signal hard_mast_addressed is set to '1' after -- writting dump address to this hardware master. After hard_mast_addressed -- is set to '1' this hardware master can not be programmed SIGNAL hard_mast_addressed: std_logic := '0'; --set from input file -- true if MASTER addresses a slave SIGNAL address_some_slave : BOOLEAN := FALSE; -- TRUE if slave is enabled to response SIGNAL en_sl_resp : std_logic := '1'; -- Master ends write, buffer is empty SIGNAL end_of_write : std_logic := '1'; -- initiate new bus request SIGNAL next_req : std_logic := '0'; --hs mode must be rejected if HS_NODE_GEN = FALSE -- number of bytes to read SIGNAL rd_cnt : NATURAL := 1; -- value to output on bus SIGNAL buff : std_logic_vector(7 downto 0) := (OTHERS => '0'); -- control signal to load rd_cnt SIGNAL load_rd_cnt : std_logic := '0'; -- load rd_cnt with rd_value SIGNAL rd_value : NATURAL := 0; -- slave delays CLK for delay_value SIGNAL delay_value : time := 0 ns; -- control signal: decrements rd_cnt SIGNAL decr_rd_cnt : std_logic := '0'; -- MASTER is ready to accept new command SIGNAL rdy : std_logic := '1'; SHARED VARIABLE out_buff : std_logic_vector(7 downto 0); SHARED VARIABLE out_num : INTEGER; SHARED VARIABLE SDA_tmp : std_logic := '1'; SIGNAL not_first_byte : BOOLEAN:= FALSE; -- clock counter SIGNAL clk_cnt : INTEGER := 0; -- active during acknowladge clk --SIGNAL ACK : std_logic := '0'; -- timing check violation SIGNAL Viol : X01 := '0'; --timeout signal after T_HIGH, used for clk synchronization SIGNAL timeout_high : std_logic := '0'; SHARED VARIABLE ts_cnt : NATURAL RANGE 1 TO 30:= 1; SHARED VARIABLE tc_cnt : NATURAL RANGE 0 TO 30:= 0; ---------------------------------------------- -- shared variables used in MASTER/SLAVE FSMs ---------------------------------------------- -- buffers initial byte (slave address, general cal,...) SIGNAL first_byte_m : std_logic_vector(9 downto 0) := (OTHERS => '0'); SIGNAL first_byte_s : std_logic_vector(9 downto 0) := (OTHERS => '0'); -- buffers second byte for genereal call procedure SIGNAL second_byte_s : std_logic_vector(7 downto 0) := (OTHERS => '0'); SIGNAL buf_loaded : std_logic := '0'; -- buffers data written to master/slave -- read or write operation in progress SHARED VARIABLE rnw_m : std_logic := 'U'; -- 7th bit of second byte in general call procedure SHARED VARIABLE B_bit_m : std_logic := 'U';-- SHARED VARIABLE B_bit_s : std_logic := 'U'; --slave and master memories, written/read data are stored here SHARED VARIABLE slv_mem : MemArray := (OTHERS=> 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -