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

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!