📄 i2c.vhd
字号:
VARIABLE load_buf_s : std_logic_vector(7 downto 0) := (OTHERS => '0'); variable BOOL : boolean := true; BEGIN IF (rising_edge(stop)) THEN hs_mode_s <= '0'; cs <= '0'; bit10_addr_s <= '0'; num := 7; --next_state_s <= IDLE; ELSE CASE current_state_s IS WHEN IDLE => IF clk_cnt'EVENT THEN SDA_zd_s <= '1'; END IF; first_byte_s <= (OTHERS =>'0'); second_byte_s <= (OTHERS =>'0'); load_buf_s := (OTHERS => '0'); IF (bit10_addr_s = '0') THEN cs <= '0'; END IF;-- IF (SLAVE_gen = TRUE AND start = '1' AND-- (hs_mode_s = '0' OR HS_mode_gen = TRUE)) THEN-- next_state_s <= S_INIT;-- END IF; WHEN S_INIT => IF (clk_cnt /= 1 AND clk_cnt'EVENT) THEN first_byte_s <= first_byte_s(8 downto 0)&SDA_tmp; buf_loaded <= '1', '0' AFTER 1 ns; END IF; IF (clk_cnt = 0 AND buf_loaded = '1') THEN --ACK CLK --rnw_s := SDA_tmp; SDA_zd_s <= '1'; 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; SDA_zd_s <= '0'; -- remember 2 and 1 bits first_byte_s(1 downto 0) <= first_byte_s(2 downto 1); bit10_addr_s <= '1'; cs <= '0'; ELSE --next_state_s <= IDLE; cs <= '0'; bit10_addr_s <= '0'; 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; SDA_zd_s <= '0'; ELSE --next_state_s <= IDLE; cs <= '0'; bit10_addr_s <= '0'; 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 cs <= '0'; bit10_addr_s <= '0'; --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 (HARD_MASTER_gen = FALSE OR SDA_tmp = '0') THEN SDA_zd_s <= '0'; cs <= '1'; END IF; --IF SDA_tmp = '1' THEN -- next_state_s <= S_READ; --ELSE -- next_state_s <= S_WRITTEN; --END IF; ELSE SDA_zd_s <= '1'; --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; --acknowladge SDA_zd_s <= '0'; cs <= '1'; -- hs mode request ELSIF (first_byte_s(7 downto 3) = HS_MODE_C) THEN --next_state_s <= IDLE; --not acknowladge SDA_zd_s <= '1'; hs_mode_s <= '1'; --ELSE --next_state_s <= IDLE; END IF; END IF; END IF; END IF; WHEN S_BIT10_ADDR => IF (clk_cnt'EVENT) THEN IF clk_cnt /= 1 THEN first_byte_s <= first_byte_s(8 downto 0)&SDA_tmp; buf_loaded <= '1', '0' AFTER 1 ns; SDA_zd_s <= '1'; ELSE SDA_zd_s <= '1'; END IF; END IF; 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; cs <= '1'; SDA_zd_s <= '0'; bit10_addr_s <= '1'; ELSE --next_state_s <= IDLE; cs <= '0'; bit10_addr_s <= '0'; SDA_zd_s <= '1'; END IF; END IF; WHEN S_SECOND => IF clk_cnt'EVENT THEN IF (clk_cnt /= 1) THEN second_byte_s <= second_byte_s(6 downto 0)&SDA_tmp; buf_loaded <= '1', '0' AFTER 1 ns; SDA_zd_s <= '1'; ELSE SDA_zd_s <= '1'; END IF; END IF; IF (clk_cnt = 0 AND buf_loaded = '1') THEN --ACK CLK --B_bit_s := SDA_tmp; SDA_zd_s <= '1'; IF SDA_tmp = '0' THEN --next_state_s <= IDLE; IF en_sl_resp = '1' THEN --slave is addressed IF to_nat(second_byte_s) = 16#06# THEN soft_addr <= '1', '0' AFTER 1 ns; --RestoreSlaveAddr(slave_addr, bool); RESET <= '1', '0' AFTER t_reset;--assert reset SDA_zd_s <= '0'; ELSIF to_nat(second_byte_s) = 16#04# THEN --RestoreSlaveAddr(slave_addr, bool); soft_addr <= '1', '0' AFTER 1 ns; SDA_zd_s <= '0'; --ELSIF to_nat(second_byte) = 16#00# THEN --Report("Code not allowed"); END IF; END IF; 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; SDA_zd_s <= '0'; cs <= '1'; ELSE --next_state_s <= IDLE; SDA_zd_s <= '1'; 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; SDA_zd_s <= '1'; -- release SDA IF bit10_addr_s = '0' THEN cs <= '0'; END IF; ELSE Drive_slave(SDA_zd_s, num); END IF; ELSIF (clk_cnt /= 0) THEN Drive_slave(SDA_zd_s, num); ELSE SDA_zd_s <= '1'; END IF; END IF; WHEN S_WRITTEN => IF (rising_edge(stop)) THEN --next_state_s <= IDLE; cs <= '0'; bit10_addr_s <= '0'; hs_mode_s <= '0'; ELSIF start'EVENT THEN IF start = '1' THEN --next_state_s <= S_INIT; SDA_zd_s <= '1'; -- load first data first_byte_s <= "00"&load_buf_s; second_byte_s <= (OTHERS =>'0'); load_buf_s := (OTHERS => '0'); IF bit10_addr_s = '0' THEN cs <= '0'; END IF; END IF; ELSIF (clk_cnt'EVENT) THEN IF (clk_cnt /= 1 AND clk_cnt'EVENT) THEN Load_buf_s := Load_buf_s(6 downto 0)&SDA_tmp; SDA_zd_s <= '1'; END IF; IF (clk_cnt = 0) THEN Store(Load_buf_s, FALSE); IF (HARD_MASTER_gen AND hard_mast_addressed = '0') THEN load_addr <= '1', '0' AFTER 1 ns; END IF; Load_buf_s := (OTHERS => '0'); IF en_sl_resp = '1' THEN --next_state_s <= S_WRITTEN; --acknowladge SDA_zd_s <= '0'; ELSE --next_state_s <= IDLE; --not acknowladge SDA_zd_s <= '1'; IF bit10_addr_s = '0' THEN cs <= '0'; END IF; END IF; ELSE SDA_zd_s <= '1'; END IF; END IF; IF ((rising_edge(stop) OR rising_edge(start)) AND clk_cnt /= 1) THEN Report("Invalid timming for STOP/RESTART condition"); END IF; END CASE; END IF; END PROCESS Functional_slave; Functional_master : PROCESS(current_state_m, next_req, stop, clk_cnt) VARIABLE num : INTEGER := 7; VARIABLE load_buf_m : std_logic_vector(7 downto 0) := (OTHERS => '0'); BEGIN IF (rising_edge(stop)) THEN --next_state_m <= IDLE; hs_mode_m <= '0'; bit10_addr_m <= '0'; num := 7; ELSE CASE current_state_m IS WHEN IDLE => first_byte_m <= (OTHERS =>'0'); --second_byte_m <= (OTHERS =>'0'); Load_buf_m := (OTHERS => '0'); not_first_byte <= FALSE; --only if device is master IF ( (hard_mast_addressed = '1') OR (HARD_MASTER_gen = TRUE AND SLAVE_gen = FALSE) OR (MASTER_gen = TRUE AND HARD_MASTER_gen = FALSE)) THEN IF (my_bus = '1' AND clk_cnt'EVENT AND SCL_in = '0') THEN -- next_state_m <= M_INIT; Drive(SDA_zd_m, num); -- initiate new request for bus -- bus is free ELSE IF (SCL_in /= '0') THEN-- only if master IF (busy = '0' AND next_req = '1') THEN SDA_zd_m <= '0'; -- restart ELSIF (my_bus = '1' AND next_req = '1') THEN SDA_zd_m <= '0'; -- end transfer ELSIF NOT(next_req'EVENT) THEN SDA_zd_m <= '1'; END IF; END IF; END IF; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -