我对VHDL中的代码有疑问;我想在Arty板上实现ADC(AD7476A)的驱动程序以及标有sDATA的16位输出矢量。
我希望ADC是可配置的(选择我们想要的数量),这就是为什么我制作了一个包装。
我的代码AD747_CTRL存在问题,它是反序列化器;我想在16位的临时寄存器中设置Shift寄存器,但是如何在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;