首页 文章

VHDL中的可合成等待语句

提问于
浏览
0

我正在编写VHDL代码以通过SPI通信控制AD7193 . 通过多个片内寄存器控制和配置ADC,DOUT / RDY(SPI_miso)变为低电平表示转换完成 . 这些是AD7193的代码和时序特性(请参阅Here) .

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):主ADC.vhd(53)上的VHDL进程语句错误:进程语句不能同时包含敏感列表和等待语句” . 我该如何解决这个错误?有没有其他方法来保持计数器并等待DOUT / RDY事件知道读取数据的转换何时完成?任何意见表示赞赏!谢谢 .

1 回答

  • 2

    错误消息是由VHDL语言语义限制引起的 .

    等待直到暗示你需要一个触发器来切换 i 计数器达到33,然后进入34 .

    关于敏感度列表项(outclock)和wait语句的错误告诉您在此过程中不能使用两个不同的时钟 .

    如果 outclk 没有亚稳态问题,而不是等待不增加 i ,除非当i = 33时spio_miso = 0.您还可以在递增之前评估 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语句表达式周围添加括号 . )

相关问题