我正在编写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 回答
错误消息是由VHDL语言语义限制引起的 .
等待直到暗示你需要一个触发器来切换
i
计数器达到33,然后进入34 .关于敏感度列表项(outclock)和wait语句的错误告诉您在此过程中不能使用两个不同的时钟 .
如果
outclk
没有亚稳态问题,而不是等待不增加i
,除非当i = 33时spio_miso = 0.您还可以在递增之前评估i
(相当于使i
成为一个信号) .这可能在合成之前需要模拟 . 潜伏在那里的其他问题 .
您的VHDL分析有两处变化:
(我通常不会在if语句表达式周围添加括号 . )