2014-09-19 224 views
0

我在寫一個VHDL代碼來通過SPI通信控制AD7193。 ADC通過多個片內寄存器進行控制和配置,DOUT/RDY(SPI_miso)變爲低電平表示轉換完成。這些是AD7193的代碼和時序特性(請參閱Here)。VHDL中的可綜合等待語句

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 
use ieee.numeric_std.all; 

entity MainADC is port (
     clk  : in std_logic;      -- OSC 50MHz 
     rst  : in std_logic;      -- Reset clock 
     sclk : out std_logic;      -- out clock 
     cs  : out std_logic;      -- Chip select 
     spi_mosi: out std_logic;      -- Write register 
     start : in std_logic;      -- Start Conversion 
     spi_miso: in std_logic);      -- Read register/Single channel, 24 bits 
end MainADC; 

architecture Behavior of MainADC is 


    signal outclk : std_logic; 
    signal clk_sel : std_logic; -- Clock Control 
    signal CommMode: std_logic_vector(7 downto 0) :="00001000"; -- Communications register==> next stage: Mode Register 
    signal Mode : std_logic_vector(23 downto 0) := "001010000000000001100000"; -- Single conversion mode  
    signal CommRead: std_logic_vector(7 downto 0) := "01011000"; -- Communications register==> next stage: Read Data 

begin 
    cs <= '0'; -- Hardwired low 

    process(clk, rst) -- Clock_gen 500KHz 
    variable cnt : integer range 0 to 500 :=1; 
     begin 
      if (rst='1') then 
       cnt := 0; 
       outclk <= '0'; 
      elsif (clk = '1' and clk'event) then 
       cnt := cnt + 1; 
       if (cnt = 50) then 
        cnt := 0; 
        outclk <= not outclk; 
       end if; 
      end if;  
    end process; 

    process(clk_sel) 
    begin 
     if (clk_sel='0') then 
      sclk <= '1'; --Clock Idle High 
     else 
      sclk <= outclk; --Provide Clock Cycles 
     end if; 
    end process;  


    process (outclk) -- SPI Comm 

    variable i  : integer :=0; 
    variable data_temp: std_logic_vector(23 downto 0) :=(others=>'0'); 

    begin 

     if (start = '0') then 
      clk_sel <= '0'; 
      i:=0; 
     else 

      if falling_edge(outclk) then     
      i:=i+1; 

       if (i>=0 and i<=7) then -- Communications register==> next stage: Mode Register (8 bits) 
        clk_sel <= '1'; 
        CommMode(7 downto 1) <= CommMode(6 downto 0); 
        CommMode(0)   <= CommMode(7); 
        spi_mosi    <= CommMode(7); 

       elsif (i=8) then 
        clk_sel <= '0'; --Clock Idle High 

       elsif (i>=9 and i<=32) then -- Single conversion mode (24 bits) 
        clk_sel <= '1'; 
        Mode(23 downto 1) <= Mode(22 downto 0); 
        Mode(0)   <= Mode(23); 
        spi_mosi   <= Mode(23); 

       elsif (i=33) then 
        clk_sel <= '0'; --Clock Idle High 
        wait until (spi_miso'event and spi_miso='0'); --Wait for Ready Read Signal (DOUT/DRY) 

       elsif (i>=34 and i<= 41) then -- Communications register==> next stage: Read Data 
        clk_sel <= '1'; 
        CommRead(7 downto 1) <= CommRead(6 downto 0); 
        CommRead(0)   <= CommRead(7); 
        spi_mosi    <= CommRead(7); 

       elsif (i=42) then 
        clk_sel <= '0'; --Clock Idle High      

       elsif (i>=43 and i<= 66) then 
        clk_sel <= '1'; 
        data_temp(23 downto 0) := data_temp(22 downto 0) & spi_miso; --Read Data 


       elsif (i>=66 and i<=566) then -- Waiting for ADC Power Up after Conversion (~1ms) 
        clk_sel <= '0'; --Clock Idle High 

       elsif (i=567) then 
       i:=0; 

       end if;  
      end if; 
     end if;             
    end process;  

end Behavior; 

據我所知等到聲明支持VHDL綜合,但我收到此錯誤:「錯誤(10441):在主ADC.vhd VHDL程序語句錯誤(53):過程聲明不能同時包含敏感列表和等待聲明「。我怎樣才能解決這個錯誤?是否有任何其他方式來保持計數器並等待DOUT/RDY事件來知道何時轉換完成讀取數據?任何意見都表示讚賞!謝謝。

回答

2

錯誤消息是由於VHDL語言語義限制。

等待,直到你使用SPI_MISO作爲時鐘,它看起來像你需要一個觸發器來切換爲i計數器達到33的結果,發展到34

錯誤之前暗示關於sensititvity列表項(outclock)和wait語句告訴你在這個過程中你不能使用兩個不同的時鐘。

如果沒有亞穩態問題與outclk,而不是等待不增加i除非spio_miso = 0當i = 33你也增加它(使i信號的等價物)之前評估i

這可能需要在合成之前進行模擬。那裏可能存在其他問題。

你的VHDL與一對夫婦的變化的分析:

 if falling_edge(outclk) then 

      if (i /= 33 or spi_miso = '0') then 
       i:= i + 1; 
      end if; 

      if (i>=0 and i<=7) then -- Communications register==> next stage: Mode Register (8 bits) 
       clk_sel <= '1'; 
       CommMode(7 downto 1) <= CommMode(6 downto 0); 
       CommMode(0)   <= CommMode(7); 
       spi_mosi    <= CommMode(7); 

      elsif (i=8) then 
       clk_sel <= '0'; --Clock Idle High 

      elsif (i>=9 and i<=32) then -- Single conversion mode (24 bits) 
       clk_sel <= '1'; 
       Mode(23 downto 1) <= Mode(22 downto 0); 
       Mode(0)   <= Mode(23); 
       spi_mosi   <= Mode(23); 

      -- elsif (i=33) then 
      --  clk_sel <= '0'; --Clock Idle High 
      --  wait until (spi_miso'event and spi_miso='0'); --Wait for Ready Read Signal (DOUT/DRY) 

      elsif (i>=34 and i<= 41) then -- Communications register==> 

(我通常不會把括號圍繞if語句表達。)

+0

好主意!謝謝大衛,我會嘗試應用它 – lft 2014-09-19 06:07:36