📄 i2c.vhd
字号:
-- Main Behavior Process for slave -- combinational process for next state generation --------------------------------------------------------------------------- StateGen_slave :PROCESS(current_state_s, stop, start, clk_cnt, buf_loaded) BEGIN IF (rising_edge(stop)) THEN next_state_s <= IDLE; ELSE CASE current_state_s IS WHEN IDLE => IF (-- if device can be slave, and start cond detected SLAVE_gen = TRUE AND start = '1' AND -- if device can work in hs mode, or hs mode is not active (hs_mode_s = '0' OR HS_mode_gen = TRUE) AND -- if device is hardware master that should be written (HARD_MASTER_gen = FALSE OR (hard_mast_addressed = '0')) ) THEN next_state_s <= S_INIT; END IF; WHEN S_INIT => IF (clk_cnt = 0 AND buf_loaded = '1') THEN --ACK CLK --rnw_s := SDA_tmp; IF (first_byte_s(7 downto 3) = BIT10_ADDR_C) THEN -- read or write req IF (SDA_tmp = '0') THEN IF (slave_addr(9 downto 8) = first_byte_s(2 downto 1)) THEN next_state_s <= S_BIT10_ADDR; ELSE next_state_s <= IDLE; END IF; ELSE IF (cs = '1' AND bit10_addr_s = '1' AND first_byte_s(2 downto 1) = slave_addr(9 downto 8) AND en_sl_resp = '1' AND HARD_MASTER_gen = FALSE) THEN next_state_s <= S_READ; ELSE next_state_s <= IDLE; END IF; END IF; ELSE -- if device was selected for 10 bit addressing, but -- none of previous conditions were matched then MASTER -- is not addressing 10 bit addressable device --7 bit slave is addressed IF (first_byte_s(7 downto 1) = slave_addr(6 downto 0) AND slave_addr(9 downto 7) = "UUU") THEN IF (en_sl_resp = '1') THEN IF SDA_tmp = '0' THEN next_state_s <= S_WRITTEN; ELSIF (HARD_MASTER_gen = FALSE) THEN next_state_s <= S_READ; ELSE -- read request for hardware master is not allowed next_state_s <= IDLE; END IF; ELSE next_state_s <= IDLE; END IF; ELSIF hs_mode_s = '0' THEN --general call procedure IF (first_byte_s(7 downto 0) = GEN_CALL) AND (GENERAL_CALL_gen = TRUE) AND (en_sl_resp = '1') THEN next_state_s <= S_SECOND; -- hs mode request ELSIF (first_byte_s(7 downto 3) = HS_MODE_C) THEN next_state_s <= IDLE; ELSE next_state_s <= IDLE; END IF; END IF; END IF; END IF; WHEN S_BIT10_ADDR => IF (clk_cnt = 0 AND buf_loaded = '1') THEN --ACK CLK --slave is addressed IF first_byte_s(9 downto 0) = slave_addr(9 downto 0) AND en_sl_resp = '1' THEN next_state_s <= S_WRITTEN; ELSE next_state_s <= IDLE; END IF; END IF; WHEN S_SECOND => IF (clk_cnt = 0 AND buf_loaded = '1') THEN --ACK CLK --B_bit_s := SDA_tmp; IF SDA_tmp = '0' THEN next_state_s <= IDLE; ELSE -- B_bit = '1' IF ( en_sl_resp = '1' AND (Listen_hard_master_gen = TRUE OR --AND hard_master_to_listen_to = second_byte (slave_addr(6 downto 0) = second_byte_s(7 downto 1) AND slave_addr(9 downto 7) = "UUU")) ) THEN next_state_s <= S_WRITTEN; ELSE next_state_s <= IDLE; END IF; END IF; END IF; WHEN S_READ => IF (clk_cnt'EVENT ) THEN --fist bit after ACK IF (clk_cnt = 1) THEN --not acknowladge from MASTER IF SDA_tmp = '1' THEN next_state_s <= IDLE; END IF; END IF; END IF; WHEN S_WRITTEN => IF (rising_edge(stop)) THEN next_state_s <= IDLE; ELSIF start'EVENT THEN IF start = '1' THEN next_state_s <= S_INIT; END IF; ELSIF (clk_cnt'EVENT) THEN IF (clk_cnt = 0) THEN IF en_sl_resp = '1' THEN next_state_s <= S_WRITTEN; ELSE next_state_s <= IDLE; END IF; END IF; END IF; END CASE; END IF; END PROCESS StateGen_slave; --------------------------------------------------------------------------- -- Main Behavior Process for master -- combinational process for next state generation --------------------------------------------------------------------------- StateGen_master :PROCESS(current_state_m, my_bus, stop, clk_cnt) BEGIN IF (rising_edge(stop)) THEN next_state_m <= IDLE; ELSE CASE current_state_m IS WHEN IDLE => IF (my_bus = '1' AND clk_cnt'EVENT AND -- hardware master ((HARD_MASTER_gen = TRUE AND SLAVE_gen = FALSE) OR -- programmed hardware master (HARD_MASTER_gen = TRUE AND SLAVE_gen = TRUE AND hard_mast_addressed = '1') OR -- or master (MASTER_gen)) ) THEN next_state_m <= M_INIT; ELSE next_state_m <= IDLE; END IF; WHEN M_INIT => IF clk_cnt'EVENT THEN -- arbitration is lost IF (clk_cnt /= 1 AND SDA_tmp /= SDA_zd_m) THEN next_state_m <= IDLE; -- device still acts as master ELSE -- if first byte IF (not_first_byte = FALSE) THEN null; -- first bit of second byte -- analyze response ELSE IF (first_byte_m(7 downto 3) = BIT10_ADDR_C) THEN IF SDA_tmp = '0' THEN --acknowladge bit reseived IF rnw_m = '0' THEN next_state_m <= M_BIT10_ADDR; ELSE IF bit10_addr_m = '1' THEN -- if 10 bit addressable device is -- already addressed next_state_m <= M_READ; ELSE next_state_m <= IDLE; END IF; END IF; ELSE --not acknowladge bit reseived next_state_m <= IDLE; END IF; ELSE IF address_some_slave = TRUE THEN IF SDA_tmp = '0' THEN --acknowladge bit received IF rnw_m = '1' THEN next_state_m <= M_READ; ELSE IF end_of_write = '1' THEN next_state_m <= IDLE; ELSE next_state_m <= M_WRITE; END IF; END IF; ELSE --not acknowladge bit received next_state_m <= IDLE; END IF; ELSIF hs_mode_m = '0' THEN IF first_byte_m(7 downto 0) = GEN_CALL THEN IF SDA_tmp = '0' THEN --acknowladge bit received next_state_m <= M_SECOND; ELSE --not acknowladge bit received next_state_m <= IDLE; END IF; ELSE next_state_m <= IDLE; END IF; ELSE next_state_m <= IDLE; END IF; END IF; END IF; END IF; END IF; WHEN M_BIT10_ADDR => IF clk_cnt'EVENT THEN -- arbitration is lost IF (clk_cnt /= 1 AND SDA_tmp /= SDA_zd_m) THEN next_state_m <= IDLE; --still master ELSE --fist bit after ACK IF (clk_cnt = 1) THEN --not acknowladge from SLAVE IF SDA_tmp = '1' THEN next_state_m <= IDLE; ELSE IF (next_req= '1') THEN -- orend_of_write next_state_m <= IDLE; ELSE next_state_m <= M_WRITE; END IF; END IF; END IF; END IF; END IF; WHEN M_READ => IF clk_cnt'EVENT THEN -- arbitration is lost IF (clk_cnt = 1 AND SDA_in /= SDA_zd_m) THEN next_state_m <= IDLE; --still master ELSE IF rd_cnt = 0 THEN --not acknowladge next_state_m <= IDLE; END IF; END IF; END IF; WHEN M_WRITE => IF clk_cnt'EVENT THEN -- arbitration is lost IF (clk_cnt /= 1 AND SDA_in /= SDA_zd_m) THEN next_state_m <= IDLE; --still master ELSE --fist bit after ACK IF (clk_cnt = 1) THEN --not acknowladge from SLAVE IF SDA_tmp = '1' OR end_of_write = '1' THEN next_state_m <= IDLE; END IF; END IF; END IF; END IF; WHEN M_SECOND => IF clk_cnt'EVENT THEN -- arbitration is lost IF (clk_cnt /= 1 AND SDA_tmp /= SDA_zd_m) THEN next_state_m <= IDLE; --still master ELSE -- check slave response after ACK clk IF (clk_cnt = 1) THEN IF B_bit_m = '1' AND SDA_tmp = '0' THEN next_state_m <= M_WRITE; ELSE next_state_m <= IDLE; END IF; END IF; END IF; END IF; END CASE; END IF; END PROCESS StateGen_master; --------------------------------------------------------------------------- --FSM Output generation and general funcionality --------------------------------------------------------------------------- Functional_slave : PROCESS(current_state_s, stop, start, clk_cnt, buf_loaded)--,next_req VARIABLE num : INTEGER := 7;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -