1

I have a question concerning my code in VHDL; I would like to implement a driver for an ADC (AD7476A) on my Arty board as well as a 16-bit output vector labeled sDATA.

I would like the ADC to be configurable (choose how much we want to have), that's why I made a package.

I have a problem with my code AD747_CTRL which is a deserializer; I would like to set up my Shift register in a tempory register of 16 bits but how can I set it in my data out which is a register of 12 bits ?

Also, I would like to test my code in the testbench, to send a data ( a ramp for example) and see the serial data on the waveform. Can you help me? Thank you very much.

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;
Khadysr
  • 21
  • 1
  • 1
  • 6
  • See [ADC SPI protocol VHDL](https://stackoverflow.com/questions/49531288/adc-spi-protocol-vhdl) (deleted by Khadysr, 10K+ users). Note you're not using serial_clk (in AD747XA_CTRL) nor is it driven in tb_AD747XA for use in AD747XA (or AD747XA_CTRL). Your code collectively analyzes (adding a context clause to the testbench) but doesn't elaborate (the component AD747XA_CTRL not matching the entity declaration). Nowhere are you assigning `reg` nor taking into account a clock domain crossing. You can use two concatenated slice names to drop '0' MSBs. The rest of your question is too broad. –  Oct 09 '18 at 00:58
  • Thank you for you respond. I am really confused about the link you've sent me in Github and also how can I use serial clock and assign reg?? Sorry, I am a french student and it is really difficult for me to understand this concept... – Khadysr Oct 09 '18 at 16:02
  • "You can use two concatenated slice names to drop '0' MSBs. " What does that mean in VHDL ? – Khadysr Oct 09 '18 at 16:04
  • Hello, I really need help, it's really hard for me. @user1155120 – Khadysr Oct 11 '18 at 08:01

0 Answers0