0
\$\begingroup\$

Behavioural SimulationI am trying to read the contents of register written in serial mode of WM8253 using SPI in Basys 3 FPGA. Link to Datasheet. I'm reading from register '011100' but the result that is read is always "111111111" irrespective of my inputs written in the register.[Register data "01010001" in my code] . The serial clock is set at frequency of 10MHz.

Here is my code:

entity WM8253_ADC is
  port
    (
      -- command input
      clock    : in  std_logic;         -- 100MHz onboard oscillator
      Dout     : out std_logic_vector(7 downto 0);  -- data from ADC
      -- ADC connection
      adc_sdo : in  std_logic;         -- ADC SPI MISO
      adc_sdi : out std_logic;         -- ADC SPI MOSI
      adc_sen : inout std_logic;         -- ADC SPI CHIP SELECT
      adc_sclk : out std_logic          -- ADC SPI CLOCK
      );

end WM8253_ADC;

architecture behavioural of WM8253_ADC is

  -- clock
  signal adc_clock,sen_clock,sen_clk : std_logic := '0';

  signal D   : std_logic_vector(7 downto 0) := (others => '0');

  signal spi_count : unsigned(4 downto 0)         := (others => '0');
  signal sen_count : unsigned(6 downto 0) := (others => '0');
  signal Q         : std_logic_vector(7 downto 0) := (others => '0');

  begin
    clock_divider : process(clock)
    variable cnt : integer := 0;
    begin
      if rising_edge(clock) then
        cnt := cnt + 1;
        if cnt = 5 then
          cnt := 0;
          adc_clock <= not adc_clock;
        end if;
      end if;
    end process;
    adc_sclk <= adc_clock;

 clock_divider_senclk_50Mhz : process(clock)
  variable cnt : integer := 0;
  begin
    if rising_edge(clock) then
      cnt := cnt + 1;
      if cnt = 1 then
        cnt := 0;
       sen_clock <= not sen_clock;
      end if;
    end if;
  end process;

  sen_clk <= sen_clock;
  shift_out : process( spi_count)
    begin
        case spi_count is
          when "00000" => adc_sdi <= '0';
          when "00001" => adc_sdi <= '1';
          when "00010" => adc_sdi <= '1';
          when "00011" => adc_sdi <= '1';
          when "00100" => adc_sdi <= '0';
          when "00101"  => adc_sdi <= '0';
          when "00110"  => adc_sdi <= '0';
          when "00111"  => adc_sdi <= '1';
          when "01000"  => adc_sdi <= '0';
          when "01001"  => adc_sdi <= '1';
          when "01010"  => adc_sdi <= '0';
          when "01011"  => adc_sdi <= '0';
          when "01100"  => adc_sdi <= '0';
          when "01101" => adc_sdi <= '1';
          when others => NULL;
        end case;
    end process;

   process(sen_count)
       begin
       case sen_count is   
       when "1000111" => adc_sen <= '1';
       when "1001000" => adc_sen <= '1';
       when "1001001" =>adc_sen <= '1';
       when others => adc_sen <= '0';
      end case;
      end process;

   process(sen_clock)
      begin
      if rising_edge(sen_clock) then 
      if sen_count = "1101111" then 
      sen_count <= "0000000";
      else 
      sen_count <= sen_count + 1;
      end if;
      end if;
      end process;

   adc_sm : process(adc_clock)
      begin
        if adc_clock'event and adc_clock = '1' then
        if spi_count = "010110" then
              spi_count <= (others => '0');
              else
              spi_count <= spi_count + 1;
          end if;
          end if;

      end process;

      -- Register sample into output
      outreg : process(adc_clock)
      begin      
      D   <= Q;
      end process;  

Dout   <= D;


      -- MISO shift register (rising edge)
      shift_in : process(adc_clock)
      begin
        if adc_clock'event and adc_clock = '0' then

            Q(0)          <= adc_sdo;
            Q(7 downto 1) <= Q(6 downto 0);
                  end if;

      end process;
   end behavioural;

I've tried to change the SPI Clock frequency with no progress. Any inputs will help.

\$\endgroup\$
  • 1
    \$\begingroup\$ Why are you writing/reading register 011100? I can not find this register in the register table of the datasheet. \$\endgroup\$ – jusaca Mar 11 at 10:28
  • \$\begingroup\$ Have you verified your signals with an oscilloscope? Have you written a testbench to verify that your code functions as you want? \$\endgroup\$ – Elliot Alderson Mar 11 at 11:45
  • \$\begingroup\$ @jusaca it seems bit 4 of the address field is not part of the register address, but instead indicates whether the operation is a read (1) or write (0). See figures 11 and 12 on the linked datasheet. \$\endgroup\$ – Kevin Kruse Mar 11 at 11:56
  • \$\begingroup\$ @jusaca As Kevin Kruse mentioned, The bit 4 is for writing to the register and after SEN is enabled, data has to be output on SDO pin. However I am not able to get an output except for "11111111". \$\endgroup\$ – Archana Narayanan Mar 13 at 5:59
  • \$\begingroup\$ @ElliotAlderson I checked the signals on oscilloscope and also tried a behavioural simulation on Vivado, forced a value on clock and SDI as 0 . I was able to verify the same on SDO. I have added a snapshot of simulation that I get. \$\endgroup\$ – Archana Narayanan Mar 13 at 6:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.