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推断出合法的寄存器,触发原因有三点:
- 同步进程敏感列表错误:
Communication是时钟同步进程,敏感列表只应该包含时钟SYS_CLK和复位RST,额外加入的DATA_ACK、DATA_VALID等信号会导致进程异步触发,寄存器无法保证在时钟边沿外保持数值。 - 单进程多边沿检测:在
SYS_CLK的上升沿判断分支内,又写了rising_edge(DATA_VALID)和falling_edge(DATA_VALID)的边沿检测,相当于要求寄存器响应两个独立的时钟边沿,实际硬件不存在这类结构,综合器无法实现。 - 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
相关产品推荐
相关产品推荐

