VHDL时钟生成器进程未检测到时钟上升沿,计数器始终为0求助
时钟生成模块上升沿检测异常排查
问题现象
实现的时钟生成模块无法正常工作:由Clocking Wizard IP生成的mclk_i(22.579MHz)上升沿未被进程检测到,导致bclk_couter和lrclk_couter始终保持为0,无法生成预期的bclk(MCLK/8)和lrclk(MCLK/64)信号。仿真波形如下:
核心问题分析
查看代码后发现致命错误:
- 进程的敏感列表声明为
clk(100MHz输入时钟),但进程内部判断的是mclk_i的上升沿。 - 在VHDL中,进程仅会在敏感列表中的信号发生跳变时触发执行。这意味着只有当100MHz的
clk跳变时,进程才会检查mclk_i是否处于上升沿——两个时钟不同步,大概率会错过mclk_i的上升沿触发时机,导致计数器完全无法递增。
修复方案
1. 修正进程敏感列表
将进程的敏感列表改为mclk_i,确保进程在mclk_i的每个跳变沿都能触发执行,正确检测上升沿:
process(mclk_i) is begin if rising_edge(mclk_i) then -- 计数器逻辑 end if; end process;
2. 优化计数器与时钟生成逻辑
原代码的计数器逻辑存在冗余,且未对输出时钟做初始赋值,可能导致未知态。优化后的逻辑更简洁可靠:
architecture Behavioral of clk_generator is component clk_wiz_0 port ( mclk : out std_logic; clk_in1 : in std_logic; reset : in std_logic := '0' ); end component; signal mclk_i : std_logic; signal bclk_couter: integer range 0 to 7 := 0; -- 限定范围,减少资源占用 signal lrclk_couter : integer range 0 to 7 := 0; signal bclk_i : std_logic := '0'; -- 初始化为0,避免未知态 signal lrclk_i : std_logic := '0'; begin clk_gen : clk_wiz_0 port map( clk_in1 => clk, mclk => mclk_i ); mclk_o <= mclk_i; bclk <= bclk_i; lrclk <= lrclk_i; process(mclk_i) is begin if rising_edge(mclk_i) then bclk_couter <= bclk_couter + 1; if bclk_couter = 7 then bclk_couter <= 0; bclk_i <= not bclk_i; -- 每8个MCLK周期翻转,生成MCLK/8的bclk lrclk_couter <= lrclk_couter + 1; if lrclk_couter = 7 then lrclk_couter <= 0; lrclk_i <= not lrclk_i; -- 每8个bclk周期翻转,生成MCLK/64的lrclk end if; end if; end if; end process; end Behavioral;
3. 辅助检查项
- 确认Clocking Wizard IP核的配置:确保输入时钟
clk(100MHz)正确映射,mclk输出频率设置为22.579MHz,复位信号配置正常。 - 仿真时添加
mclk_i的波形观测,确认IP核是否正常输出时钟信号。
内容的提问来源于stack exchange,提问作者Alvaro Suarez Menendez
相关产品推荐
相关产品推荐

