VHDL短格式,用于触发凸起边缘上的操作

VHDL短格式,用于触发凸起边缘上的操作,vhdl,fpga,Vhdl,Fpga,我想知道是否有一种较短的方法可以在非时钟的信号边缘触发 考虑以下示例: signal clock : std_logic; signal ready : std_logic; -- comes from some slow component signal last_ready : std_logic; signal some_rare_condition : std_logic; --------

我想知道是否有一种较短的方法可以在非时钟的信号边缘触发

考虑以下示例:

  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;
信号时钟:标准逻辑;
信号准备就绪:标准逻辑;——来自某个慢组件
信号最后就绪:标准逻辑;
信号某些条件:标准逻辑;
----------------------------------
进程(时钟)是
开始
如果上升沿(时钟),则
如果(某些罕见条件='1'),则
如果(ready='1')和(last_ready='0'),则
--在这里做一些事情,例如将数据写入UART。
如果结束;

last_ready您可以在两行中写入上升或下降沿检测:

  • 一个简单的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;
例如:

mySignal_d <= ffdre(q => mySignal_d, d => mySignal, en => myEnable) when rising_edge(Clock);
mySignal\u d mySignal\u d,d=>mySignal,en=>myEnable)上升沿(时钟)时;

我不知道有哪种可合成的语言结构能够完成您所寻找的内容,而不涉及明确声明寄存器和以某种方式自己进行边缘检查

人们可能会想尝试以下几点:

if rising_edge(clk) then
  if some_rare_condition = '1' then
    if rising_edge(ready) then
      ...
这(可能?)不仅不会合成,而且要通过
上升沿(就绪)
检查,事件必须完全同时发生(在sim卡中,一直到增量循环,这可能非常不方便)

或者可能:

if ready = '1' and ready'last_value = '0' and ready'last_event < CLK_PERIOD then

添加一些泛型以覆盖细微的变化。稍微多一些代码,但少一些信号,如果这就是你想要的。(edit:好吧,我想实际上并没有更少的信号,但至少它被整齐地包装起来了)

如果VHDL函数允许输入参数,您可以稍微减轻痛苦:

impure function first_time(ready : in std_logic; last : inout std_logic) 
   return boolean is
begin
   last <= ready;
   return ready = '1' and last = '0';
end first_time;
不纯函数第一次(就绪:标准逻辑中;最后:标准逻辑中)
返回布尔值为
开始

最后,这不应该是在代码审查中吗?我要求的是语言功能或库功能,而不是代码审查(顺便说一句,这是伪代码)。您可能需要添加一个时钟启用,以便您的代码更接近OP的情况。@fru1tbat我在答案中添加了触发器函数。现在,甚至可以在一行VHDL代码中构建像ffdre这样的复杂触发器。rising_edge版本不会合成(尽管可以想象,对于自定义类型,您可以使用自己的函数重载rising_edge)是的,我可能(!)应该省略“可能?”,但为错误留出额外空间是一种习惯。。。
ready_edge : edge_detect
  port map (
    clk  => clock,
    ena  => some_rare_condition,
    sig  => ready,
    edge => ready_edge
  );

process (clock)
begin
  if rising_edge(clock) then
    if ready_edge = '1' then
      ...
impure function first_time(ready : in std_logic; last : inout std_logic) 
   return boolean is
begin
   last <= ready;
   return ready = '1' and last = '0';
end first_time;
impure function first_ready return boolean is
begin
   last_ready <= ready;
   return ready = '1' and last_ready = '0';
end first_ready;

...
if first_ready then 
   do_something ...
end if;