Перейти к содержанию
    

Влияние смежных цепей на работу схемы.

1 minute ago, Bad0512 said:

нарезал бы всё внутренним 400 МГц клоком и жил бы припеваючи. :))

это для тех кому старшие семерки  и ультрас достаются бесплатно) такие люди, спиай давно уже не используют. Оке, уточним задачу, берем чип класса спартан6/сыклон 5, самый медленный. SPI 90 МГц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 minutes ago, des00 said:

это для тех кому старшие семерки  и ультрас достаются бесплатно) такие люди, спиай давно уже не используют. Оке, уточним задачу, берем чип класса спартан6/сыклон 5, самый медленный. SPI 90 МГц.

Вот тут уже включаем голову и применяем системный подход. После беглого анализа понимаем что 90МГц SPI и дохленький чип ПЛИС как-то между собой не коррелируют. И решаем либо частоту SPI понизить, либо решить проблему сменой ПЛИС (дохленький цинк с аппаратной поддрежкой SPI в PS вполне прокатит, кстати).

P.S. А по поводу "не используют" скажу так. Эти люди иногда такое унылое говно используют, что становится страшно за будущее нашей оборонки. Из примеров - преобразователь электрика-оптика-электрика на скорости до 100 мегабит на цинке 7030. Как вам такое, Илон Маск?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, des00 said:

Оке, уточним задачу, берем чип класса спартан6/сыклон 5, самый медленный. SPI 90 МГц.

Вопрос не мне, но отвечу. Когда-то делал специфический SPI на 64MHz 16 бит. Тактовый сигнал и данные держал в двух регистрах. В момент передачи оба регистра синхронно выдвигал. Выходные регистры были упакованы в IO буфферы ПЛИС. За счёт всего этого удалось добиться полного отсутствия разницы фаз между клоком и данными и достаточно простым управлением тактового сигнала в период пачки. Минус в том, что внутренняя логика должна в этом случае работать на удвоенной частоте. Но думаю, что даже 100MHz SPI (200Mhz внутренней частоты) этот дизайн бы запросто потянул, при условии согласованности линии и возможности ведомого принять такой поток. Но это если делать на чистом HDL. Не знаю как на C5, но на спартане6 есть ODDR2 (выходной буфер DDR). Думаю, что тот же фокус с двумя регистрами можно провернуть и с ним, только в этом случае удвоенная внутренняя частота уже не будет нужна.

 

А топикстартеру рекомендую изучить неблокирующие присваивания, иначе этот ад не заработает никогда.

Изменено пользователем Inanity

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 minutes ago, Inanity said:

Вопрос не мне, но отвечу. Когда-то делал специфический SPI на 64MHz 16 бит. Тактовый сигнал и данные держал в двух регистрах. В момент передачи оба регистра синхронно выдвигал. Выходные регистры были упакованы в IO буфферы ПЛИС. За счёт всего этого удалось добиться полного отсутствия разницы фаз между клоком и данными и достаточно простым управлением тактового сигнала в период пачки. Минус в том, что внутренняя логика должна в этом случае работать на удвоенной частоте. Но думаю, что даже 100MHz SPI (200Mhz внутренней частоты) этот дизайн бы запросто потянул, при условии согласованности линии и возможности ведомого принять такой поток. Но это если делать на чистом HDL. Не знаю как на C5, но на спартане6 есть ODDR2 (выходной буфер DDR). Думаю, что тот же фокус с двумя регистрами можно провернуть и с ним, только в этом случае удвоенная внутренняя частота уже не будет нужна.

 

А топикстартеру рекомендую изучить неблокирующие присваивания, иначе этот ад не заработает никогда.

 

на передачу вообще на любой почти частоте можно сделать легко. Тут речь идёт за slave, то есть надо сделать приёмник, соответственно надо переложить всё на внутренний клок заведомо более быстрый (ну хотя бы в 3 раза быстрее) чтобы не потерять фронты.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 minutes ago, Bad0512 said:

на передачу вообще на любой почти частоте можно сделать легко. Тут речь идёт за slave, то есть надо сделать приёмник, соответственно надо переложить всё на внутренний клок заведомо более быстрый (ну хотя бы в 3 раза быстрее) чтобы не потерять фронты.

 

Какой-то странный подход. Это же не асинхронный интерфейс. Зачем тогда лишний провод на тактовый сигнал тратить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, Inanity said:

Какой-то странный подход. Это же не асинхронный интерфейс. Зачем тогда лишний провод на тактовый сигнал тратить?

Без перехода на внутренний клок получится унылое асинхронное говнище, которое будет нестабильно работать из-за дребезга и периодически залипать наглухо по причине того, что клок SCK присутствует только в момент передачи данных, а паузах может и вообще отсутствовать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, Bad0512 said:

Без перехода на внутренний клок получится унылое асинхронное говнище, которое будет нестабильно работать из-за дребезга и периодически залипать наглухо по причине того, что клок SCK присутствует только в момент передачи данных, а паузах может и вообще отсутствовать.

Переход на внутренний клок будет в любом случае, но приёмный каскад должен работать по клоку приходящему. Это какой-то непонятный огород, который вас не спасёт, т.к. кроме фронта приходящего тактового сигнала нет никаких других способов детектировать валидные данные на шине.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

23 hours ago, des00 said:

Оке, уточним задачу, берем чип класса спартан6/сыклон 5, самый медленный. SPI 90 МГц.

 

17 hours ago, Inanity said:

Но думаю, что даже 100MHz SPI (200Mhz внутренней частоты) этот дизайн бы запросто потянул,

У меня сейчас лежит проект на Спартан 6 с клоком 200MHz. В основном всё работает без проблем, если не загружать все ненужные блоки одновременно. И при определённой сноровке можно спокойно поднять детектирование входным буффером до 300MHz, а дальше уже логику на любой частоте прикрутить. Так что не вижу необходимости заводить клок от SPI  и тактировать им внутренние ФФ. Разве что выше 100MHz  что-то будет. А может я просто ленивый и мне лень констрейнить все сопли SPI

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 minutes ago, Inanity said:

Переход на внутренний клок будет в любом случае, но приёмный каскад должен работать по клоку приходящему. Это какой-то непонятный огород, который вас не спасёт, т.к. кроме фронта приходящего тактового сигнала нет никаких других способов детектировать валидные данные на шине.

Неизбежный дребезг как побеждать будете в этом случае?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Собственно решил проблему, как подсказал des00Cделал срабатывание по по фронту SS. 
 


module spi_slave (rstb,ss,sck,sdin,done,rdata, sdout);
input rstb;
input ss;
input sck;
input sdin; 
output reg done;
output reg [7:0] rdata;


output reg sdout;

reg [7:0] rreg;
reg [3:0] nb;          
reg [3:0] nf;

always @(posedge sck or negedge rstb or posedge ss)
begin
if (rstb == 0)
  begin                    

  done <= 0;
  nb   <= 0;
  nf    <= 0;
  sdout <= 0;
  end
else
	if (ss)                    
		begin
		nb   <= 0;
		done <= 0;
		nf <= 0;
		sdout <= 0;
		end
	else            
		begin 
		rreg ={rreg[6:0],sdin};
		nb <= nb + 1;            
		if(nb != 7) done <= 0;
		else                    
		  begin
		  rdata=rreg;
		  done <= 1;
		  nb   <= 0;
		  nf <= nf + 1;
		  if(nf == 7) 
			begin
			sdout <= 1;
			nf    <= 0;   
			end
		  end
		end

end
endmodule

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

49 minutes ago, Bad0512 said:

Неизбежный дребезг как побеждать будете в этом случае?

Для начала установить природу дребезга или глитча. В 90% уверен, что проблема в несогласованности линии, сигнал отражается от приёмника и гуляет по проводу, создавая внеочередные фронты, провалы, короче говоря глитчи. Решать эту проблему надо на схемотехническом уровне (согласование/экранирование и т.д.). Если все эти вопросы решены, но всё равно есть проблемы с приёмом данных ввиду внешних наводок и т.д. то проблему можно попробовать решить на уровне протокола, т.е. контрольные суммы, запрос-ответ и т.д. В худшем случае SPI как интерфейс может вам и не подойти совсем. Тогда нужен асинхронный протокол с нормальной преамбулой, ECC и т.д. Вы же, насколько я понимаю, предлагаете оверсемплингом восстанавливать клок, который поможет детектировать данные. Не могу сказать, что это не будет работать, но зачем тогда вообще применять не предназначенный для таких задач синхронный интерфейс? Стоит ли программировать навороченный гибрид SPI-приёмника и осциллографа, чтобы принять шумный SPI? Не знаю, возможно, когда другого выхода нет, то это оправданно, но во всех других ситуациях это не рационально.

Изменено пользователем Inanity

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, Cianid said:

Собственно решил проблему, как подсказал des00Cделал срабатывание по по фронту SS.

Что такое 《posedge sck or negedge rstb or posedge ss 》 ?

С точки зрения синтеза весьма любопытно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, Nieve сказал:

Что такое 《posedge sck or negedge rstb or posedge ss 》 ?

С точки зрения синтеза весьма любопытно.

А это заявка записаться в расстрельный список. Чтобы начальник знал кого и за что...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, Nieve said:

Что такое 《posedge sck or negedge rstb or posedge ss 》 ?

С точки зрения синтеза весьма любопытно.

простое описание слейва (vhdl):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

-- THE SPI SLAVE MODULE SUPPORT ONLY SPI MODE 0 (CPOL=0, CPHA=0)!!!

entity SPI_SLAVE is
    Port (
        CLK      : in  std_logic; -- system clock
        RST      : in  std_logic; -- high active synchronous reset
        -- SPI SLAVE INTERFACE
        SCLK     : in  std_logic;
        CS_N     : in  std_logic;
        MOSI     : in  std_logic;
        MISO     : out std_logic;
        -- USER INTERFACE
        READY    : out std_logic; -- when READY = 1, SPI slave is ready to accept input data
        DIN      : in  std_logic_vector(7 downto 0); -- input data for master
        DIN_VLD  : in  std_logic; -- when DIN_VLD = 1, input data are valid and can be accept
        DOUT     : out std_logic_vector(7 downto 0); -- output data from master
        DOUT_VLD : out std_logic  -- when DOUT_VLD = 1, output data are valid
    );
end SPI_SLAVE;

architecture RTL of SPI_SLAVE is

    signal spi_clk_reg        : std_logic;
    signal spi_clk_redge_en   : std_logic;
    signal spi_clk_fedge_en   : std_logic;
    signal load_data          : std_logic;
    signal data_shreg         : std_logic_vector(7 downto 0);
    signal bit_cnt            : unsigned(2 downto 0);
    signal last_bit_en        : std_logic;
    signal slave_ready        : std_logic;
    signal data_busy_reg      : std_logic;
    signal rx_data_vld        : std_logic;

begin

    load_data <= slave_ready and DIN_VLD;
    READY     <= slave_ready;
    DOUT      <= data_shreg;

    -- -------------------------------------------------------------------------
    --  SPI CLOCK REGISTER
    -- -------------------------------------------------------------------------

    spi_clk_reg_p : process (CLK)
    begin
        if (rising_edge(CLK)) then
            if (RST = '1') then
                spi_clk_reg <= '0';
            else
                spi_clk_reg <= SCLK;
            end if;
        end if;
    end process;

    -- -------------------------------------------------------------------------
    --  SPI CLOCK EDGES FLAGS
    -- -------------------------------------------------------------------------

    spi_clk_fedge_en <= not SCLK and spi_clk_reg;
    spi_clk_redge_en <= SCLK and not spi_clk_reg;

    -- -------------------------------------------------------------------------
    --  DATA BUSY REGISTER
    -- -------------------------------------------------------------------------

    data_busy_reg_p : process (CLK)
    begin
        if (rising_edge(CLK)) then
            if (RST = '1') then
                data_busy_reg <= '0';
            else
                if (DIN_VLD = '1' and CS_N = '1') then
                    data_busy_reg <= '1';
                elsif (rx_data_vld = '1') then
                    data_busy_reg <= '0';
                else
                    data_busy_reg <= data_busy_reg;
                end if;
            end if;
        end if;
    end process;

    slave_ready <= CS_N and not data_busy_reg;

    -- -------------------------------------------------------------------------
    --  MISO REGISTER
    -- -------------------------------------------------------------------------

    miso_p : process (CLK)
    begin
        if (rising_edge(CLK)) then
            if (load_data = '1') then
                MISO <= DIN(7);
            elsif (spi_clk_fedge_en = '1' and CS_N = '0') then
                MISO <= data_shreg(7);
            end if;
        end if;
    end process;

    -- -------------------------------------------------------------------------
    --  DATA SHIFT REGISTER
    -- -------------------------------------------------------------------------

    data_shreg_p : process (CLK)
    begin
        if (rising_edge(CLK)) then
            if (load_data = '1') then
                data_shreg <= DIN;
            elsif (spi_clk_redge_en = '1' and CS_N = '0') then
                data_shreg <= data_shreg(6 downto 0) & MOSI;
            end if;
        end if;
    end process;

    -- -------------------------------------------------------------------------
    --  DATA OUT VALID FLAG REGISTER
    -- -------------------------------------------------------------------------

    rx_data_vld <= spi_clk_fedge_en and last_bit_en;

    dout_vld_reg_p : process (CLK)
    begin
        if (rising_edge(CLK)) then
            if (RST = '1') then
                DOUT_VLD <= '0';
            else
                DOUT_VLD <= rx_data_vld;
            end if;
        end if;
    end process;

    -- -------------------------------------------------------------------------
    --  BIT COUNTER
    -- -------------------------------------------------------------------------

    bit_cnt_p : process (CLK)
    begin
        if (rising_edge(CLK)) then
            if (RST = '1') then
                bit_cnt <= (others => '0');
            elsif (spi_clk_fedge_en = '1' and CS_N = '0') then
                if (bit_cnt = "111") then
                    bit_cnt <= (others => '0');
                else
                    bit_cnt <= bit_cnt + 1;
                end if;
            end if;
        end if;
    end process;

    -- -------------------------------------------------------------------------
    --  LAST BIT FLAG REGISTER
    -- -------------------------------------------------------------------------

    last_bit_en_p : process (CLK)
    begin
        if (rising_edge(CLK)) then
            if (RST = '1') then
                last_bit_en <= '0';
            else
                if (bit_cnt = "111") then
                    last_bit_en <= '1';
                else
                    last_bit_en <= '0';
                end if;
            end if;
        end if;
    end process;

end RTL;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30 minutes ago, iosifk said:

А это заявка записаться в расстрельный список. Чтобы начальник знал кого и за что...

И обратите внимание, если что - можно сказать, что des00 подсказал ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...