我在项目中使用的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;
我只是在进行比较后才知道是否有更好的方法来做我已经做过的事情。
答案 0 :(得分:2)
为什么将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 ;
答案 1 :(得分:1)
为了回应Jim的评论,我写了一个简单的热模型测试台来测试你的设计。
我只是将您的设计更改为使用包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&#39;时的温度增加有关。或不。我每4个时钟任意设置加热系数为1,每10个时钟温度衰减系数为1。同时将环境温度(tout)设置为10,将tset设置为22.选择的数字非常严格,以保持模型运行时间短,增强便携性,而不依赖于设置模拟器分辨率限制。
热模型使用固定的有符号算法实现,不使用fixed_generic_pkg,允许在没有数学包的情况下移植到-1993工具,并包含一个小数部分,负责在达到正常工作温度后,Heaton的不同宽度。该模型可以很容易地用两个不同的前体计数器实现,用于判断何时增加或减少Tact。
使用REAL类型是可能的,这是不可取的,因为将REAL转换为INTEGER(然后转换为SIGNED)是不可移植的(IEEE Std 1076-2008 Annex 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;
给我们更长的Heaton开关循环,减少加热器启动和停止的次数:
实际上允许我们看到温度达到Tset + 2以及Tset-2。这些阈值提供滞后,其特征为最小开启或最小关闭时间,取决于加热器的效率和热量损失加热器关闭时的速率。
那么热模型过程的执行发生了什么变化?看看两个版本的综合结果的差异。