Отправка данных с FPGA на Raspberry Pi с использованием протокола SPI

#python #vhdl #spi

#python #vhdl #spi

Вопрос:

У меня есть FPGA, и я хочу записывать рабочие значения (обычно размером 4 байта) в FPGA, используя протоколы Raspberry pi и SPI, где подчиненным является FPGA. Rpi выводит ar_clk и ar_en (включить). FPGA выводит ar_dat(данные). Проблема в том, что я иногда немного пропускаю чтение. Мой приведенный ниже код VHDL должен выполнять следующее: когда вывод enable (ar_en) обнуляется или вывод ar_clk переходит в low, FPGA ожидает около 1024 отсчетов и помещает бит данных на вывод ar_dat. Затем у него есть время расслабиться перед восходящим фронтом ar_clk, где он считывается Rpi. Под кодом VHDL находится мой код Python. Код python должен читать ar_dat на переднем крае ar_clk. Длина моего кабеля между ними составляет около 1 м. Сигналы выглядят чистыми из o-области. Я использую красный, синий и оранжевый провода от кабеля RJ45 со всеми остальными 5 концами, подключенными к заземлению на Rpi (pin6) и связанными вместе с землей на пользовательском проводном разъеме RJ45 с 5 концами для заземления на моей плате FPGA. У меня есть плата Deo Nano Soc, подключенная к печатной плате. Пожалуйста, помогите мне найти, где / почему я пропускаю чтение битов.

  screen_shot : process(CLK)
      begin
            if rising_edge(CLK) then
                if ar_en = '1' then  -- (purple cable orange wire[24]) -- Initializes these 5 when high
                        ss_timer <= (others => '0'); -- 32 bit SLV
                        ss_value <= (others => '0'); -- 32 bit SLV 
                        ss_cntr  <= 1; -- 0 to 1023 integer
                        ss_word  <= 0; -- 0 to 1023 integer
                        ar_dat <= '0'; -- data bit to Raspberry Pi
                end if;
                            
            if ar_en = '0' then -- (purple cable orange wire[24]) The SDI data enable bit
                ss_timer <= ss_timer   1; -- 
                
                if ar_clk = '1' then --  10240 Hz from Raspberry Pi
                    ss_timer <= (others => '0');
                end if;
                
                if ar_clk = '0' then-- (purple cable green wire[23])
                    
                    if ss_timer = 1024 then  -- This is an abitrary time to make sure value is set and settled
                        ar_dat <= ss_value(31- ss_word);  -- Put bit before rising edge (purple cable blue wire[21])
                    end if;
                
                    if ss_timer = 1024   5 then
                        ss_word <= ss_word   1;
                    end if;
                    
                    if ss_word = 32 and ss_timer = 1024   10 then
                        ss_cntr <= ss_cntr   1;
                    end if;
                                
                    if ss_word = 32 and ss_timer = 1024   15 then
                        ss_word <= 0;
                    end if;
                end if; -- if ar_clk = '0'
                            
                case ss_cntr is
                    when 1 =>  ss_value <= "10101010101010101010101010101010";
                    when 2 =>  ss_value <= "10101010101010101010101010101010";
                    when 3 =>  ss_value <= "10101010101010101010101010101010";
                    when 4 =>  ss_value <= "10101010101010101010101010101010";
                    when 5 =>  ss_value <= "10101010101010101010101010101010";
                    when others => ss_value <= "11111110101010101010101010101010";
                end case;               
        
            end if; -- if ar_en = '0'
            
        end if; -- Rising Edge
        
  end process;
  

Код Python:

 import spidev
import time
spi = spidev.SpiDev()
print("start")
spi.open(0, 0)
spi.mode = 0b00
spi.max_speed_hz =10240
#print(val)
for j in range(0, 2):
    val = spi.readbytes(20)
    print(val)
spi.close()
  

Комментарии:

1. Вы видите недостающий бит на осциллографе? Учитываете ли вы все сроки? RasPi может считывать строку данных до того, как FPGA добавит в нее значение.

2. Сегодня я в настоящее время использую Signal Tap (виртуальную область ввода), и я вижу там недостающие биты. Это должно быть в моем коде VHDL. Пытаюсь найти его сейчас.

3. Вы это смоделировали?

4. Да, я провел симуляцию, и она сработала, когда я имитировал ввод данных. Я также записывал данные с помощью Saleae pro 8 и Signal Tap одновременно в режиме реального времени. Я вижу, что часы поступают через регулярные промежутки времени, и я вижу одни и те же неправильные данные на обоих. Неправильные данные кажутся случайными. Я не вижу отказов при использовании Saleae. В VHDL я изменил все счетчики в этом процессе на целочисленный формат. Я подумываю о том, чтобы отменить этот процесс VHDL и переписать его, но я хочу найти свою ошибку VHDL.

5. «все счетчики» я имел в виду ss_timer…