1. 用这个板子做个什么功能来学习?板子上有个温度传感器,看下官方是否有例程,板子售价1780元,相当的贵,下面是I2C接口,
看下芯片的引脚图
2. 资料下载地址,得注册账号
https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/start?redirect=1
3. 下面的例程,包括温度传感器的参考代码
4. 找到温度传感器的参考代码
5. 研究下代码吗,不过我VHDL不太懂,所以要研究下代码
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.math_real.all;
use IEEE.std_logic_arith.all; -- Use the package defined in the TWICtl.vhd file
use work.TWIUtils.ALL; -- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all; entity TempSensorCtl is
Generic (CLOCKFREQ : natural := ); -- input CLK frequency in MHz
Port (
TMP_SCL : inout STD_LOGIC;
TMP_SDA : inout STD_LOGIC;
-- TMP_INT : in STD_LOGIC; -- Interrupt line from the ADT7420, not used in this project
-- TMP_CT : in STD_LOGIC; -- Critical Temperature interrupt line from ADT7420, not used in this project TEMP_O : out STD_LOGIC_VECTOR( downto ); ---bit two's complement temperature with sign bit
RDY_O : out STD_LOGIC; --'' when there is a valid temperature reading on TEMP_O
ERR_O : out STD_LOGIC; --'' if communication error CLK_I : in STD_LOGIC;
SRST_I : in STD_LOGIC
);
end TempSensorCtl; architecture Behavioral of TempSensorCtl is -- TWI Controller component declaration
component TWICtl
generic
(
CLOCKFREQ : natural := ; -- input CLK frequency in MHz
ATTEMPT_SLAVE_UNBLOCK : boolean := false --setting this true will attempt
--to drive a few clock pulses for a slave to allow to finish a previous
--interrupted read transfer, otherwise the bus might remain locked up
);
port (
MSG_I : in STD_LOGIC; --new message
STB_I : in STD_LOGIC; --strobe
A_I : in STD_LOGIC_VECTOR ( downto ); --address input bus
D_I : in STD_LOGIC_VECTOR ( downto ); --data input bus
D_O : out STD_LOGIC_VECTOR ( downto ); --data output bus
DONE_O : out STD_LOGIC; --done status signal
ERR_O : out STD_LOGIC; --error status
ERRTYPE_O : out error_type; --error type
CLK : in std_logic;
SRST : in std_logic;
----------------------------------------------------------------------------------
-- TWI bus signals
----------------------------------------------------------------------------------
SDA : inout std_logic; --TWI SDA
SCL : inout std_logic --TWI SCL
);
end component; ----------------------------------------------------------------------------------
-- Definitions for the I2C initialization vector
----------------------------------------------------------------------------------
constant IRD : std_logic := ''; -- init read
constant IWR : std_logic := ''; -- init write constant ADT7420_ADDR : std_logic_vector( downto ) := ""; -- TWI Slave Address
constant ADT7420_RID : std_logic_vector( downto ) := x"0B"; -- ID Register Address for the ADT7420
constant ADT7420_RRESET : std_logic_vector( downto ) := x"2F"; -- Software Reset Register
constant ADT7420_RTEMP : std_logic_vector( downto ) := x""; -- Temperature Read MSB Address
constant ADT7420_ID : std_logic_vector( downto ) := x"CB"; -- ADT7420 Manufacturer ID constant DELAY : NATURAL := ; --ms
constant DELAY_CYCLES : NATURAL := natural(ceil(real(DELAY**CLOCKFREQ)));
constant RETRY_COUNT : NATURAL := ; -- State MAchine states definition
type state_type is (
stIdle, -- Idle State
stInitReg, -- Send register address from the init vector
stInitData, -- Send data byte from the init vector
stRetry, -- Retry state reached when there is a bus error, will retry RETRY_COUNT times
stReadTempR, -- Send temperature register address
stReadTempD1, -- Read temperature MSB
stReadTempD2, -- Read temperature LSB
stError -- Error state when reached when there is a bus error after a successful init; stays here until reset
);
signal state, nstate : state_type; constant NO_OF_INIT_VECTORS : natural := ; -- number of init vectors in TempSensInitMap
constant DATA_WIDTH : integer := + + ; -- RD/WR bit + byte register address + byte data
constant ADDR_WIDTH : natural := natural(ceil(log(real(NO_OF_INIT_VECTORS), 2.0))); type TempSensInitMap_type is array ( to NO_OF_INIT_VECTORS-) of std_logic_vector(DATA_WIDTH- downto );
signal TempSensInitMap: TempSensInitMap_type := (
IRD & x"0B" & x"CB", -- Read ID R[0x0B]=0xCB
IWR & x"2F" & x"", -- Reset R[0x2F]=don't care
IRD & x"0B" & x"CB" -- Read ID R[0x0B]=0xCB
); signal initWord: std_logic_vector (DATA_WIDTH- downto );
signal initA : natural range to NO_OF_INIT_VECTORS := ; --init vector index
signal initEn : std_logic; --Two-Wire Controller signals
signal twiMsg, twiStb, twiDone, twiErr : std_logic;
signal twiDi, twiDo, twiAddr : std_logic_vector( downto ); --Wait counter used between retry attempts
signal waitCnt : natural range to DELAY_CYCLES := DELAY_CYCLES;
signal waitCntEn : std_logic; --Retry counter to count down attempts to get rid of a bus error
signal retryCnt : natural range to RETRY_COUNT := RETRY_COUNT;
signal retryCntEn : std_logic;
-- Temporary register to store received data
signal tempReg : std_logic_vector( downto ) := (others => '');
-- Flag indicating that a new temperature data is available
signal fReady : boolean := false;
begin ----------------------------------------------------------------------------------
-- Outputs
----------------------------------------------------------------------------------
TEMP_O <= tempReg( downto ); RDY_O <= '' when fReady else
'';
ERR_O <= '' when state = stError else
''; ----------------------------------------------------------------------------------
-- I2C Master Controller
----------------------------------------------------------------------------------
Inst_TWICtl : TWICtl
generic map (
ATTEMPT_SLAVE_UNBLOCK => true,
CLOCKFREQ =>
)
port map (
MSG_I => twiMsg,
STB_I => twiStb,
A_I => twiAddr,
D_I => twiDi,
D_O => twiDo,
DONE_O => twiDone,
ERR_O => twiErr,
ERRTYPE_O => open,
CLK => CLK_I,
SRST => SRST_I,
SDA => TMP_SDA,
SCL => TMP_SCL
); ----------------------------------------------------------------------------------
-- Initialiation Map RAM
----------------------------------------------------------------------------------
initWord <= TempSensInitMap(initA); InitA_CNT: process (CLK_I)
begin
if Rising_Edge(CLK_I) then
if (state = stIdle or initA = NO_OF_INIT_VECTORS) then
initA <= ;
elsif (initEn = '') then
initA <= initA + ;
end if;
end if;
end process; ----------------------------------------------------------------------------------
-- Delay and Retry Counters
----------------------------------------------------------------------------------
Wait_CNT: process (CLK_I)
begin
if Rising_Edge(CLK_I) then
if (waitCntEn = '') then
waitCnt <= DELAY_CYCLES;
else
waitCnt <= waitCnt - ;
end if;
end if;
end process; Retry_CNT: process (CLK_I)
begin
if Rising_Edge(CLK_I) then
if (state = stIdle) then
retryCnt <= RETRY_COUNT;
elsif (retryCntEn = '') then
retryCnt <= retryCnt - ;
end if;
end if;
end process; ----------------------------------------------------------------------------------
-- Temperature Registers
----------------------------------------------------------------------------------
TemperatureReg: process (CLK_I)
variable temp : std_logic_vector( downto );
begin
if Rising_Edge(CLK_I) then
--MSB
if (state = stReadTempD1 and twiDone = '' and twiErr = '') then
temp := twiDo;
end if;
--LSB
if (state = stReadTempD2 and twiDone = '' and twiErr = '') then
tempReg <= temp & twiDo;
end if;
end if;
end process; ----------------------------------------------------------------------------------
-- Ready Flag
----------------------------------------------------------------------------------
ReadyFlag: process (CLK_I)
begin
if Rising_Edge(CLK_I) then
if (state = stIdle or state = stError) then
fReady <= false;
elsif (state = stReadTempD2 and twiDone = '' and twiErr = '') then
fReady <= true;
end if;
end if;
end process; ----------------------------------------------------------------------------------
-- Initialization FSM & Continuous temperature read
----------------------------------------------------------------------------------
SYNC_PROC: process (CLK_I)
begin
if (CLK_I'event and CLK_I = '') then
if (SRST_I = '') then
state <= stIdle;
else
state <= nstate;
end if;
end if;
end process; OUTPUT_DECODE: process (state, initWord, twiDone, twiErr, twiDo, retryCnt, waitCnt, initA)
begin
twiStb <= ''; --byte send/receive strobe
twiMsg <= ''; --new transfer request (repeated start)
waitCntEn <= ''; --wait countdown enable
twiDi <= "--------"; --byte to send
twiAddr <= ADT7420_ADDR & ''; --I2C device address with R/W bit
initEn <= ''; --increase init map address
retryCntEn <= ''; --retry countdown enable case (state) is
when stIdle => when stInitReg => --this state sends the register address from the current init vector
twiStb <= '';
twiMsg <= '';
twiAddr() <= IWR; --Register address is a write
twiDi <= initWord( downto );
when stInitData => --this state sends the data byte from the current init vector
twiStb <= '';
twiAddr() <= initWord(initWord'high); --could be read or write
twiDi <= initWord( downto );
if (twiDone = '' and
(twiErr = '' or (initWord() = IWR and initWord( downto ) = ADT7420_RRESET)) and
(initWord(initWord'high) = IWR or twiDo = initWord(7 downto 0))) then
initEn <= '';
end if;
when stRetry=> --in case of an I2C error during initialization this state will be reached
if (retryCnt /= ) then
waitCntEn <= '';
if (waitCnt = ) then
retryCntEn <= '';
end if;
end if; when stReadTempR => --this state sends the temperature register address
twiStb <= '';
twiMsg <= '';
twiDi <= ADT7420_RTEMP;
twiAddr() <= IWR; --Register address is a write
when stReadTempD1 => --this state reads the temperature MSB
twiStb <= '';
twiAddr() <= IRD;
when stReadTempD2 => --this state reads the temperature LSB
twiStb <= '';
twiAddr() <= IRD; when stError => --in case of an I2C error during temperature poll
null; --stay here
end case; end process; NEXT_STATE_DECODE: process (state, twiDone, twiErr, initWord, twiDo, retryCnt, waitCnt)
begin
--declare default state for nstate to avoid latches
nstate <= state; --default is to stay in current state case (state) is
when stIdle =>
nstate <= stInitReg; when stInitReg =>
if (twiDone = '') then
if (twiErr = '') then
nstate <= stRetry;
else
nstate <= stInitData;
end if;
end if; when stInitData =>
if (twiDone = '') then
if (twiErr = '') then
nstate <= stRetry;
else
if (initWord(initWord'high) = IRD and twiDo /= initWord(7 downto 0)) then
nstate <= stRetry;
elsif (initA = NO_OF_INIT_VECTORS-) then
nstate <= stReadTempR;
else
nstate <= stInitReg;
end if;
end if;
end if;
when stRetry =>
if (retryCnt = ) then
nstate <= stError;
elsif (waitCnt = ) then
nstate <= stInitReg; --new retry attempt
end if; when stReadTempR =>
if (twiDone = '') then
if (twiErr = '') then
nstate <= stError;
else
nstate <= stReadTempD1;
end if;
end if;
when stReadTempD1 =>
if (twiDone = '') then
if (twiErr = '') then
nstate <= stError;
else
nstate <= stReadTempD2;
end if;
end if;
when stReadTempD2 =>
if (twiDone = '') then
if (twiErr = '') then
nstate <= stError;
else
nstate <= stReadTempR;
end if;
end if; when stError =>
null; --stay when others =>
nstate <= stIdle;
end case;
end process; end Behavioral;