我有下面的VHDL代码,我在一个项目中使用。我一直在使用架构中的一个过程,我想知道是否有任何其他方法,我确信有实现相同的目标。本质上,将一个数字与另一个数字进行比较,如果存在+/- 2的差异,则将其反映在输出中。我正在使用以下内容:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all, IEEE.std_logic_arith.all, IEEE.std_logic_signed;
ENTITY thermo IS
PORT (
CLK : in std_logic;
Tset, Tact : in std_logic_vector (6 DOWNTO 0);
Heaton : out std_logic
);
END ENTITY thermo;
ARCHITECTURE behavioral OF thermo IS
SIGNAL TsetINT, TactINT : integer RANGE 63 Downto -64; --INT range so no 32bit usage
BEGIN
Heat_on_off: PROCESS
VARIABLE ONOFF: std_logic;
BEGIN
TsetINT <= conv_integer (signed (Tset));--converts vector to Int
TactINT <= conv_integer (signed (Tact));--converts vector to Int
--If you read this why is it conv_integer not to_integer?? thx
ONOFF := '0'; --so variable does not hang on start
WAIT UNTIL CLK'EVENT and CLK = '1';
IF TactINT <= (TsetINT - 2) then
ONOFF := '1';
ELSIF TactINT >= (TsetINT + 2) then
ONOFF := '0';
END IF;
Heaton <= ONOFF;
END PROCESS;
END ARCHITECTURE behavioral; 我只是想比较一下,看看有没有更好的方法来做我已经做过的事情。
发布于 2015-12-05 05:42:10
为什么要将Tact和Tset转换为整数?
为什么有ONOFF变量?变量初始化似乎消除了任何滞后感,这是您想要的吗?根据你的其他代码,我打赌不会。我建议您直接赋值给信号Heaton,而不是使用变量ONOFF。
如果我要创建TsetINT和TactINt,它们将是很好的变量候选者。但是,不需要进行整数转换,因为您只需执行以下操作:
if signed(Tact) <= signed(Tset) - 2 then
...
elsif signed(Tact) >= signed(Tset) + 2 then请使用numeric_std。请问问你的教授,为什么他们教你旧的方法,而不是目前的行业实践。Numeric_std是一种IEEE标准,并根据该标准进行了更新,但std_logic_arith不是IEEE标准。
use ieee.numeric_std.all ; 发布于 2015-12-06 14:14:02
为了响应Jim的评论,我编写了一个简单的热模型测试平台来测试您的设计。
我只是更改了您的设计,使用package numeric_std而不是Synopsys包。剩下的只是美化和删除评论,与Tact是否达到Tset的问题无关。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity thermo is
port (
CLK: in std_logic;
Tset, Tact: in std_logic_vector (6 downto 0);
Heaton: out std_logic
);
end entity thermo;
architecture behavioral of thermo is
signal TsetINT, TactINT: integer range 63 downto -64;
begin
HEAT_ON_OFF:
process
variable ONOFF: std_logic;
begin
TsetINT <= to_integer (signed (Tset)); -- package numeric_std
TactINT <= to_integer (signed (Tact)); -- instead of conv_integer
ONOFF := '0'; -- AT ISSUE -- so variable does not hang on start
wait until CLK'event and CLK = '1';
if TactINT <= TsetINT - 2 then -- operator precedence needs no parens
ONOFF := '1';
elsif TactINT >= TsetINT + 2 then
ONOFF := '0';
end if;
Heaton <= ONOFF;
end process;
end architecture behavioral; 您的流程中有一条注释,询问为什么需要conv_integer而不是to_integer。这促使了这一变化。
我删除了基于操作符顺序优先级的多余括号(添加比关系操作符更高的操作符),请注意Jim的答案也是如此。
因此,简单模型热模型在时钟设置为1秒的情况下运行,并具有两个系数,这两个系数与Heaton为'1‘或不为’1‘时的温度升高有关。我任意地将升温系数设置为每4个时钟1,将温度衰减系数设置为每10个时钟1。同时将环境温度(tout)设置为10,将tset设置为22。选择的数字是严格的,以保持模型运行时间短,增强可移植性,而不依赖于设置模拟器分辨率限制。
热模型是使用固定符号算法实现的,不使用fixed_generic_pkg,允许移植到-1993工具,没有数学软件包,并包括一个小数部分,负责达到正常工作温度后的不同宽度的热真。该模型可以很容易地用两个不同的前兆计数器来实现,用于告诉何时增加或减少Tact。
使用实数类型是可能的,但并不可取,因为将实数转换为整数(然后转换为带符号的)是不可移植的(IEEE Std 1076-2008附录D)。
这里的想法是为了证明滞后的缺乏,并证明模型没有达到Tset:

缺少命中Tset (22 + 2)是基于缺少滞后。滞后是减少加热开和关周期的理想选择,这个想法是一旦你启动加热器,你就让它开着一段时间,一旦你停止它,你也想让它关一段时间。
使用Jim的修改:
-- signal TsetINT, TactINT: integer range 63 downto -64;开始
HEAT_ON_OFF:进程(CLK)开始
if rising_edge(CLK) then
if signed(Tact) <= signed(Tset) - 2 then
Heaton <= '1';
elsif signed(Tact) >= signed(Tset) + 2 then
Heaton <= '0';
end if;
end if;
end process;延长了加热器的开启和关闭周期,减少了加热器启动和停止的次数:

并且实际上允许我们看到达到Tset + 2和Tset -2的温度,其中这些阈值提供滞后,其特征是最小开启或最小关闭时间,这取决于加热器的效率和加热器关闭时的热损失率。
那么,在执行热模型过程中发生了什么变化呢?看看这两个版本的合成结果的差异。
https://stackoverflow.com/questions/34096607
复制相似问题