2012-07-03 111 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

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