VHDL简写形式,用于触发上升沿上的动作 [英] VHDL short form to trigger actions on raising edges
问题描述
我想知道是否有一种较短的方法来触发不是时钟的信号沿.
I wonder if there is a shorter way to trigger on signal edges that are not the clock.
请考虑以下示例:
signal clock : std_logic;
signal ready : std_logic; -- comes from some slow component
signal last_ready : std_logic;
signal some_rare_condition : std_logic;
----------------------------------
process (clock) is
begin
if rising_edge (clock) then
if (some_rare_condition = '1') then
if (ready = '1') and (last_ready = '0') then
-- do something here, writing data to UART for example.
end if;
last_ready <= ready;
end if;
end if;
end process;
如果信号就绪"有上升沿,我想在这里做些事情.仅当some_rare_condition为true时,才应评估上升沿.
Here I want to do something if the signal 'ready' got a raising edge. The raising edge should only be evaluated if some_rare_condition is true.
我目前只记得锁存器中就绪信号的最后状态,并自己构建边缘检测逻辑.
I currently just remember the last state of the ready signal in a latch and build the edge detection logic myself.
问题:是否有更短,更优雅的方法来做到这一点?
我做对的方式很好,但是我用所有这些last_ready信号填充了我的代码.这似乎是一种常见的范例,我想我错过了一些语言或库构造来帮助我保持代码的简洁和精简.
The way I do it right works just fine, but I litter up my code with all these last_ready signals. This seem to be such a common paradigm that I think I miss some language or library construct that helps me to keep my code clean and lean.
推荐答案
您可以分两行编写上升沿或下降沿检测:
You can write a rising or falling edge detection in two lines:
- 用于注册旧信号的简单D-FF
- 上升沿比较
示例代码:
signal MMCM_Locked : STD_LOGIC;
signal MMCM_Locked_d : STD_LOGIC := '0';
signal MMCM_Locked_re : STD_LOGIC;
-- detect rising edge on CMB locked signals
MMCM_Locked_d <= MMCM_Locked when rising_edge(Control_Clock);
MMCM_Locked_re <= not MMCM_Locked_d and MMCM_Locked;
编辑1
当然,您还可以通过定义一些FF功能(此功能仍然是可合成的!)为此单线D-FF添加启用功能.
Edit 1
Of cause, you can also add an enable to this one-liner D-FF by defining some FF functions (this is still synthesizeable !).
-- d-flipflop with reset and enable
function ffdre(q : STD_LOGIC; d : STD_LOGIC; rst : STD_LOGIC := '0'; en : STD_LOGIC := '1') return STD_LOGIC is
begin
return ((d and en) or (q and not en)) and not rst;
end function;
function ffdre(q : STD_LOGIC_VECTOR; d : STD_LOGIC_VECTOR; rst : STD_LOGIC := '0'; en : STD_LOGIC := '1') return STD_LOGIC_VECTOR is
begin
return ((d and (q'range => en)) or (q and not (q'range => en))) and not (q'range => rst);
end function;
-- d-flipflop with set and enable
function ffdse(q : STD_LOGIC; d : STD_LOGIC; set : STD_LOGIC := '0'; en : STD_LOGIC := '1') return STD_LOGIC is
begin
return ((d and en) or (q and not en)) or set;
end function;
-- t-flipflop with reset and enable
function fftre(q : STD_LOGIC; rst : STD_LOGIC := '0'; en : STD_LOGIC := '1') return STD_LOGIC is
begin
return ((not q and en) or (q and not en)) and not rst;
end function;
-- rs-flipflop with dominant rst
function ffrs(q : STD_LOGIC; rst : STD_LOGIC := '0'; set : STD_LOGIC := '0') return STD_LOGIC is
begin
return (q or set) and not rst;
end function;
-- rs-flipflop with dominant set
function ffsr(q : STD_LOGIC; rst : STD_LOGIC := '0'; set : STD_LOGIC := '0') return STD_LOGIC is
begin
return (q and not rst) or set;
end function;
示例:
mySignal_d <= ffdre(q => mySignal_d, d => mySignal, en => myEnable) when rising_edge(Clock);
这篇关于VHDL简写形式,用于触发上升沿上的动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!