You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带数组插入的时钟化VHDL过程问题:FIFO仅读取一个数据即退出

问题根源

  1. 过程仅被调用一次:主进程只在单个时钟沿后执行一次read_uplink_FIFO,过程运行完毕直接退出,不会持续监听后续时钟沿来读取FIFO。
  2. 时钟沿逻辑错误:过程内的if rising_edge(clk)是即时条件判断,不是等待语句——只有调用过程的瞬间恰好是时钟上升沿时,才会执行内部操作,无法等待下一个时钟周期。
  3. 局部变量生命周期问题:过程内的rd_cnt是局部变量,每次调用过程都会被重新初始化为0,无法累计读取次数。

解决方案

方案1:用持续运行的进程替代过程(推荐)

测试平台中,独立进程是实现时序循环逻辑的首选,能持续响应时钟沿直到FIFO为空:

-- 把计数变量放在进程外部,保留状态
signal rd_cnt : integer := 0; 

process(clk)
begin
    if rising_edge(clk) then
        if fifo_empty_o = '0' then
            rd_ena_i <= '1';
            uplink_fifo_reg(rd_cnt) <= rd_data_o;
            rd_cnt <= rd_cnt + 1;
        else
            rd_ena_i <= '0';
            rd_cnt <= 0; -- FIFO空时重置计数
        end if;
    end if;
end process;

-- 主进程示例:FIFO写入完成后触发读取逻辑
process
begin
    -- 执行FIFO写入操作
    -- ... 写入逻辑代码 ...
    wait until fifo_write_done; -- 假设fifo_write_done是写入完成的标志信号
    -- 读取进程已在持续响应时钟,无需额外调用
    wait;
end process;

方案2:用包含循环等待的过程(仅作演示)

如果一定要用过程,需让过程内部循环等待每个时钟沿,同时将计数变量移到过程外部以保留状态:

-- 定义在过程外部,避免每次调用重置计数
variable rd_cnt : integer := 0; 

procedure read_uplink_FIFO is
begin
    rd_cnt := 0; -- 每次读取开始前重置计数
    loop
        wait until rising_edge(clk); -- 等待下一个时钟上升沿
        exit when fifo_empty_o = '1'; -- FIFO空时退出循环
        
        rd_ena_i <= '1';
        uplink_fifo_reg(rd_cnt) <= rd_data_o;
        rd_cnt := rd_cnt + 1;
    end loop;
    rd_ena_i <= '0'; -- 退出后拉低读使能
end procedure;

-- 主进程调用示例
process
begin
    -- FIFO写入完成后调用
    wait until rising_edge(clk);
    read_uplink_FIFO;
    wait;
end process;

注意事项

  • 测试平台中,进程优先于过程实现时序循环逻辑,过程更适合封装单次复用的组合逻辑,而非持续的时序操作。
  • 不要在过程中用rising_edge做条件判断,应使用wait until rising_edge(clk)等待时钟沿,确保过程能响应每个周期。
  • 局部变量仅在过程执行期间有效,若需保留状态,需将变量定义在过程外部(如进程内的信号/变量)。

内容的提问来源于stack exchange,提问作者Sander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 07:11:28