You are on page 1of 5

Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?

13.5.3 Example Simulation Codes


This is the first time we have a simulation test bench. It is working as a "test bench" for the design files. Most
of the time the test bench files can run only in simulation but NOT in real hardware. This is because the test
bench not only includes the design files but also has to simulate the external world. In this case, they are
physical UART interfaces, ADT7420 I2C interfaces, LEDs, and 50 MHz clock sources.

13.5.3.1 tb_temp_sensor_top.vhd Code
This test bench includes an i2c slave model (i2c_slave) and the temperature_sensor_top design, which
we call the unit under test in the test bench. We use test_data as an array of bytes to send to the UART
interface. There is a new std_logic value "H" which is used in this test bench for the I2C bus scl (serial clock)
and sda (serial data) signals. This "H" value means a weak pull-up (10K ohm) resistor on the bus which is
used to simulate the I2C bus 10k pull-up resistor on the board (Figure 13-22). There is a VHDL 2008 new
method that gets used in this test bench. Following is that piece of code:

s_br_clk_uart_o <= << signal .tb_temp_sensor_top.uut.uartTOi2c_pm.s_uart_br_clk : std_


logic >>

This VHDL code means the s_uart_br_clk value, which is in the uartTOi2c_pm module that is
assigned to s_br_clk_uart_o in the top level of the design.
Following is the VHDL code:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity tb_temp_sensor_top is
end tb_temp_sensor_top;

architecture behavior of tb_temp_sensor_top is

--Inputs
signal sys_clk_i : std_logic := '0';
signal uart_din_emu : std_logic := '0';
signal uart_rst_emu : std_logic := '0';

--Outputs
signal uart_dout_emu : std_logic;
signal s_br_clk_uart_o : std_logic;
signal uart_leds_emu : std_logic_vector (7 downto 0);

--i2c slave
signal rst : std_logic;
signal read_req : std_logic;
signal data_to_master : std_logic_vector(7 downto 0) := (others => '0');
signal data_valid : std_logic;
signal data_from_master : std_logic_vector(7 downto 0);

signal scl, sda : std_logic := 'H'; -- 'H' is to simulate Pull up resistors

292
Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?

constant system_clock_period : time := 20 ns;


constant uart_clock_period : time := 34 ns; -- 29.5MHz
constant bit_period : time := uart_clock_period*32; -- 921600bps

type sample_array is array (natural range<>) of std_logic_vector (7 downto 0);

constant test_data : sample_array :=


(
-- READ TDA7420 ID CMD -1: Write 0xb to I2C address 0x48
X"00", -- BYTE1
X"10", -- BYTE2
X"80", -- BYTE3
X"48", -- BYTE4
X"00", -- BYTE5
X"0b", -- BYTE6
-- READ ID CMD -2: Read from I2C
X"00", -- BYTE1
X"10", -- BYTE2
X"80", -- BYTE3
X"C8", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- DUMMY for waiting
X"00", -- BYTE1
X"20", -- BYTE2
X"00", -- BYTE3
X"00", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- DUMMY for waiting
X"00", -- BYTE1
X"20", -- BYTE2
X"00", -- BYTE3
X"00", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- Read registers to UART
X"80", -- BYTE1
X"00", -- BYTE2
X"00", -- BYTE3
X"00", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- DUMMY for waiting
X"00", -- BYTE1
X"20", -- BYTE2
X"00", -- BYTE3
X"00", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- DUMMY for waiting

293
Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?

X"00", -- BYTE1
X"20", -- BYTE2
X"00", -- BYTE3
X"00", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- Reset the ADC write 0x00 to ADT7420 register offset:0x2F
X"00", -- BYTE1
X"10", -- BYTE2
X"C0", -- BYTE3
X"48", -- BYTE4
X"00", -- BYTE5
X"2F", -- BYTE6
-- Write 0x80 to offset 0x03 to ADT7420 to set 13bit
X"00", -- BYTE1
X"10", -- BYTE2
X"C0", -- BYTE3
X"48", -- BYTE4
X"80", -- BYTE5
X"03", -- BYTE6
-- dummy
X"00", -- BYTE1
X"20", -- BYTE2
X"00", -- BYTE3
X"00", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- Read two byte - 1 From I2C address 0x48
X"00", -- BYTE1
X"10", -- BYTE2
X"80", -- BYTE3
X"48", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- Read two byte - 2
X"00", -- BYTE1
X"10", -- BYTE2
X"C0", -- BYTE3
X"C8", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6
-- dummy Waiting
X"00", -- BYTE1
X"20", -- BYTE2
X"00", -- BYTE3
X"00", -- BYTE4
X"00", -- BYTE5
X"00", -- BYTE6

-- Read back from I2C


X"80", -- BYTE1

294
Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?

X"00", -- BYTE2
X"00", -- BYTE3
X"00", -- BYTE4
X"00", -- BYTE5
X"00" -- BYTE6
);

begin

-- Instantiate the Unit Under Test (UUT)


uut : entity work.temperature_sensor_top port map(
SYS_CLK => sys_clk_i,
USER_LED => uart_leds_emu,
GPIO_J3_39 => uart_dout_emu,
GPIO_J3_40 => uart_din_emu,
ADT7420_CT => '0', -- Not use
ADT7420_INT => '0', -- NOt use
ADT7420_SCL => scl, -- I2C SCL
ADT7420_SDA => sda -- I2C SDA
);

i2c_slave : entity work.I2C_slave


generic map(
SLAVE_ADDR => "1001000") -- address 0x48
port map(
scl => scl,
sda => sda,
clk => sys_clk_i,
rst => rst,
-- User interface
read_req => read_req,
data_to_master => data_to_master,
data_valid => data_valid,
data_from_master => data_from_master);

scl <= 'H';


sda <= 'H';

s_br_clk_uart_o <= << signal


.tb_temp_sensor_top.uut.uartTOi2c_pm.s_uart_br_clk : std_logic >>;

i2c_data : process(sys_clk_i)
begin
if(rising_edge(sys_clk_i)) then
if read_req = '1' then -- the read back value increment by one every read
data_to_master <= std_logic_vector(unsigned(data_to_master) +1);
end if;
end if;
end process;

uart_clock_process : process

295
Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?

begin
sys_clk_i <= '0';
wait for system_clock_period/2;
sys_clk_i <= '1';
wait for system_clock_period/2;
end process;

rst_p : process
begin
rst <= '1';
wait for 200 ns;
wait until rising_edge(sys_clk_i);
rst <= '0';
wait;
end process;

-- Stimulus process
stim_proc : process
begin
-- hold reset
wait for 50 ns;
wait for system_clock_period*10;
-- insert stimulus here
uart_din_emu <= '1';

wait for 10 us;

-- look through test_data


for j in test_data'range loop
-- tx_start_bit
uart_din_emu <= '0';
wait for bit_period;

-- Byte serializer
for i in 0 to 7 loop
uart_din_emu <= test_data(j)(i);
wait for bit_period;
end loop;

-- tx_stop_bit
uart_din_emu <= '1';
wait for bit_period;
wait for 5 us;
end loop;

wait;
end process;

end;

296

You might also like