Question: Hello, can someone explain the bytesel part to me, this is an I2C controller and i'm confused on the case statement, like explain the reasoning
Hello, can someone explain the bytesel part to me, this is an I2C controller and i'm confused on the case statement, like explain the reasoning behind the hex values assigned and why they are assigned at those specific bytesel values, thank you!
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
entity i2c_controller is
port(
clk : in std_logic;
reset : in std_logic;
dataIn : in std_logic_vector(15 downto 0);
address : in std_logic_vector(6 downto 0);
sda : inout std_logic;
scl : inout std_logic
);
end i2c_controller;
architecture UserLogic of i2c_controller is
-- I2C Master Inclusion
component i2c_master is
GENERIC(
input_clk : INTEGER := 50_000_000;
bus_clk : INTEGER := 400_000);
PORT(
clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
ena : IN STD_LOGIC;
addr : IN STD_LOGIC_VECTOR(6 DOWNTO 0);
rw : IN STD_LOGIC;
data_wr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
busy : OUT STD_LOGIC;
data_rd : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
ack_error : BUFFER STD_LOGIC;
sda : INOUT STD_LOGIC;
scl : INOUT STD_LOGIC);
END component;
-- State Machine Declaration
type state_type is(start, ready, data_valid, busy_high, repeat);
signal state : state_type;
signal busy : std_logic;
signal reset_n : std_logic;
signal ena : std_logic;
signal addr : std_logic_vector(6 downto 0);
signal rw : std_logic;
signal data_wr : std_logic_vector(7 downto 0);
signal byteSel : integer range 0 to 12:= 0;
-- Registered Internal Signals
signal InternalData : std_logic_vector(15 downto 0);
signal InternalAddr : std_logic_vector(6 downto 0);
begin
Inst_i2c_master: i2c_master
GENERIC MAP(
input_clk => 50_000_000,
bus_clk => 400_000)
PORT MAP(
clk => clk,
reset_n => reset_n,
ena => ena,
addr => addr,
rw => rw,
data_wr => data_wr,
busy => busy,
data_rd => open,
ack_error => open,
sda => sda,
scl => scl
);
-- LUT
process(byteSel, dataIn, clk)
begin
if rising_edge(clk) then
case byteSel is
when 0 => data_wr <= X"76";
when 1 => data_wr <= X"76";
when 2 => data_wr <= X"76";
when 3 => data_wr <= X"7A";
when 4 => data_wr <= X"FF";
when 5 => data_wr <= X"77";
when 6 => data_wr <= X"00";
when 7 => data_wr <= X"79";
when 8 => data_wr <= X"00";
when 9 => data_wr <= X"0"&InternalData(15 downto 12);
when 10 => data_wr <= X"0"&InternalData(11 downto 8);
when 11 => data_wr <= X"0"&InternalData(7 downto 4);
when 12 => data_wr <= X"0"&InternalData(3 downto 0);
when others => data_wr <= X"76";
end case;
end if;
end process;
-- Registering Inputs
process(clk)
begin
if rising_edge(clk) then
InternalData <= dataIn;
InternalAddr <= address;
end if;
end process;
-- State Machine
process(clk, reset)
begin
if reset = '1' then
state <= start;
ena <= '0';
byteSel <= 0;
elsif rising_edge(clk) then
case state is
when start =>
ena <= '1'; --initiate the transaction
addr <= InternalAddr; --set the address of the slave
rw <= '0'; --command 0 allows it a write
data_wr <= data_wr; --data to be written
state <= ready;
when ready =>
if busy = '1' then
ena <= '1';
state <= data_valid;
end if;
when data_valid =>
if busy = '1' then
ena <= '0';
state <= busy_high;
end if;
when busy_high =>
if busy = '0' then
state <= repeat;
end if;
when repeat =>
if byteSel < 12 then
byteSel <= byteSel + 1;
else
byteSel <= 9;
end if;
state <= start;
when others => null;
end case;
end if;
end process;
-- Assigning the reset of the I2C master to the reset of the I2C controller
reset_n <= not reset;
end UserLogic;
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
