У меня есть вопрос относительно моего кода в VHDL;Я хотел бы реализовать драйвер для АЦП (AD7476A) на моей плате Arty, а также 16-разрядный выходной вектор с меткой sDATA.
Я бы хотел, чтобы АЦП был настраиваемым (выберите, сколько мы хотиместь), поэтому я сделал пакет.
У меня проблема с моим кодом AD747_CTRL, который является десериализатором;Я хотел бы настроить свой регистр сдвига во временном регистре из 16 битов, но как я могу установить его в моих данных, который является регистром из 12 битов?
Кроме того, я хотел бы проверить свой код втестовый стенд, чтобы отправить данные (например, рампу) и увидеть последовательные данные на осциллограмме.Вы можете мне помочь?Большое спасибо.
AD747XA_pkg.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
package AD747X is
SUBTYPE ad747X_sample IS std_logic_vector( 11 downto 0 );
TYPE ad747X_sample_v IS ARRAY (natural range<>) OF ad747X_sample;
end package;
AD747XA.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity AD747XA is
Port (
serial_clk : in STD_LOGIC; --ADC serial clock
sdata : out STD_LOGIC;
cs_n : in STD_LOGIC
);
end AD747XA;
architecture Behavioral of AD747XA is
--Timing specifications
constant tsclk : time := 1 sec/20000000; --Fsclk -> 20 MHz
constant tconvert : time := 16*tsclk;
constant tquiet : time := 50 ns;
constant tpowerup : time := 1 us;
constant t1 : time := 10 ns;
constant t2 : time := 10 ns;
constant t3 : time := 22 ns;
constant t4 : time := 40 ns;
constant t5 : time := 0.4*tsclk;
constant t6 : time := 0.4*tsclk;
constant t7 : time := 9.5 ns; --To modify according to the value of VDD
constant t8 : time := 36 ns; --max value
--Signals declaration
signal data : STD_LOGIC_VECTOR(15 downto 0) := (others=>'0');
begin
process
begin
wait until falling_edge(cs_n);
wait for t2;
for i in 0 to 3 loop
wait until falling_edge(serial_clk);
wait for t4;
sdata <= data(i);
end loop;
for i in 3 to 15 loop
wait until falling_edge(serial_clk);
wait for t7;
sdata <= data(i);
end loop;
data <= STD_LOGIC_VECTOR(unsigned(data) + 1);
end process;
end Behavioral;
AD747XA_CTRL.vhd:
library IEEE;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_1164.ALL;
library WORK;
use WORK.AD747X.all;
entity AD747XA_CTRL is
generic (
chan_count : integer := 2
);
Port ( clk : in STD_LOGIC;
rstn : in STD_LOGIC;
serial_clk : in STD_LOGIC;
sdata : in ad747X_sample_v(chan_count-1 downto 0);
ready : out STD_LOGIC;
data : out ad747X_sample_v(chan_count-1 downto 0)
);
end AD747XA_CTRL;
architecture Behavioral of AD747XA_CTRL is
signal rx_counter : integer := 0 ;
signal reg : ad747X_sample_v (chan_count-1 downto 0);
type TYPE_STATE is (Idle,ShiftIn);
type temp is array (0 to chan_count-1) of std_logic_vector(15 downto 0);
signal temp_reg : temp;
signal CURRENT_STATE : TYPE_STATE := Idle;
signal i_enable_conv : std_logic := '0';
begin
process(clk,rstn)
begin
if (rstn = '0') then
for i in chan_count-1 downto 0 loop
reg(i) <= (others => '0');
end loop;
rx_counter <= 0;
i_enable_conv <='0';
CURRENT_STATE <= Idle;
elsif (clk = '1' and clk'event) then
case CURRENT_STATE is
when Idle =>
rx_counter <= 0;
if (i_enable_conv = '1' ) then
CURRENT_STATE <= ShiftIn;
end if;
when ShiftIn =>
i_enable_conv <= '0';
for i in chan_count-1 downto 0 loop
temp_reg(i) <= sdata(i) & temp_reg(i)(15 downto 1);
end loop;
rx_counter <= rx_counter + 1;
if (rx_counter = 15) then
CURRENT_STATE <= Idle;
rx_counter <= 0;
else
CURRENT_STATE <= ShiftIn;
rx_counter <= rx_counter + 1;
end if;
end case;
end if;
end process;
data <= reg;
end Behavioral;
tb_AD747XA.vhd:
entity tb_AD747XA is
end tb_AD747XA;
architecture Behavioral of tb_AD747XA is
constant chan_count : integer := 2 ;
COMPONENT AD747XA_CTRL is
generic (chan_count : integer := 2 );
Port (
clk : in STD_LOGIC;
rstn : in STD_LOGIC;
serial_clk : in STD_LOGIC;
enable : in STD_LOGIC;
data : in ad747X_sample_v(chan_count-1 downto 0);
sdata : out ad747X_sample_v(chan_count-1 downto 0)
);
end COMPONENT;
signal clk : STD_LOGIC := '1';
signal rstn : STD_LOGIC;
signal enable : std_logic := '0';
signal serial_clk : STD_LOGIC;
signal sdata : ad747X_sample_v(chan_count-1 downto 0);
signal data : ad747X_sample_v(chan_count-1 downto 0);
SIGNAL end_of_simu : STD_LOGIC := '0';
begin
--AD1.vhd
ad747X : AD747XA_CTRL
generic map(chan_count => 2)
Port map(
clk => clk,
rstn => rstn ,
enable => enable ,
serial_clk => serial_clk,
sdata => sdata ,
data => data
);
process
begin
enable <= '0';
wait for 150 ns;
enable <= '1';
wait;
end process;
process
begin
rstn <= '0';
wait for 100 ns;
rstn <= '1';
if enable = '0' then
wait until enable = '1';
end if;
data(0) <= "000000000000";
wait for 50 ns;
data(0) <= "000000000001";
wait for 50 ns;
data(0) <= "000000000010";
wait for 50 ns;
data(0) <= "000000000100";
wait for 50 ns;
data(0) <= "000000001000";
end_of_simu <= '1';
wait;
end process;
process
begin
IF end_of_simu /= '1' THEN
clk <= not clk;
wait for 5 ns;
ELSE
assert false report "end of test" severity note;
WAIT;
END IF;
end process;
end Behavioral;