2012-07-03 78 views
1

我写了一个实现PWM控制器功能的VHDL代码。我已经成功模拟了它,结果如预期。我也检查了综合的语法,但是它显示了任何错误。当我使用XILINX ISE 12.4进行合成时,它不合成,错误状态为VHDL代码综合错误

“错误:Xst:827 - 第67行:信号tmp_PC无法合成,错误的同步描述。同步元素(寄存器,内存等)在当前的软件版本中不受支持。“

--library UNISIM; 
--use UNISIM.VComponents.all; 

entity CONTROLLER is 
PORT(

    CLK: IN STD_LOGIC; 
    VOUT: IN STD_LOGIC; 
    M1: OUT STD_LOGIC:='0'; 
    M2: OUT STD_LOGIC:='0' 

); 


end CONTROLLER; 

architecture Behavioral of CONTROLLER is 

    SIGNAL VREF:  STD_LOGIC_VECTOR(7 DOWNTO 0):="01000000"; 
    SIGNAL V_ERR:  STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL PWM:   STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL PWM_NEW:   STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL COUNT:  STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL COUNT2:   STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL TEMP1:  STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL TEMP2:  STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL TEMP3:  STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL FEED_BACK:  STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL REG:   STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000"; 
    SIGNAL PWM_COUNT:  STD_LOGIC_VECTOR(7 DOWNTO 0):="10000000"; 

BEGIN 

PROCESS(CLK) 

BEGIN 

    IF(RISING_EDGE(CLK) AND COUNT2<"10000000")THEN 
      COUNT <= COUNT+'1'; 
    END IF; 

    IF(RISING_EDGE(CLK) AND COUNT2>="10000000")THEN 
     COUNT <= COUNT+'1'; 
    END IF; 

    IF (COUNT>"00000101" AND COUNT<"01111000") THEN 
     IF(RISING_EDGE(CLK))THEN 
      IF (VOUT='0') THEN 
       FEED_BACK<= FEED_BACK+'1'; 
      END IF; 
     END IF; 
    END IF; 

    IF (COUNT>"01111000" AND COUNT<"01111100")THEN 
     REG<=FEED_BACK; 
     TEMP1<=VREF-REG; 
     IF(TEMP1>"01000000") THEN 
      TEMP2<=TEMP1+"11111111"; 
      V_ERR<=TEMP2+'1'; 
     END IF; 
     IF (TEMP1<"01000000") THEN 
       V_ERR<=TEMP1; 
     END IF; 

     PWM<=V_ERR+VREF; 

     IF (PWM>"11000000")THEN 
      PWM<="11000000"; 
     IF(PWM<"00001010")THEN 
      PWM<="00001010"; 

     END IF; 
     END IF; 

    END IF; 

    PWM_NEW<= PWM; 

    IF (RISING_EDGE(CLK))THEN 
     IF(COUNT="01111111")THEN 
      COUNT<="00000000"; 
      FEED_BACK<="00000000"; 
     END IF; 
    END IF; 

    IF(RISING_EDGE(CLK))THEN 
     COUNT2 <= COUNT2+ '1'; 
    END IF; 

    IF(COUNT>"00000000" AND COUNT<("00000010"))THEN 
     IF(RISING_EDGE(CLK)) THEN 
      M1<='0'; 
      M2<='0'; 
     END IF; 
    END IF; 

    IF(COUNT>("00000010") AND COUNT<("00000010"+PWM_NEW))THEN 
     IF(RISING_EDGE(CLK)) THEN 
      M1<='1'; 
      M2<='0'; 
     END IF; 
    END IF; 

    IF(COUNT>("00000010"+PWM_NEW) AND COUNT<("00000100"+PWM_NEW))THEN 
     IF (RISING_EDGE(CLK)) THEN 
      M1<='0'; 
      M2<='0'; 
     END IF; 
    END IF; 

    IF(COUNT>("00000100"+PWM_NEW) AND COUNT<("10000000"))THEN 
     IF (RISING_EDGE(CLK)) THEN 
      M1<='0'; 
      M2<='1'; 
     END IF; 
    END IF; 

    IF (COUNT=("10000000"))THEN 
     IF (RISING_EDGE(CLK)) THEN 
      COUNT2<="10000001"; 
     END IF; 
    END IF; 

END PROCESS; 
end Behavioral;` 

我试图查找错误消息,并得到不同的答案。可能的原因显示为 1:错误的“IF”嵌套不符合合成模板。 2:使用“risisng_edge(clk)”而不是通常的“(clk'event和clk ='1')”。

我仍然不完全确定什么可能是确切的问题。如果有人能够提出我忽略的可能错误,那将会非常有帮助。

回答

2

为了得到合成工具的认可,您的工艺必须具有一个单块if rising_edge(clk)块。

它应该很容易与reg <= feed_back;

如果这一特定款机型的异步行为来适应你的代码,除了数据块,然后将其移动到一个组合过程。

关于可能的原因1.和2.您列出了,您的代码在两方面都可以:嵌套是可以的(语法上)并且您的使用rising_edge是可以的。

+0

我就这一工作。感谢您指出了这一点。 –

0

的样子,你可以做你的代码完成SYNCHRON这些都

LIBRARY ieee; 
USE ieee.std_logic_1164.all; 
USE ieee.NUMERIC_STD.all; 

有标准化

process(clk) 
begin 
    -- put your asyncron code here if needed 
    if(rising_edge(clk)) then 
     if(reset = '1') then 
     -- if you like to implement a synchron reset 
     else 
     -- all your synchron code e.g. 

     if (COUNT2 >= "10000000") then 
      COUNT <= COUNT+'1'; 
     end if; 

     if (COUNT > ("00000100"+PWM_NEW)) AND (COUNT < "10000000") then 
      M1 <= '0'; 
      M2 <= '1'; 
     end if; 
     . 
     . 
     . 

     end if; 
    end if; 
    -- put your asyncron code here if needed 
end process; 

不使用新跃大学图书馆...你可以做的一切。

为了使它一点点清晰的您可以在十六进制写

if (COUNT2 >= x"80") then -- 80 hex = 124 dec 
    COUNT <= COUNT+'1'; 
end if; 

,或者你可以使用无符号的信号

SIGNAL COUNT:  unsigned (7 DOWNTO 0) := (others => '0'); -- same as "000000000" but looks better 

if (COUNT2 >= 128) then 
    COUNT <= COUNT + '1'; 
end if; 

计算不是如问题

if (COUNT > ("00000100"+PWM_NEW)) AND (COUNT < "10000000") then 
    M1 <= '0'; 
    M2 <= '1'; 
end if; 

if (COUNT > (unsigned(PWM_NEW) + 4)) AND (COUNT < 128) then 
    M1 <= '0'; 
    M2 <= '1'; 
end if; 
+0

谢谢。我明白你的意思。 –