Line 35... |
Line 35... |
---- ----
|
---- ----
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
|
|
-- CVS Log
|
-- CVS Log
|
--
|
--
|
-- $Id: i2c_master_byte_ctrl.vhd,v 1.1 2001-11-05 12:02:33 rherveille Exp $
|
-- $Id: i2c_master_byte_ctrl.vhd,v 1.2 2002-11-30 22:24:37 rherveille Exp $
|
--
|
--
|
-- $Date: 2001-11-05 12:02:33 $
|
-- $Date: 2002-11-30 22:24:37 $
|
-- $Revision: 1.1 $
|
-- $Revision: 1.2 $
|
-- $Author: rherveille $
|
-- $Author: rherveille $
|
-- $Locker: $
|
-- $Locker: $
|
-- $State: Exp $
|
-- $State: Exp $
|
--
|
--
|
-- Change History:
|
-- Change History:
|
-- $Log: not supported by cvs2svn $
|
-- $Log: not supported by cvs2svn $
|
|
-- Revision 1.1 2001/11/05 12:02:33 rherveille
|
|
-- Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
|
|
-- Code updated, is now up-to-date to doc. rev.0.4.
|
|
-- Added headers.
|
|
--
|
|
|
|
|
|
|
|
|
--
|
--
|
Line 59... |
Line 64... |
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
|
|
entity i2c_master_byte_ctrl is
|
entity i2c_master_byte_ctrl is
|
generic(
|
|
Tcq : time := 1 ns
|
|
);
|
|
port (
|
port (
|
clk : in std_logic;
|
clk : in std_logic;
|
rst : in std_logic; -- synchronous active high reset (WISHBONE compatible)
|
rst : in std_logic; -- synchronous active high reset (WISHBONE compatible)
|
nReset : in std_logic; -- asynchornous active low reset (FPGA compatible)
|
nReset : in std_logic; -- asynchornous active low reset (FPGA compatible)
|
ena : in std_logic; -- core enable signal
|
ena : in std_logic; -- core enable signal
|
Line 96... |
Line 98... |
);
|
);
|
end entity i2c_master_byte_ctrl;
|
end entity i2c_master_byte_ctrl;
|
|
|
architecture structural of i2c_master_byte_ctrl is
|
architecture structural of i2c_master_byte_ctrl is
|
component i2c_master_bit_ctrl is
|
component i2c_master_bit_ctrl is
|
generic(
|
|
Tcq : time := Tcq
|
|
);
|
|
port (
|
port (
|
clk : in std_logic;
|
clk : in std_logic;
|
rst : in std_logic;
|
rst : in std_logic;
|
nReset : in std_logic;
|
nReset : in std_logic;
|
ena : in std_logic; -- core enable signal
|
ena : in std_logic; -- core enable signal
|
Line 178... |
Line 177... |
|
|
-- generate shift register
|
-- generate shift register
|
shift_register: process(clk, nReset)
|
shift_register: process(clk, nReset)
|
begin
|
begin
|
if (nReset = '0') then
|
if (nReset = '0') then
|
sr <= (others => '0') after Tcq;
|
sr <= (others => '0');
|
elsif (clk'event and clk = '1') then
|
elsif (clk'event and clk = '1') then
|
if (rst = '1') then
|
if (rst = '1') then
|
sr <= (others => '0') after Tcq;
|
sr <= (others => '0');
|
elsif (ld = '1') then
|
elsif (ld = '1') then
|
sr <= din after Tcq;
|
sr <= din;
|
elsif (shift = '1') then
|
elsif (shift = '1') then
|
sr <= (sr(6 downto 0) & core_rxd) after Tcq;
|
sr <= (sr(6 downto 0) & core_rxd);
|
end if;
|
end if;
|
end if;
|
end if;
|
end process shift_register;
|
end process shift_register;
|
|
|
-- generate data-counter
|
-- generate data-counter
|
data_cnt: process(clk, nReset)
|
data_cnt: process(clk, nReset)
|
begin
|
begin
|
if (nReset = '0') then
|
if (nReset = '0') then
|
dcnt <= (others => '0') after Tcq;
|
dcnt <= (others => '0');
|
elsif (clk'event and clk = '1') then
|
elsif (clk'event and clk = '1') then
|
if (rst = '1') then
|
if (rst = '1') then
|
dcnt <= (others => '0') after Tcq;
|
dcnt <= (others => '0');
|
elsif (ld = '1') then
|
elsif (ld = '1') then
|
dcnt <= (others => '1') after Tcq; -- load counter with 7
|
dcnt <= (others => '1'); -- load counter with 7
|
elsif (shift = '1') then
|
elsif (shift = '1') then
|
dcnt <= dcnt -1 after Tcq;
|
dcnt <= dcnt -1;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process data_cnt;
|
end process data_cnt;
|
|
|
cnt_done <= '1' when (dcnt = 0) else '0';
|
cnt_done <= '1' when (dcnt = 0) else '0';
|
Line 221... |
Line 220... |
-- command interpreter, translate complex commands into simpler I2C commands
|
-- command interpreter, translate complex commands into simpler I2C commands
|
--
|
--
|
nxt_state_decoder: process(clk, nReset)
|
nxt_state_decoder: process(clk, nReset)
|
begin
|
begin
|
if (nReset = '0') then
|
if (nReset = '0') then
|
core_cmd <= I2C_CMD_NOP after Tcq;
|
core_cmd <= I2C_CMD_NOP;
|
core_txd <= '0' after Tcq;
|
core_txd <= '0';
|
|
shift <= '0';
|
shift <= '0' after Tcq;
|
ld <= '0';
|
ld <= '0' after Tcq;
|
host_ack <= '0';
|
|
c_state <= st_idle;
|
host_ack <= '0' after Tcq;
|
ack_out <= '0';
|
c_state <= st_idle after Tcq;
|
|
|
|
ack_out <= '0' after Tcq;
|
|
elsif (clk'event and clk = '1') then
|
elsif (clk'event and clk = '1') then
|
if (rst = '1') then
|
if (rst = '1') then
|
core_cmd <= I2C_CMD_NOP after Tcq;
|
core_cmd <= I2C_CMD_NOP;
|
core_txd <= '0' after Tcq;
|
core_txd <= '0';
|
|
shift <= '0';
|
shift <= '0' after Tcq;
|
ld <= '0';
|
ld <= '0' after Tcq;
|
host_ack <= '0';
|
|
c_state <= st_idle;
|
host_ack <= '0' after Tcq;
|
ack_out <= '0';
|
c_state <= st_idle after Tcq;
|
|
|
|
ack_out <= '0' after Tcq;
|
|
else
|
else
|
-- initialy reset all signal
|
-- initialy reset all signal
|
core_txd <= sr(7) after Tcq;
|
core_txd <= sr(7);
|
|
shift <= '0';
|
shift <= '0' after Tcq;
|
ld <= '0';
|
ld <= '0' after Tcq;
|
host_ack <= '0';
|
|
|
host_ack <= '0' after Tcq;
|
|
|
|
case c_state is
|
case c_state is
|
when st_idle =>
|
when st_idle =>
|
if (go = '1') then
|
if (go = '1') then
|
if (start = '1') then
|
if (start = '1') then
|
c_state <= st_start after Tcq;
|
c_state <= st_start;
|
core_cmd <= I2C_CMD_START after Tcq;
|
core_cmd <= I2C_CMD_START;
|
elsif (read = '1') then
|
elsif (read = '1') then
|
c_state <= st_read after Tcq;
|
c_state <= st_read;
|
core_cmd <= I2C_CMD_READ after Tcq;
|
core_cmd <= I2C_CMD_READ;
|
elsif (write = '1') then
|
elsif (write = '1') then
|
c_state <= st_write after Tcq;
|
c_state <= st_write;
|
core_cmd <= I2C_CMD_WRITE after Tcq;
|
core_cmd <= I2C_CMD_WRITE;
|
else -- stop
|
else -- stop
|
c_state <= st_stop after Tcq;
|
c_state <= st_stop;
|
core_cmd <= I2C_CMD_STOP after Tcq;
|
core_cmd <= I2C_CMD_STOP;
|
|
host_ack <= '1'; -- generate acknowledge signal
|
host_ack <= '1' after Tcq; -- generate acknowledge signal
|
|
end if;
|
end if;
|
|
|
ld <= '1' after Tcq;
|
ld <= '1';
|
end if;
|
end if;
|
|
|
when st_start =>
|
when st_start =>
|
if (core_ack = '1') then
|
if (core_ack = '1') then
|
if (read = '1') then
|
if (read = '1') then
|
c_state <= st_read after Tcq;
|
c_state <= st_read;
|
core_cmd <= I2C_CMD_READ after Tcq;
|
core_cmd <= I2C_CMD_READ;
|
else
|
else
|
c_state <= st_write after Tcq;
|
c_state <= st_write;
|
core_cmd <= I2C_CMD_WRITE after Tcq;
|
core_cmd <= I2C_CMD_WRITE;
|
end if;
|
end if;
|
|
|
ld <= '1' after Tcq;
|
ld <= '1';
|
end if;
|
end if;
|
|
|
when st_write =>
|
when st_write =>
|
if (core_ack = '1') then
|
if (core_ack = '1') then
|
if (cnt_done = '1') then
|
if (cnt_done = '1') then
|
c_state <= st_ack after Tcq;
|
c_state <= st_ack;
|
core_cmd <= I2C_CMD_READ after Tcq;
|
core_cmd <= I2C_CMD_READ;
|
else
|
else
|
c_state <= st_write after Tcq; -- stay in same state
|
c_state <= st_write; -- stay in same state
|
core_cmd <= I2C_CMD_WRITE after Tcq; -- write next bit
|
core_cmd <= I2C_CMD_WRITE; -- write next bit
|
|
shift <= '1';
|
shift <= '1' after Tcq;
|
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
when st_read =>
|
when st_read =>
|
if (core_ack = '1') then
|
if (core_ack = '1') then
|
if (cnt_done = '1') then
|
if (cnt_done = '1') then
|
c_state <= st_ack after Tcq;
|
c_state <= st_ack;
|
core_cmd <= I2C_CMD_WRITE after Tcq;
|
core_cmd <= I2C_CMD_WRITE;
|
else
|
else
|
c_state <= st_read after Tcq; -- stay in same state
|
c_state <= st_read; -- stay in same state
|
core_cmd <= I2C_CMD_READ after Tcq; -- read next bit
|
core_cmd <= I2C_CMD_READ; -- read next bit
|
end if;
|
end if;
|
|
|
shift <= '1' after Tcq;
|
shift <= '1';
|
core_txd <= ack_in after Tcq;
|
core_txd <= ack_in;
|
end if;
|
end if;
|
|
|
when st_ack =>
|
when st_ack =>
|
if (core_ack = '1') then
|
if (core_ack = '1') then
|
-- check for stop; Should a STOP command be generated ?
|
-- check for stop; Should a STOP command be generated ?
|
if (stop = '1') then
|
if (stop = '1') then
|
c_state <= st_stop after Tcq;
|
c_state <= st_stop;
|
core_cmd <= I2C_CMD_STOP after Tcq;
|
core_cmd <= I2C_CMD_STOP;
|
else
|
else
|
c_state <= st_idle after Tcq;
|
c_state <= st_idle;
|
core_cmd <= I2C_CMD_NOP after Tcq;
|
core_cmd <= I2C_CMD_NOP;
|
end if;
|
end if;
|
|
|
-- assign ack_out output to core_rxd (contains last received bit)
|
-- assign ack_out output to core_rxd (contains last received bit)
|
ack_out <= core_rxd after Tcq;
|
ack_out <= core_rxd;
|
|
|
-- generate command acknowledge signal
|
-- generate command acknowledge signal
|
host_ack <= '1' after Tcq;
|
host_ack <= '1';
|
|
|
core_txd <= '1' after Tcq;
|
core_txd <= '1';
|
else
|
else
|
core_txd <= ack_in after Tcq;
|
core_txd <= ack_in;
|
end if;
|
end if;
|
|
|
when st_stop =>
|
when st_stop =>
|
if (core_ack = '1') then
|
if (core_ack = '1') then
|
c_state <= st_idle after Tcq;
|
c_state <= st_idle;
|
core_cmd <= I2C_CMD_NOP after Tcq;
|
core_cmd <= I2C_CMD_NOP;
|
end if;
|
end if;
|
|
|
when others => -- illegal states
|
when others => -- illegal states
|
c_state <= st_idle after Tcq;
|
c_state <= st_idle;
|
core_cmd <= I2C_CMD_NOP after Tcq;
|
core_cmd <= I2C_CMD_NOP;
|
report ("Byte controller entered illegal state.");
|
report ("Byte controller entered illegal state.");
|
|
|
end case;
|
end case;
|
|
|
end if;
|
end if;
|