4

我正在尝试一些基本上涉及使用 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。

任何人都可以阐明如何克服这个问题吗?非常感激。

4

3 回答 3

5

这里没有错。警告表示write_temp_0始终为 0 - 也就是说,警告仅适用于 的第 0 位write_temp,而不适用于其他 7 位。

这是意料之中的,因为您从来没有将位 0 ​​设置write_temp为除 0 之外的任何值。合成器对此进行了处理,并通过简单地将其修整为常数 0 而不是连接到逻辑来对其进行优化。

所以试试代码,看看它是否有效 - 如果没有,可能是由于其他原因。

此外,在编写和验证这样的代码时,模拟器是一个很棒的工具 - 它可以让您非常轻松地定位代码中的逻辑错误。所以没有理由不去了解如何使用它。

于 2012-08-29T07:10:16.300 回答
1

亲爱的同样的问题我在 fir 上运行我的代码时遇到同样的问题,我已经运行了你的代码,它合成但由于警告它显示你的输入和 clk 的未定义值,不要分配 0 值,尝试输入不同的值,如 write_temp 7到 1. 我不是 vhdl 的完整专家,但是当我以类似的方式进行此更改时,我克服了这些警告,希望这对您也有用。

于 2014-02-06T16:53:10.537 回答
-1

我猜,这个警告(FF/Latch)发生在我们忘记为某些信号赋值时(或者甚至我们认为没有必要赋值),特别是当有一些条件比如 if-else 时。预计对于所有条件,我们都会分配一个值。因此,它使我们的代码在每个条件下都重复一些分配变得整洁且冗长,但我们可以在进程开始之后和上升之前为所有这些信号(FF/Latch 警告指的是它们)设置一个初始值-边缘。例如,在 STATE_Transition 过程中,在 begin 和 ifrising_edge 之间,您应该写 write_temp <= (others=>'0')。

于 2020-04-02T23:04:37.247 回答