vhdl错误827:信号<>无法合成

时间:2015-01-15 11:08:20

标签: signals vhdl

我知道之前曾问过这个问题,但我认为我的问题不同。 我正在尝试为UART接收器编写代码并得到错误827.我对VHDL很新,不知道我做错了什么。有人可以帮我解决一下吗?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;

entity RX_STATE_MACHINE is
    port(rxD,DataAck,resetN,Clk_D: in std_logic;
          Data: out std_logic_vector(7 downto 0);
            DataRdy,ParityErr,StopErr: out std_logic);
end RX_STATE_MACHINE;

architecture Behavioral of RX_STATE_MACHINE is
    type stateType is(st1,st2,st3,st4,st5,st6);
     signal NS,PS :stateType := st1;
     signal cnt : integer range 0 to 15 :=0;
    signal sample: integer range 0 to 15;
begin

--Process for memmory system with asynchronic resetN 
    process(Clk_D,resetN)
     begin
        if (resetN='0') then
           PS <= st1;
         elsif rising_edge(Clk_D) then 
           PS <= NS;
        end if;
     end process;

--process that generating 16 steps counter   
     process(Clk_D)
       begin
          if rising_edge(Clk_D) then
            cnt <= (cnt+1) mod(16);
          end if;
     end process;

  process(rxD,cnt,DataAck,resetN,PS)
    -- process(rxD,PS)
        variable a: integer range 0 to 7;
         variable dat: std_logic_vector(7 downto 0);

        begin

         sample <= (sample+1) mod(16);

         case PS is 

           when st1 =>
             if falling_edge(rxD) then
                NS <= st2;
              else
                 NS <= st1;--
              end if;

            when st2 => 
              if (rxD='0') then
                if (cnt=7) then
                  NS <= st3;
                    sample <= 0;
                 else
                    NS <= st2;
                end if;
              else
                 NS <= st1;
              end if;   

         when st3 =>
              if (a<8) then
             if (sample=15) then
                  dat(a):=rxD;
                   a:=a+1;
                end if;
                 NS <= st3;--
              else
                a:=0;
                NS <= st4;
              end if;
          -- Data <= (dat(0),dat(1),dat(2),dat(3),dat(4),dat(5),dat(6),dat(7));

             when st4 =>
               if (sample=15) then
                  if((dat(0) xor dat(1) xor dat(2) xor dat(3) xor dat(4) xor dat(5) xor dat(6) xor dat(7))=rxD) then
                      ParityErr <= '0';               
                    else
                      ParityErr <= '1';           
                    end if;
                    NS <= st5;
                else
                  NS <= st4;--
               end if;

             when st5 =>
               if (sample=15) then
                 if(rxD='1') then
                      StopErr <= '0';
                    else
                      StopErr <= '1';             
                    end if;
                    NS <= st6;
                else
                  NS <= st5;--
                end if;

             when st6 =>
               if rising_edge(DataAck) then
                  NS <= st1;
                else
                  NS <= st6;--
                end if;



         end case;


            end process;        



end Behavioral;

谢谢!

2 个答案:

答案 0 :(得分:1)

在可综合代码中,rising_edge只能用于推断寄存器,例如:

process (clk, rst) is
begin
    if rst = '1' then
        -- reset code
    elsif rising_edge(clk) then
        -- actual code
    end if;
end process;

您正在将一个控制信号(而不是一个时钟)作为参数传递给rising_edge函数,并在进程的case语句中使用rising_edge函数。那不会合成。

要解决此问题:您可以使用一个时钟延迟控制信号,以便您可以写:

if DataAck_d = '0' and DataAck = '1' then 

其他提示:

  • 在一个同步过程中编写所有代码。这样可以降低与组合过程相关的错误风险(如锁存器,不完整的敏感性列表)
  • 您正在使用ieee.numeric_std,这很好。您不需要ieee.std_logic_unsignedieee.std_logic_arith
  • 上一个流程的敏感度列表应包含sample,不应包含resetN

答案 1 :(得分:0)

如果您还没有这样做,我会阅读Xilinx的这篇文章: AR# 14047

您提供的代码属于导致此类错误的方案的第二个示例。

您希望从本文中删除的关键点是:

  

为了让XST推断同步元素,事件VHDL属性必须出现在最顶层的&#34; IF&#34;你的过程陈述。

rising_edge()falling_edge()功能都使用&#39;事件&#39;传入信号的属性。

如果Clk_D的固定频率比RxDDataAck的转换速度快(例如MHz与KHz),则在UART总线的情况下可能是真的,那么你可以考虑将这些输入同步到Clk_D。这将允许您使FSM同步,这(IMO)更容易理解和调试。

我已经创建了一个用于处理UART已恢复数据的同步FSM的示例:

process(clk_D, ResetN) 
begin
  if (resetN = '1') then
    state <= S_IDLE;
  elsif (rising_edge(clk_D)) then
    rxD_s_d <= rxD_s;

    case state is
      when S_IDLE =>
        cnt <= 0;
        bit_cnt <= 0;
        -- Wait for start bit.
        if (rxD_s = '0' and rxD_s_d = '1') then -- falling edge detect
          state <= S_WAIT8; 
        endif;
      when S_WAIT8 =>
        -- Wait 8 clock cycles after start bit detect
        -- to align count to center of bit.
        if (cnt = 8) then
          state <= S_WAIT16;
          cnt <= 0;
        else
          cnt <= cnt + 1;
        end if;
      when S_WAIT16 =>
        -- Wait 16 clock cycles to align data to center of 
        -- next bit.
        if (cnt = 16) then
          state <= S_CAPTURE;
          cnt <= 0;
        else
          cnt <= cnt + 1;
        end if;
      when S_CAPTURE =>
        -- Shift in Rx data;
        data <= data(6 downto 0) & rxD_s;
        if (bit_cnt = 7) then
          -- All 8 bits captured; we're done.
          -- Could do stop bit detection instead of going 
          -- back to idle.
          state <= S_IDLE;
        else
          bit_cnt <= bit_cnt + 1;
          state <= S_WAIT16;
        endif;
    end case;
  end if;
end process;  

此示例假定clk_D的运行速度比UART波特率快16倍。它使用计数器尝试将接收数据线的采样点居中(同步到clk_D),以避免在亚稳态(过渡边缘)捕获rxD_s。它也假定没有奇偶校验,可以很容易地添加。

此外,我还没有对此进行模拟,但建议您做一些更好的理解。