2014-09-19 2 views
0

J'écris un code VHDL pour contrôler AD7193 via la communication SPI. ADC est contrôlé et configuré par le biais du nombre de registres de puce, DOUT/RDY (SPI_miso) passe à l'état bas pour indiquer l'achèvement de la conversion. Ce sont les caractéristiques de code et de synchronisation (voir Here) de AD7193.Déclaration d'attente synthétisable en 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; 

Pour autant que je sais attendre UNTIL soutient pour la synthèse VHDL, mais j'ai reçu cette erreur: « Erreur (10441): VHDL erreur de traitement de processus Main ADC.vhd (53): Le processus Déclaration ne peut pas contenir à la fois une liste de sensibilité et une déclaration d'attente ". Comment puis-je résoudre cette erreur? Existe-t-il un autre moyen de conserver le compteur et d'attendre que l'événement DOUT/RDY sache quand la conversion est terminée pour lire les données? Toutes les opinions sont appréciées! Je vous remercie.

Répondre

2

Le message d'erreur est dû à une restriction sémantique du langage VHDL.

L'attente jusqu'à ce que vous utilisez implique spi_miso comme une horloge, et il semble que vous besoin d'une bascule pour basculer à la suite de i contre pour atteindre 33, avant de passer à 34.

L'erreur à propos de l'élément de liste de sensititvité (outclock) et la déclaration d'attente vous dit que vous ne pouvez pas utiliser deux horloges différentes dans ce processus.

S'il n'y a pas de problème de métastabilité avec outclk, au lieu d'attendre n'incrémenter i à moins spio_miso = 0 quand i = 33. Vous pouvez également évaluer i avant incrémenter (l'équivalent de faire i un signal).

Cela peut mériter une simulation avant la synthèse. Il y a peut-être d'autres problèmes qui s'y cachent.

Votre VHDL analyse avec quelques changements:

 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==> 

(Et je normalement ne mettre des parenthèses autour d'une expression si de déclaration.)

+0

Excellente idée! Merci David, je vais essayer de l'appliquer – lft