- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am beginner with vhdl and i have to implement an I2C master controller. I found this code to generate I2C clock but i didn't understand why the cycle is devided into for parts and how it assigns values to scl_clk and data_clk.ENTITY i2c_master IS
GENERIC(
input_clk : INTEGER := 50_000_000; --input clock speed from user logic in Hz
bus_clk : INTEGER := 400_000); --speed the i2c bus (scl) will run at in Hz
PORT(
clk : IN STD_LOGIC; --system clock
reset_n : IN STD_LOGIC; --active low reset
ena : IN STD_LOGIC; --latch in command
addr : IN STD_LOGIC_VECTOR(6 DOWNTO 0); --address of target slave
rw : IN STD_LOGIC; --'0' is write, '1' is read
data_wr : IN STD_LOGIC_VECTOR(7 DOWNTO 0); --data to write to slave
busy : OUT STD_LOGIC; --indicates transaction in progress
data_rd : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --data read from slave
ack_error : BUFFER STD_LOGIC; --flag if improper acknowledge from slave
sda : INOUT STD_LOGIC; --serial data output of i2c bus
scl : INOUT STD_LOGIC); --serial clock output of i2c bus
END i2c_master;
ARCHITECTURE logic OF i2c_master IS
CONSTANT divider : INTEGER := (input_clk/bus_clk)/4; --number of clocks in 1/4 cycle of scl
TYPE machine IS(ready, start, command, slv_ack1, wr, rd, slv_ack2, mstr_ack, stop); --needed states
SIGNAL state : machine; --state machine
SIGNAL data_clk : STD_LOGIC; --clock edges for sda
SIGNAL scl_clk : STD_LOGIC; --constantly running internal scl
SIGNAL scl_ena : STD_LOGIC := '0'; --enables internal scl to output
SIGNAL sda_int : STD_LOGIC := '1'; --internal sda
SIGNAL sda_ena_n : STD_LOGIC; --enables internal sda to output
SIGNAL addr_rw : STD_LOGIC_VECTOR(7 DOWNTO 0); --latched in address and read/write
SIGNAL data_tx : STD_LOGIC_VECTOR(7 DOWNTO 0); --latched in data to write to slave
SIGNAL data_rx : STD_LOGIC_VECTOR(7 DOWNTO 0); --data received from slave
SIGNAL bit_cnt : INTEGER RANGE 0 TO 7 := 7; --tracks bit number in transaction
SIGNAL stretch : STD_LOGIC := '0'; --identifies if slave is stretching scl
BEGIN
--generate the timing for the bus clock (scl_clk) and the data clock (data_clk)
PROCESS(clk, reset_n)
VARIABLE count : INTEGER RANGE 0 TO divider*4; --timing for clock generation
BEGIN
IF(reset_n = '0') THEN --reset asserted
--stretch <= '0';
count := 0;
ELSIF(clk'EVENT AND clk = '1') THEN
IF(count = divider*4-1) THEN --end of timing cycle
count := 0; --reset timer
ELSIF(stretch = '0') THEN --clock stretching from slave not detected
count := count + 1; --continue clock generation timing
END IF;
CASE count IS
WHEN 0 TO divider-1 => --first 1/4 cycle of clocking scl=0 et sda=0 start sequence
scl_clk <= '0';
data_clk <= '0';
WHEN divider TO divider*2-1 => --second 1/4 cycle of clocking scl=0 et sda=1 lecture
scl_clk <= '0';
data_clk <= '1';
WHEN divider*2 TO divider*3-1 => --third 1/4 cycle of clocking ecriture ????
scl_clk <= 'Z'; --release scl
IF(scl = '0') THEN --detect if slave is stretching clock
stretch <= '1';
ELSE
stretch <= '0';
END IF;
data_clk <= '1';
WHEN OTHERS => --last 1/4 cycle of clocking sda =0 donc stop sequence
scl_clk <= 'Z';
data_clk <= '0';
END CASE;
END IF;
END PROCESS;
I search for that but i didn't find an explaination so please help me it's urgent :cry: Thanks in advance
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did you run a testbench to see how it works?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Did you run a testbench to see how it works? --- Quote End --- thanks for your response. No i did not run a test bench because i think that it 's I2C's clock behavor and data_clk will be the sensibility for the FSM process to wich i will run a test bench. i just want to understand why data clock and scl_clk are generated in that way.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page