我在大学课程中使用 VHDL 进行了一段时间的开发,我认为我了解它的工作原理,但有时我意识到我实际上并不了解它。
这是我的问题:
正如我所理解的,如果一个信号在进程的敏感列表中,那么只要该信号改变值,该进程就会“执行”。
所以我问,这2段代码有什么区别:
process(clk) is
begin
if(clk = '1') then
--Do Something
end if;
end process;
Run Code Online (Sandbox Code Playgroud)
和
process(clk) is
begin
if(rising_edge(clk)) then
--Do Something
end if;
end process;
Run Code Online (Sandbox Code Playgroud)
他们不应该表现得一样吗?
让我们看看 VHDL 信号值是如何在 VHDL 中定义的。您将在ieee.std_logic_1164库中找到这些定义。
通常,信号被声明为std_logic以下std_ulogic定义的解析子类型:
type STD_ULOGIC is ( 'U', -- Uninitialized
'X', -- Forcing Unknown
'0', -- Forcing 0
'1', -- Forcing 1
'Z', -- High Impedance
'W', -- Weak Unknown
'L', -- Weak 0
'H', -- Weak 1
'-' -- Don't care
);
Run Code Online (Sandbox Code Playgroud)
我们可以看到,这种信号除了通常的“0”和“1”之外,还可以有其他几个值。您的两个流程之间的区别就在这里。
现在让我们看看rising_edge函数是如何定义的,总是在 std_logic_1164 库中:
function rising_edge (signal s : STD_ULOGIC) return BOOLEAN is
begin
return (s'event and (To_X01(s) = '1') and
(To_X01(s'last_value) = '0'));
end function rising_edge;
function To_X01 (s : STD_ULOGIC) return X01 is
begin
return (cvt_to_x01(s));
end function To_X01;
----------------------------------------------------------
-- table name : cvt_to_x01
--
-- parameters :
-- in : std_ulogic -- some logic value
-- returns : x01 -- state value of logic value
-- purpose : to convert state-strength to state only
--
-- example : if (cvt_to_x01 (input_signal) = '1' ) then ...
--
----------------------------------------------------------
constant cvt_to_x01 : logic_x01_table := (
'X', -- 'U'
'X', -- 'X'
'0', -- '0'
'1', -- '1'
'X', -- 'Z'
'X', -- 'W'
'0', -- 'L'
'1', -- 'H'
'X' -- '-'
);
Run Code Online (Sandbox Code Playgroud)
该函数实际上将信号值转换为“X”或“0”或“1”。并且该函数仅在转换后的新值为“1”且转换后的最后值为“0”时才为真。
那么该rising_edge函数仅对以下几对 [last_value;value] 为真:
所有其他条件都无效。
[编辑以删除虚假信息]
正如@user1155120 在主要帖子评论中所解释的:
缺少信号分配,这两个过程都不会产生模拟事件。缺少分配目标,第一个在综合中不会产生电平敏感的时序逻辑(透明锁存器)。缺少分配目标,第二个在综合中不会产生边沿触发的时序逻辑(寄存器)。与 grorel 的 Quartus prime 不同,其他综合工具不能保证为他的输出生成寄存器1。请参阅 IEEE Std 1076.6-2004(已撤销)6.1.2.1 上升(正)沿时钟。,6.2.1.1 来自带有敏感列表的进程的电平敏感存储(需要敏感列表中的输入信号)。
output1 生成如下:
process(clk) is
begin
if(clk = '1') then
output1 <= input1;
end if;
end process;
Run Code Online (Sandbox Code Playgroud)
您必须在您的过程中使用边缘检测来确保寄存器创建良好。
| 归档时间: |
|
| 查看次数: |
1692 次 |
| 最近记录: |