Beginning FPGA Programming - Partie58
Beginning FPGA Programming - Partie58
282
Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?
283
Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?
Figure 1223 shows that temperature_sensor_top is the top-level design. It includes two modules:
pll_29p5M and uartTOi2c. Under the uartTOi2c module, there are another two modules: i2c_master and
uart_16550_wrapper. Both of them are third-party IPs.
Based on the temperature sensor design block diagram, we will need to create two more modules. One
is temperature_sensor_top.vhd and the other one is uartTOi2c.vhd. The temperature_sensor_top provides
all of the connections from outside the FPGA and connects all the ports to the right modules. The uartTOi2c.
vhd is a little bit more complicated. Not only is it connecting the upper-level module (temperature_sensor_
top) to the i2c_master and uart_16550_wrapper, but it also has a state machine to generate data for the
UART_16550_wrapper to send to the PC and decode the command from the uart_16550_wrapper. All the
command and status definitions are in the next section, “Define What Needs to Be Done—Command and
Status Registers.”
The example code section will have both new design .vhdl files (temperature_sensor_top.vhd and
uartTOi2c.vhd) and simulation test bench files for ModelSim to do the simulation. This is the first time we
are using .vhdl files as a test bench.
284
Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?
In the command register table, we defined that the register at memory address location 0x0000 can turn
on or off the external 8 LED lights.
The register at memory address location 0x0010 (Table 13-2) is used to send a command to the I2C
Master to create I2C commands to ADT7420. The IC2 command includes read/write (bit 23), I2C slave
address (bit 22 to 16), and two bytes (bit 15 to 0). The I2C slave address for ADT7420 is 0x48, which is from
the ADT7420 datasheet. We will have examples later to show you how to use this command.
The last command at memory address location 0x8000 is used to request that all of the status registers
(Table 13-3) are read back from the BeMicro MAX 10.
entity temperature_sensor_top is
port(
-- Clock ins, SYS_CLK = 50MHz
SYS_CLK : in std_logic;
-- LED outs
USER_LED : out std_logic_vector(8 downto 1);
begin
285
Chapter 13 ■ Temperature Sensors: Is It Hot in Here, or Is It Just Me?
dealy_p: process(SYS_CLK)
begin
if(rising_edge(SYS_CLK) )THEN
delay_8 <= delay_8(6 downto 0)&locked; -- create active LOW reset
END IF;
END PROCESS;
13.5.2.2 uartTOi2c.vhd Code
This is the major design in this example (Listing 13-2). This is because it does all of the decoding of
commands from the UART and generates status updates to the UART. It also translates the commands from
the PC and sends the correct operation sequence for the i2C Master module. There are three processes in
this module: register_map, i2c_data_p, and register_update.
The register_map process works as a command decoder. It decodes the s_uart_rx_add when s_uart_
rx_rdy is high and copies the 32-bit s_uart_rx_data to the correct registers (e.g., 0x0000 is mapped to
r_leds).
The second process is i2c_data_p. It copies data from the I2C Master byte read output to reg02 in the
lower 16 bits (15 down to 0). It is a special shift register, which is similar to the 8-bit shift register which shifts
1 bit at a time in Chapter 10. This special shift register shifts 8 bits at a time such that two 8 bytes (16 bits)
from the i2c_Master can be stored in one 32-bit register. This process will translate the 13-bit ADC data from
the temperature sensor to degrees Celsius. This simple bit shift to the left for 9 bits happens every clock
cycles. Figure 13-14 shows that the 25̊C digital output bit (15:3) is "0000110010000." The 2-byte (16 bits)
output bits should look like "0000110010000000." If we shift the 2-byte version 9 bits to left, then we will get
a 4-byte "0000000000011001 0000000000000000." The higher 2-byte binary value is "0000000000011001,"
which equals 25 in unsigned value. This shows that we can use the shift register to do the math.
The last process is register_update. It is actually a small state machine. It is used to generate a sequence
of register reads by the command address in 0x8000 with the value all zero and to send the Table 13-3 values
to the uart_16550_wrapper.
286