Синтезируемый оператор ожидания в VHDL

Я пишу код VHDL для управления AD7193 через связь SPI. АЦП управляется и настраивается через количество регистров микросхемы, DOUT / RDY (SPI_miso) переходит в низкий уровень, указывая на завершение преобразования. Это код и временные характеристики (см. Здесь) AD7193.

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; 

Насколько мне известно, инструкция Wait until поддерживает синтез vhdl, но я получил эту ошибку: «Ошибка (10441): ошибка инструкции процесса VHDL в главном ADC.vhd (53): инструкция процесса не может содержать одновременно список чувствительности и инструкцию ожидания. ". Как я могу решить эту ошибку? Есть ли другой способ удерживать счетчик и ждать события DOUT / RDY, чтобы узнать, когда преобразование завершено для считанных данных? Любые мнения приветствуются! Спасибо.


person lft    schedule 19.09.2014    source источник


Ответы (1)


Сообщение об ошибке возникает из-за семантического ограничения языка VHDL.

Ожидание до подразумевает, что вы используете spi_miso в качестве часов, и похоже, что вам требуется триггер для переключения в результате того, что счетчик i достигает 33, прежде чем прогрессировать до 34.

Ошибка, связанная с элементом списка чувствительности (outclock) и оператором ожидания, сообщает вам, что вы не можете использовать два разных тактовых сигнала в этом процессе.

Если нет проблем с метастабильностью с 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.)

person Community    schedule 19.09.2014