为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

i2c slave fpga实现代码

2017-09-06 13页 doc 35KB 44阅读

用户头像

is_037433

暂无简介

举报
i2c slave fpga实现代码LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY i2c_slave IS GENERIC ( WR_OP_MODE: STD_LOGIC :='1' ); PORT ( ----------I2C Bus-------- scl : IN STD_LOGIC ;----I2C bus clk sda : INOUT STD_LOG...
i2c slave fpga实现代码
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY i2c_slave IS GENERIC ( WR_OP_MODE: STD_LOGIC :='1' ); PORT ( ----------I2C Bus-------- scl : IN STD_LOGIC ;----I2C bus clk sda : INOUT STD_LOGIC ; ---------sys clk----add sys_clk : IN std_logic; reset : IN STD_LOGIC ; ---------Logic Out------- i2c_addr : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); i2c_data_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); wrd : OUT STD_LOGIC ; ---0 write 1 read wrd_en : OUT STD_LOGIC ;---1 active i2c_scl_out : OUT STD_LOGIC ;----falling edge ---------Logic In------- i2c_data_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0); --------dv_id in-------- dv_id_in : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ); END i2c_slave; ARCHITECTURE beh OF i2c_slave IS CONSTANT RESET_ACTIVE : STD_LOGIC := '0'; CONSTANT IDLE : STD_LOGIC_VECTOR :="0001"; ----Grad code CONSTANT HEADER : STD_LOGIC_VECTOR :="0011"; CONSTANT ACK_HEADER : STD_LOGIC_VECTOR :="0010"; CONSTANT RCV_REG_ADDR : STD_LOGIC_VECTOR :="0110"; CONSTANT ACK_REG_ADDR : STD_LOGIC_VECTOR :="0111"; CONSTANT RCV_DATA : STD_LOGIC_VECTOR :="0101"; CONSTANT ACK_DATA : STD_LOGIC_VECTOR :="0100"; CONSTANT XMIT_DATA : STD_LOGIC_VECTOR :="1010"; CONSTANT WAIT_ACK : STD_LOGIC_VECTOR :="1011"; ----bit counter constant CONSTANT CNT_DONE : STD_LOGIC_VECTOR :="0111"; ---i2c signal SIGNAL sda_in : STD_LOGIC ; SIGNAL detect_start,detect_stop : STD_LOGIC; sIGNAL state : STD_LOGIC_VECTOR(3 DOWNTO 0); ----bit counter 0 to 7 SIGNAL bit_cnt : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL bit_cnt_ld,bit_cnt_en : STD_LOGIC ; SIGNAL addr_match : STD_LOGIC ; ---header data SIGNAL i2c_header : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL i2c_header_en : STD_LOGIC; ---shift data SIGNAL i2c_shift_data : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL i2c_shift_en : STD_LOGIC ; ---addr SIGNAL addr_flag : STD_LOGIC ; SIGNAL addr_reg : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL get_data_flag : STD_LOGIC ; ----slave_sda SIGNAL slave_sda : STD_LOGIC ; SIGNAL sda_dir : STD_LOGIC ; ---load data SIGNAL load_data_reg_tem : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL load_data_flag,load_data_flag_dl : STD_LOGIC ; SIGNAL load_data_en : STD_LOGIC ; SIGNAL shift_out : STD_LOGIC ; --wrd_en SIGNAL wrd_en_reg,wrd_en_reg_dl : STD_LOGIC; signal scl_reg : std_logic; signal scl_reg_shift : std_logic_vector(5 downto 0); BEGIN ------------jitter ----------------- gen_scl_reg : PROCESS (sys_clk,reset) IS BEGIN IF (reset=RESET_ACTIVE) THEN scl_reg<='1'; scl_reg_shift<=(others=>'1'); ELSIF (sys_clk'EVENT AND sys_clk='1') THEN scl_reg_shift<=scl_reg_shift(4 downto 0)&scl; if scl_reg_shift(5 downto 0)="111111" then scl_reg<='1'; elsif scl_reg_shift(5 downto 0)="000000" then scl_reg<='0'; else scl_reg<=scl_reg; end if; END IF; END PROCESS gen_scl_reg; --************************Get Out************************** i2c_addr<=addr_reg; i2c_data_out<=i2c_shift_data; wrd<=i2c_header(0); --wrd_en<=wrd_en_reg AND wrd_en_reg_dl; wrd_en<=wrd_en_reg; i2c_scl_out<=scl_reg; gen_sda : PROCESS (sda_dir,slave_sda,sda) IS BEGIN IF (sda_dir='1') THEN sda<=slave_sda; ELSE sda_in<=sda; sda<='Z'; END IF; END PROCESS gen_sda; wrd_en_reg<=get_data_flag OR load_data_flag; -- ************************ START/STOP Detect Process ************************ -- This process detects the start and stop conditions. -- by using SDA as a clock ------------------------------------- start_det : PROCESS (sda_in,reset) IS BEGIN IF (reset=RESET_ACTIVE OR state=HEADER) THEN detect_start<='0'; --ELSIF (sda'EVENT AND sda='0') THEN ELSIF (sda'EVENT AND sda='0') THEN---change by lq 3.5 IF (scl_reg='1') THEN ---or scl='1'?? detect_start<='1'; ELSE detect_start<='0'; END IF; END IF; END PROCESS start_det; stop_det : PROCESS (sda_in,reset,detect_start) IS BEGIN IF (reset=RESET_ACTIVE OR detect_start='1') THEN detect_stop<='0'; ELSIF (sda'EVENT AND sda/='0') THEN---- IF (scl_reg='1') THEN ---or scl='1'?? detect_stop<='1'; ELSE detect_stop<='0'; END IF; END IF; END PROCESS stop_det; --******************I2C Header Process**************** --i2c_header_en<='1' WHEN (detect_start='1' OR state=HEADER) ELSE '0'; i2c_header_en<='1' WHEN (state=HEADER) ELSE '0'; gen_i2cheader : PROCESS (reset,scl_reg,detect_stop) IS BEGIN IF (reset=RESET_ACTIVE OR detect_stop='1') THEN i2c_header<=( OTHERS =>'0');----------------????? ELSIF (scl_reg'EVENT AND scl_reg='1') THEN -----rising_edge IF (i2c_header_en='1') THEN i2c_header<=i2c_header(6 DOWNTO 0)&sda_in; END IF; END IF; END PROCESS gen_i2cheader; --******************Bit Counter Process****************** gen_bit_cnter : PROCESS (reset,scl_reg) IS BEGIN IF (reset=RESET_ACTIVE) THEN bit_cnt<=( OTHERS =>'0'); ELSIF (scl_reg'EVENT AND scl_reg='0') THEN -----falling_edge IF (bit_cnt_ld='1') THEN bit_cnt<=( OTHERS =>'0'); ELSIF (bit_cnt_en='1') THEN bit_cnt<=bit_cnt+1; ELSE bit_cnt<=( OTHERS =>'0'); END IF; END IF; END PROCESS gen_bit_cnter; bit_cnt_ld<='1' WHEN (state=IDLE) OR (state=ACK_HEADER) OR (state=ACK_REG_ADDR) OR (state=ACK_DATA) OR (state=WAIT_ACK) OR (detect_start='1') ELSE '0'; bit_cnt_en<='1' WHEN (state=HEADER) OR (state=RCV_REG_ADDR) OR (state=RCV_DATA) OR (state=XMIT_DATA) ELSE '0'; --*******************Addr Match Process****************** addr_match<='1' WHEN i2c_header(7 DOWNTO 1)=("110"&dv_id_in) ELSE '0'; --******************Shift data Process******************* get_shift_data : PROCESS (reset,scl_reg) IS BEGIN IF (reset=RESET_ACTIVE) THEN i2c_shift_data<=(OTHERS =>'0'); ELSIF (scl_reg'EVENT AND scl_reg='1') THEN---change by lq IF (i2c_shift_en='1') THEN i2c_shift_data<=i2c_shift_data(6 DOWNTO 0)&sda_in; END IF; END IF; END PROCESS get_shift_data; i2c_shift_en<='1' WHEN (state=RCV_REG_ADDR) OR (state=RCV_DATA) ELSE '0'; --******************Get addr Process****************** addr_flag<='1' WHEN state=ACK_REG_ADDR ELSE '0'; get_addr_reg : PROCESS (reset,scl_reg) IS BEGIN IF (reset=RESET_ACTIVE) THEN addr_reg<=(OTHERS =>'0'); ELSIF (scl_reg'EVENT AND scl_reg='0') THEN IF (addr_flag='1') THEN addr_reg<=i2c_shift_data; END IF; END IF; END PROCESS get_addr_reg; get_data_flag<='1' WHEN state=ACK_DATA ELSE '0'; --******************Load Data Process**************** gen_load : PROCESS (scl_reg,reset) IS BEGIN IF (reset=RESET_ACTIVE) THEN load_data_reg_tem<=( OTHERS =>'0'); ELSIF (scl_reg'EVENT AND scl_reg='0') THEN IF (load_data_flag='1') THEN load_data_reg_tem<=i2c_data_in; ELSIF (load_data_en='1') THEN load_data_reg_tem<=load_data_reg_tem(6 DOWNTO 0)&load_data_reg_tem(7); END IF; END IF; END PROCESS gen_load; --shift_out<=load_data_reg_tem(7) WHEN ((load_data_en='1') AND (load_data_flag_dl/='1')) ELSE i2c_data_in(7); shift_out<=load_data_reg_tem(7) ;-- WHEN ((load_data_en='1') AND (load_data_flag_dl/='1')) ELSE '0'; load_data_en<='1' WHEN (state=XMIT_DATA) ELSE '0'; load_data_flag<='1' WHEN ((state=ACK_HEADER) AND (i2c_header(0)='1') AND (addr_match='1')) ELSE '0'; get_load_flag_dl : PROCESS (reset,scl_reg) IS BEGIN IF (reset=RESET_ACTIVE) THEN load_data_flag_dl<='0'; ELSIF (scl_reg'EVENT AND scl_reg='0') THEN load_data_flag_dl<=load_data_flag; END IF; END PROCESS get_load_flag_dl; --***************Shift out Process********************** slave_sda<='0' WHEN ((state=ACK_HEADER) AND (addr_match='1')) OR (state=ACK_REG_ADDR) OR (state=ACK_DATA) ELSE shift_out WHEN (state=XMIT_DATA) ELSE '1'; sda_dir<='1' WHEN ((state=ACK_HEADER) AND (addr_match='1')) OR (state=ACK_REG_ADDR) OR (state=ACK_DATA) OR (state=XMIT_DATA) ELSE '0'; -- ************** Main State Machine Process ************ state_machine : PROCESS (scl_reg,reset,detect_stop) IS BEGIN IF (reset=RESET_ACTIVE OR detect_stop='1') THEN state <= IDLE; ELSIF (scl_reg'EVENT AND scl_reg='0') THEN CASE (state) IS ---------------IDLE STATE-------- WHEN IDLE => IF (detect_start='1') THEN state<=HEADER; END IF; ---------------HEADER STATE------- WHEN HEADER =>IF (bit_cnt=CNT_DONE) THEN state<=ACK_HEADER; END IF; ---------------ACK_HEADER STATE--- WHEN ACK_HEADER => IF (addr_match='1') THEN IF (i2c_header(0)='0') THEN---write state<=RCV_REG_ADDR; ELSE ----read state<=XMIT_DATA; END IF; ELSE state<=IDLE; END IF; --------------- RCV_REG_ADDR STATE--- WHEN RCV_REG_ADDR => IF (detect_start='1') THEN state<=HEADER; ELSIF (bit_cnt=CNT_DONE) THEN state<=ACK_REG_ADDR; END IF; ----------------ACK_REG_ADDR STATE-------- WHEN ACK_REG_ADDR => state<=RCV_DATA; --------------- RCV_DATA STATE-------- WHEN RCV_DATA => IF (detect_start='1') THEN state<=HEADER; ELSIF (bit_cnt=CNT_DONE) THEN state<=ACK_DATA; END IF; --------------- ACK_DATA STATE------- WHEN ACK_DATA => IF (WR_OP_MODE='1') THEN state<=RCV_REG_ADDR; ELSE state<=RCV_DATA; END IF; --------------- XMIT_DATA STATE------ WHEN XMIT_DATA => IF (detect_start='1') THEN state<=HEADER; ELSIF (bit_cnt=CNT_DONE) THEN state<=WAIT_ACK; END IF; --------------- WAIT_ACK STATE------- WHEN WAIT_ACK => IF (sda_in='0') THEN state<= XMIT_DATA; ELSE state<= IDLE; END IF; WHEN OTHERS => state<= IDLE; -- i2c_header_en<='0'; END CASE; END IF; END PROCESS state_machine; END beh;
/
本文档为【i2c slave fpga实现代码】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索