我正在尝试一些基本上涉及使用FPGA并从温度传感器读取值的代码。
代码如下:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ds18b20 is
Port ( clk : in STD_LOGIC; --50Mhz oscillator onboard
dq : inout STD_LOGIC;
temp_h : out STD_LOGIC_VECTOR (7 downto 0);
temp_l : out STD_LOGIC_VECTOR (7 downto 0);
temperature : out STD_LOGIC_VECTOR (11 downto 0));
end ds18b20;
architecture Behavioral of ds18b20 is
--RESET : RESET AND PRESENCE PULSE
--CMD_CC : SKIP ROM [CCh]
--WRITE_BYTE : WRITE SCRATCHPAD COMMAND
--WRITE_LOW
--WRITE_HIGH
--READ_BIT :
TYPE STATE_TYPE is (RESET,CMD_CC,WRITE_BYTE,WRITE_LOW,WRITE_HIGH,READ_BIT,CMD_44,WAIT800MS,CMD_BE,GET_TMP,WAIT4MS);
signal STATE: STATE_TYPE:=RESET;
signal clk_temp : std_logic:='0';
signal clk1m : std_logic;
signal write_temp : std_logic_vector(7 downto 0) := (others => '0');
signal TMP : std_logic_vector(11 downto 0);
signal tmp_bit : std_logic;
signal WRITE_BYTE_CNT : integer range 0 to 8:=0;
signal WRITE_LOW_CNT : integer range 0 to 2:=0;
signal WRITE_HIGH_CNT : integer range 0 to 2:=0;
signal READ_BIT_CNT : integer range 0 to 3:=0;
signal GET_TMP_CNT : integer range 0 to 12:=0;
signal cnt : integer range 0 to 100001:=0;
signal count : integer range 0 to 25:=0;
signal WRITE_BYTE_FLAG : integer range 0 to 4:=0;
begin
ClkDivider: process (clk)
begin
if rising_edge(clk) then
if (count = 24) then
count <= 0;
clk_temp<= not clk_temp;
else
count <= count +1;
end if;
end if;
clk1m<=clk_temp;
end Process;
STATE_TRANSITION: process(STATE,clk)
begin
if rising_edge(clk) then
case STATE is
--Master issues RESET pulse
when RESET=>
if (cnt>=0 and cnt<500) then
dq<='0';
cnt<=cnt+1;
STATE<=RESET;
--Master waits for PRESENCE pulse
elsif (cnt>=500 and cnt<1000) then
dq<='Z';
cnt<=cnt+1;
STATE<=RESET;
elsif (cnt>=1000) then
cnt<=0;
STATE<=CMD_CC; -- SKIP ROM COMMAND STATE
end if;
when CMD_CC=> -- SKIP ROM COMMAND
write_temp<="11001100"; -- SKIP ROM BINARY COMMAND
STATE<=WRITE_BYTE; -- modified here
--Master issues write scratchpad command
when WRITE_BYTE=>
case WRITE_BYTE_CNT is
when 0 to 7=>
if (write_temp(WRITE_BYTE_CNT)='0') then
STATE<=WRITE_LOW;
else
STATE<=WRITE_HIGH;
end if;
WRITE_BYTE_CNT<=WRITE_BYTE_CNT+1;
when 8=>
if (WRITE_BYTE_FLAG=0) then -- ????0XCC??
STATE<=CMD_44; --CONVERT TEMPERATURE
WRITE_BYTE_FLAG<=1;
elsif (WRITE_BYTE_FLAG=1) then --?0X44??
STATE<=RESET;
WRITE_BYTE_FLAG<=2;
elsif (WRITE_BYTE_FLAG=2) then --????0XCC??
STATE<=CMD_BE; -- READ SCRATCHPAD
WRITE_BYTE_FLAG<=3;
elsif (WRITE_BYTE_FLAG=3) then --?0XBE??
STATE<=GET_TMP;
WRITE_BYTE_FLAG<=0;
end if;
WRITE_BYTE_CNT<=0;
end case;
when WRITE_LOW=>
case WRITE_LOW_CNT is
when 0=>
dq<='0';
if (cnt=78) then
cnt<=0;
WRITE_LOW_CNT<=1;
else
cnt<=cnt+1;
end if;
when 1=>
dq<='Z';
if (cnt=2) then
cnt<=0;
WRITE_LOW_CNT<=2;
else
cnt<=cnt+1;
end if;
when 2=>
STATE<=WRITE_BYTE;
WRITE_LOW_CNT<=0;
when others=>WRITE_LOW_CNT<=0;
end case;
when WRITE_HIGH=>
case WRITE_HIGH_CNT is
when 0=>
dq<='0';
if (cnt=8) then
cnt<=0;
WRITE_HIGH_CNT<=1;
else
cnt<=cnt+1;
end if;
when 1=>
dq<='Z';
if (cnt=72) then
cnt<=0;
WRITE_HIGH_CNT<=2;
else
cnt<=cnt+1;
end if;
when 2=>
STATE<=WRITE_BYTE;
WRITE_HIGH_CNT<=0;
when others=>WRITE_HIGH_CNT<=0;
end case;
when READ_BIT=>
case READ_BIT_CNT is
when 0=>
dq<='0';
if (cnt=4) then
READ_BIT_CNT<=1;
cnt<=0;
else
cnt<=cnt+1;
end if;
when 1=>
dq<='Z';
if (cnt=4) then
READ_BIT_CNT<=2;
cnt<=0;
else
cnt<=cnt+1;
end if;
when 2=>
TMP_BIT<=dq;
if (cnt=1) then
READ_BIT_CNT<=3;
cnt<=0;
else
cnt<=cnt+1;
end if;
when 3=>
if (cnt=45) then
cnt<=0;
READ_BIT_CNT<=0;
STATE<=GET_TMP;
else
cnt<=cnt+1;
end if;
when others=>READ_BIT_CNT<=0;
end case;
when CMD_44=> -- CONVERT TEMPERATURE
write_temp<="01000100"; -- CONVERT TEMPERATURE BINARY COMMAND
STATE<=WRITE_BYTE;
when WAIT800MS=>
if (cnt>=100000) then
STATE<=RESET;
cnt<=0;
else
cnt<=cnt+1;
STATE<=WAIT800MS;
end if;
when CMD_BE=> -- READ SCRATCHPAD
write_temp<="10111110"; -- READ SCRATHPAD BINARY COMMAND
STATE<=WRITE_BYTE;
when GET_TMP=>
case GET_TMP_CNT is
when 0 to 11=>
STATE<=READ_BIT;
TMP(GET_TMP_CNT)<=TMP_BIT;
GET_TMP_CNT<=GET_TMP_CNT+1;
when 12=>
GET_TMP_CNT<=0;
STATE<=WAIT4MS;
end case;
when WAIT4MS=>
if (cnt>=4000) then
STATE<=RESET;
cnt<=0;
else
cnt<=cnt+1;
STATE<=WAIT4MS;
end if;
when others=>STATE<=RESET;
end case;
end if;
end process;
temp_h<='0'&TMP(11 downto 5);
temp_l<="0000"&TMP(4 downto 1);
temperature <= TMP;
end Behavioral;
我得到的警告是
WARNING:Xst:1293 - FF/Latch <write_temp_0> has a constant value of 0 in block <ds18b20>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1710 - FF/Latch <Mtridata_dq> (without init value) has a constant value of 0 in block <ds18b20>. This FF/Latch will be trimmed during the optimization process.
write_temp是一个包含传感器二进制命令的变量。基本上,我将通过“dq”双向端口将这些命令发送到传感器。现在,警告声明write_temp始终为0,这意味着我无法指示传感器完全执行任何操作,因为它始终为0。
有谁能请说明如何克服这个问题? 非常感谢。
答案 0 :(得分:5)
这里没有错。警告说write_temp_0
始终为0 - 也就是说,警告仅适用于write_temp
的第0位,而不适用于其他7位。
这是可以预料到的,因为你永远不会将write_temp
的第0位设置为0以外的任何东西。合成器会选择它,并通过简单地将其修剪为常数0而不是连接来优化它逻辑。
所以试试代码,看它是否有效 - 如果没有,可能是由于其他原因。
此外,在编写和验证这样的代码时,模拟器是一个很棒的工具 - 它可以让你很容易地在代码中找到逻辑错误。所以没有理由不去了解如何使用它。
答案 1 :(得分:1)
亲爱的同样的问题我面临同样的问题在fir上运行我的代码,我已经运行你的代码合成但是由于警告它显示你的输入和clk的未定义值,不要分配0值,尝试放不同的值像write_temp 7到1.我不是vhdl的完全专家,但是当我做出这种改变的方式类似于我克服这些警告时,希望这也适合你。
答案 2 :(得分:-1)
我猜想,当我们忘记为某些信号分配一些值(或者甚至我们认为没有必要分配一些值)时,会出现此警告(FF /闩锁),尤其是在某些情况下,例如if-其他。期望我们为所有条件分配一个值。因此,它使我们的代码整洁,也很长,需要在每种情况下重复进行一些分配,但是我们可以为所有这些信号(FF / Latch警告所指的信号)设置一个刚好在过程开始之后以及上升之前的初始值。 -边缘。 例如,在STATE_Transition过程中,在开始和上升之间,应写write_temp <=(others =>'0')。