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

VHDL编译报Error(10818)无法推断寄存器错误问题咨询

VHDL编译报错10818问题解答

问题背景

用户对VHDL编程尚不熟练,代码单独编译无错,作为模块加入包含其他代码的块图后编译报错,本次为学校作业仅需完成仿真无需上板,需要明确问题原因以及仿真是否可以规避错误。

错误信息

Error (10818): Can't infer register for "Current_Number_32[0]" at Receiver.vhd(123) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[1]" at Receiver.vhd(123) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[2]" at Receiver.vhd(123) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[3]" at Receiver.vhd(123) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[4]" at Receiver.vhd(123) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[5]" at Receiver.vhd(123) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[6]" at Receiver.vhd(123) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[7]" at Receiver.vhd(123) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[8]" at Receiver.vhd(106) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[9]" at Receiver.vhd(106) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[10]" at Receiver.vhd(106) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[11]" at Receiver.vhd(106) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[12]" at Receiver.vhd(106) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[13]" at Receiver.vhd(106) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[14]" at Receiver.vhd(106) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[15]" at Receiver.vhd(106) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[16]" at Receiver.vhd(89) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[17]" at Receiver.vhd(89) because it does not hold its value outside the clock edge
Error (10818): Can't infer register for "Current_Number_32[18]" at Receiver.vhd(89) because it does not hold its value outside the clock edge

问题代码

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Receiver is
    Port ( SYS_CLK : in STD_LOGIC;
          RST : in STD_LOGIC;
          DATA_ACK : out STD_LOGIC;
             DATA_VALID : in STD_LOGIC;
             DATA_BUS_8 : in STD_LOGIC_VECTOR (7 downto 0);
             DIGIT_1 : out STD_LOGIC_VECTOR (6 downto 0);
             DIGIT_2 : out STD_LOGIC_VECTOR (6 downto 0);
             DIGIT_3 : out STD_LOGIC_VECTOR (6 downto 0);
             DIGIT_4 : out STD_LOGIC_VECTOR (6 downto 0);
             DIGIT_5 : out STD_LOGIC_VECTOR (6 downto 0);
             DIGIT_6 : out STD_LOGIC_VECTOR (6 downto 0);
             DIGIT_7 : out STD_LOGIC_VECTOR (6 downto 0);
             DIGIT_8 : out STD_LOGIC_VECTOR (6 downto 0));
end Receiver;

architecture Behavioral of Receiver is
    signal Current_Number_32 : STD_LOGIC_VECTOR (31 downto 0) := (others => '0');
    
    function BitsToDisplay (Bits : STD_LOGIC_VECTOR (3 downto 0) := (others => '0')) return STD_LOGIC_VECTOR is
        variable DisplayBits : STD_LOGIC_VECTOR (6 downto 0);
    begin
        case Bits is
            when "0000" => DisplayBits :=   "1111110";
            when "0001" => DisplayBits :=   "0110000";
            when "0010" => DisplayBits :=   "1101110";
            when "0011" => DisplayBits :=   "1111001";
            when "0100" => DisplayBits :=   "0110011";
            when "0101" => DisplayBits :=   "1011011";
            when "0110" => DisplayBits :=   "1011111";
            when "0111" => DisplayBits :=   "1110000";
            when "1000" => DisplayBits :=   "1111111";
            when "1001" => DisplayBits :=   "1111101";
            when "1010" => DisplayBits :=   "1110111";
            when "1011" => DisplayBits :=   "0011111";
            when "1100" => DisplayBits :=   "1001111";
            when "1101" => DisplayBits :=   "0111101";
            when "1110" => DisplayBits :=   "1001111";
            when "1111" => DisplayBits :=   "1000111";
            when  others => DisplayBits := "0000001";
        end case;
        return DisplayBits;
    end function;
    
    
begin
    Communication : process (SYS_CLK,RST,DATA_ACK,DATA_VALID,DATA_BUS_8)
        variable Section_1 : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
        variable Section_2 : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
        variable Section_3 : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
        variable Section_4 : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
        variable Current_Section : STD_LOGIC_VECTOR (1 downto 0) := (others => '0');
        variable Stage : STD_LOGIC_VECTOR (1 downto 0) := (others => '0');
    begin
        if (RST = '1') then
            DATA_ACK <= '0';
            Current_Number_32 <= (others => '0');
            Section_1 := (others => '0');
            Section_2 := (others => '0');
            Section_3 := (others => '0');
            Section_4 := (others => '0');
            Current_Section := (others => '0');
            Stage := (others => '0');
        elsif rising_edge(SYS_CLK)  then
                if (Current_Section = "00") then
                    if (Stage = "00") and rising_edge(DATA_VALID) then
                        Section_1 := DATA_BUS_8;
                        Stage := "01";
                    end if;
                    
                    if (Stage = "01") and (DATA_ACK = '1') then
                        DATA_ACK <= '0';
                        Stage := "00";
                        Current_Section := "01";
                    end if;
                    
                    if (Stage = "01") and falling_edge(DATA_VALID) then
                        DATA_ACK <= '1';
                    end if;                 
                end if;
                
                if (Current_Section = "01") then
                    if (Stage = "00") and rising_edge(DATA_VALID) then
                        Section_2 := DATA_BUS_8;
                        Stage := "01";
                    end if;
                    
                    if (Stage = "01") and (DATA_ACK = '1') then
                        DATA_ACK <= '0';
                        Stage := "00";
                        Current_Section := "10";
                    end if;
                    
                    if (Stage = "01") and falling_edge(DATA_VALID) then
                        DATA_ACK <= '1';
                    end if;                 
                end if;
                
                if (Current_Section = "10") then
                    if (Stage = "00") and rising_edge(DATA_VALID) then
                        Section_3 := DATA_BUS_8;
                        Stage := "01";
                    end if;
                    
                    if (Stage = "01") and (DATA_ACK = '1') then
                        DATA_ACK <= '0';
                        Stage := "00";
                        Current_Section := "11";
                    end if;
                    
                    if (Stage = "01") and falling_edge(DATA_VALID) then
                        DATA_ACK <= '1';
                    end if;                 
                end if;
                
                if (Current_Section = "11") then
                    if (Stage = "00") and rising_edge(DATA_VALID) then
                        Section_4 := DATA_BUS_8;
                        Stage := "01";
                    end if;
                    
                    if (Stage = "01") and (DATA_ACK = '1') then
                        Current_Number_32(31 downto 24) <= Section_1;
                        Current_Number_32(23 downto 16) <= Section_2;
                        Current_Number_32(15 downto 8) <= Section_3;
                        Current_Number_32(7 downto 0) <= Section_4;
                        DATA_ACK <= '0';
                        Stage := "00";
                        Current_Section := "00";
                    end if;
                    
                    if (Stage = "01") and falling_edge(DATA_VALID) then
                        DATA_ACK <= '1';
                    end if;                 
                end if;             
        end if;
    end process Communication;
    
    Display : process (SYS_CLK,RST,DIGIT_1,DIGIT_2,DIGIT_3,DIGIT_4,DIGIT_5,DIGIT_6,DIGIT_7,DIGIT_8)
    begin
        if (RST = '1') then
            DIGIT_8 <= (others => '0');
            DIGIT_7 <= (others => '0');
            DIGIT_6 <= (others => '0');
            DIGIT_5 <= (others => '0');
            DIGIT_4 <= (others => '0');
            DIGIT_3 <= (others => '0');
            DIGIT_2 <= (others => '0');
            DIGIT_1 <= (others => '0');
        else
            DIGIT_8 <= BitsToDisplay(Current_Number_32(3 downto 0));
            DIGIT_7 <= BitsToDisplay(Current_Number_32(7 downto 4));
            DIGIT_6 <= BitsToDisplay(Current_Number_32(11 downto 8));
            DIGIT_5 <= BitsToDisplay(Current_Number_32(15 downto 12));
            DIGIT_4 <= BitsToDisplay(Current_Number_32(19 downto 16));
            DIGIT_3 <= BitsToDisplay(Current_Number_32(23 downto 20));
            DIGIT_2 <= BitsToDisplay(Current_Number_32(27 downto 24));
            DIGIT_1 <= BitsToDisplay(Current_Number_32(31 downto 28));
        end if; 
    end process Display;
    
end Behavioral;

问题原因

报错核心是综合器无法为Current_Number_32推断出合法的寄存器,触发原因有三点:

  1. 同步进程敏感列表错误:Communication是时钟同步进程,敏感列表只应该包含时钟SYS_CLK和复位RST,额外加入的DATA_ACK、DATA_VALID等信号会导致进程异步触发,寄存器无法保证在时钟边沿外保持数值。
  2. 单进程多边沿检测:在SYS_CLK的上升沿判断分支内,又写了rising_edge(DATA_VALID)和falling_edge(DATA_VALID)的边沿检测,相当于要求寄存器响应两个独立的时钟边沿,实际硬件不存在这类结构,综合器无法实现。
  3. Display进程敏感列表错误:Display进程是组合逻辑输出七段数码管值,敏感列表错误加入了输出端口DIGIT_x,缺少输入数据源Current_Number_32,也会导致逻辑推断异常。

仿真规避可行性

  • 如果仅做行为级仿真,不需要经过综合步骤,只要代码逻辑自洽就可以运行,可临时绕过该报错。
  • 如果需要做综合后仿真、时序仿真,必须修正代码,否则综合步骤无法通过,无法生成仿真所需的网表文件。

快速修复建议

要彻底解决问题可做如下修改:

  • 把Communication进程的敏感列表改成仅包含SYS_CLK, RST
  • 新增DATA_VALID打拍寄存器,用同步逻辑检测边沿,代替直接在进程内写rising_edge(DATA_VALID)
  • 把Display进程的敏感列表改成RST, Current_Number_32,不需要加入时钟和输出端口

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 22:24:03