VHDL实现4阶转置型FIR滤波器前3时钟周期输出不定问题
VHDL实现4阶转置型FIR滤波器时序不定态问题修复
问题表现
- 第1个时钟周期拉高复位信号,预期将
adder_out数组初始化为全0 - 第2个时钟周期加载输入数据,因输入需写入寄存器,第3个时钟周期才完成输入锁存,此时乘法器输出对应输入与系数的乘积结果
- 异常点:第3个时钟周期触发加法器更新时,
adder_out变为不定态,导致前3个时钟周期无有效输出,3个时钟周期后输出结果才恢复正确
根因定位
- 复位逻辑写法错误
原代码中加法器进程的复位是异步复位,但复位判断没有放在时钟沿触发分支内:
adder:process(clk) begin if(rst='1') then adder_out<=(others=>(others=>'0')); elsif(rising_edge(clk)) then for index1 in 0 to 2 loop adder_out(index1)<=((34 downto 28=>product(index1)(27)) & product(index1))+adder_out(index1+1); end loop; adder_out(3)<=(34 downto 28=>product(3)(27)) & product(3); end if; end process adder;
这种写法下,只要rst为高就会直接给adder_out赋值,不受时钟控制。如果rst释放的时机不满足寄存器的建立保持时间要求,就会触发亚稳态,仿真中表现为不定态向后传递。
2. 乘法器为纯组合逻辑,无输出寄存器
原代码中乘法器直接用in1*in2组合逻辑实现,输出没有打拍寄存器。输入寄存器input_data更新时的跳变、毛刺会直接传递到乘法结果端,加法器在时钟沿采样到不稳定的乘积值时,就会把不定态写入加法器寄存器链。
3. 冗余信号未赋值
端口信号bpf_ready在代码中全程没有驱动,仿真时默认是不定态,容易干扰对模块工作状态的判断。
修复方案
- 统一使用同步复位逻辑:所有寄存器的赋值操作全部放在
rising_edge(clk)的判断分支内,避免复位释放带来的时序违例 - 给乘法器输出增加一级寄存器打拍,阻断组合逻辑毛刺向加法链传递,匹配转置FIR的流水线时序
- 补全
bpf_ready信号逻辑,对齐流水线输出延迟,正确指示输出有效状态
修正后的核心时序逻辑代码如下:
-- 新增乘法结果打拍寄存器 signal product_reg : product_array; pipeline_proc: process(clk) begin if rising_edge(clk) then -- 同步复位所有寄存器 if rst = '1' then input_data <= (others => '0'); product_reg <= (others => (others => '0')); adder_out <= (others => (others => '0')); bpf_ready <= '0'; else -- 输入锁存 if bpf_enable = '1' then input_data <= bpf_input; end if; -- 乘法结果打拍,隔离组合逻辑毛刺 for idx in 0 to 3 loop product_reg(idx) <= product(idx); end loop; -- 转置结构加法链 adder_out(3) <= (34 downto 28 => product_reg(3)(27)) & product_reg(3); for idx in 0 to 2 loop adder_out(idx) <= ((34 downto 28 => product_reg(idx)(27)) & product_reg(idx)) + adder_out(idx+1); end loop; -- 输出有效信号对齐流水线延迟 bpf_ready <= bpf_enable; end if; end if; end process pipeline_proc; bpf_output <= adder_out(0)(29 downto 15);
注意事项
- 4阶转置FIR本身存在固定的流水线延迟,前几个周期无有效输出是结构特性,属于正常现象,修复后不定态会完全消除
- 代码中不要同时引用
ieee.std_logic_signed和ieee.numeric_std库,容易出现类型转换冲突,统一使用ieee.numeric_std库下的signed类型做算术运算更稳妥
内容的提问来源于stack exchange,提问作者Aami
相关产品推荐
相关产品推荐

