关于std_logic_vector(4 downto 0)变化检测的代码问题求助
问题分析与解决
核心问题:多驱动导致的'X'信号
你的LOAD信号存在多驱动冲突:
- 一处驱动来自复位进程内的
LOAD <= '0'; - 另一处驱动来自进程外的连续赋值语句
LOAD <= '1' when compare = "00000" else '1';。
在VHDL中,同一个std_logic信号被多个驱动源赋值时,会触发信号解析逻辑,冲突时就会出现仿真中的'X'值。同时你的连续赋值逻辑完全错误:不管compare结果是什么,LOAD都会输出'1',根本没实现检测CUR_GRP变化的功能。
修正方案
方案1:将所有逻辑整合到时钟进程中
把LOAD的赋值统一放到时钟进程内,同时复位时初始化寄存器grp,避免未知值传播:
LIBRARY IEEE; library work; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; Entity CHANGE_CUR_GRP is port( MCLK : in std_logic; RST_N : in std_logic; CUR_GRP : in std_logic_vector(4 downto 0); LOAD : out std_logic ); end entity; Architecture RTL of CHANGE_CUR_GRP is signal grp : std_logic_vector(4 downto 0); begin process(RST_N, MCLK) begin if(RST_N = '0') then LOAD <= '0'; grp <= (others => '0'); -- 复位时初始化寄存器 elsif(rising_edge(MCLK)) then grp <= CUR_GRP; -- 检测当前输入与上一拍值是否不同 if grp /= CUR_GRP then LOAD <= '1'; else LOAD <= '0'; end if; end if; end process; end Architecture;
方案2:使用连续赋值,移除进程内的LOAD赋值
复位时仅初始化grp,通过连续赋值实现变化检测:
LIBRARY IEEE; library work; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; Entity CHANGE_CUR_GRP is port( MCLK : in std_logic; RST_N : in std_logic; CUR_GRP : in std_logic_vector(4 downto 0); LOAD : out std_logic ); end entity; Architecture RTL of CHANGE_CUR_GRP is signal grp : std_logic_vector(4 downto 0); signal compare : std_logic_vector(4 downto 0); begin process(RST_N, MCLK) begin if(RST_N = '0') then grp <= (others => '0'); -- 复位初始化寄存器 elsif(rising_edge(MCLK)) then grp <= CUR_GRP; end if; end process; compare <= grp xor CUR_GRP; -- 当异或结果非全0时,说明输入有变化,输出LOAD=1 LOAD <= '1' when compare /= "00000" else '0'; end Architecture;
关键说明
- 复位时必须初始化
grp:否则复位后grp会是未知值('U'),异或后compare也会带未知值,导致LOAD出现不确定态。 - 同一信号只能有一个驱动源:要么在进程内赋值,要么用连续赋值,避免冲突。
内容的提问来源于stack exchange,提问作者mugen54
相关产品推荐
相关产品推荐

