реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> SPI подобный интерфейс, Проблемы с синтезом
kkosik
сообщение Oct 4 2012, 12:34
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445



Написал код, моделирование до синтеза производится отлично - все сигналы на месте!

После синтеза непонятно почему исчезают сигналы strob и data2!!
Чем это можно объяснить и как исправить, подскажите, пожалуйста...

Собственно код:
Код
LIBRARY ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

ENTITY spi_slave IS
  GENERIC(
    d_width : INTEGER := 12);     --data width in bits
  PORT
    (
        Clk         : IN    STD_LOGIC;-- := '0';
        Shift       : IN    STD_LOGIC;-- := '0';
        Mosi        : IN    STD_LOGIC;-- := '0';
    
        Data1       : out   std_logic_vector(d_width-1 downto 0);-- := (others => '0');
        Data2       : out   std_logic_vector(d_width-1 downto 0);-- := (others => '0');

        Strob       : out std_logic--:='0'
    );
END spi_slave;

ARCHITECTURE logic OF spi_slave IS
  signal buff    : STD_LOGIC_vector(d_width-1 downto 0) := (others => '0');
  --signal buff2    : STD_LOGIC_vector(d_width-1 downto 0) := (others => '0');

  signal buff_r0    : STD_LOGIC_vector(d_width-1 downto 0) := (others => '0');
  signal buff_r1    : STD_LOGIC_vector(d_width-1 downto 0) := (others => '0');
  signal bit_counter : std_logic_vector (d_width downto 0) := (others => '0');
  signal strob_counter : std_logic_vector (d_width downto 0) := (others => '0');
  
  signal ss : std_logic;
  signal clock : std_logic;
  signal stb : std_logic  := '0';

  signal strob_start : std_logic := '0';
  signal strob_stop : std_logic:= '0';

BEGIN
  
  ss <= Shift;
  clock <= Clk;

  process(ss,clock)
  begin
    if(rising_edge(ss)) then
        bit_counter <= (others => '0');
        strob_start <= '0';
        elsif(falling_edge(clock) and ss = '1') THEN
            IF(bit_counter = d_width) THEN
                case(buff(1)) is
                    when '0' => buff_r0 <= buff;
                    when '1' => buff_r1 <= buff;
                    when others => null;
                    end case;
                    strob_start <= '1';

                else
                    buff <= Mosi & buff(d_width-1 downto 1);
                    bit_counter <= bit_counter + 1;
            end if;

        end if;
    
    
    if(falling_edge(ss)) then
        strob_counter <= (others => '0');
        
        elsif(falling_edge(clock) and stb = '1') then
        if(strob_counter = 1) then
            strob_stop <= '1';
            else strob_counter <= strob_counter + 1;
        end if;
    end if;
    END PROCESS;

    Data1 <= buff_r0;
  Data2 <= buff_r1;

  stb <= strob_start and (not strob_stop);

  Strob <= stb;
END logic;


Tb:
Код
-- spi_TB.vhd

LIBRARY ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity testbench is
  GENERIC(
    d_width : INTEGER := 12);
end testbench;

architecture SPI_test of testbench is

    
    component spi_slave is
    port
    (
        Clk         : IN    STD_LOGIC;  --spi clk from master
        Shift          : IN    STD_LOGIC;  --active low slave select
        Mosi        : IN    STD_LOGIC;

        Data1        : out   std_logic_vector(d_width-1 downto 0) := (others => '0');
        Data2        : out   std_logic_vector(d_width-1 downto 0) := (others => '0');
        Strob       : out std_logic:='0'
    );
    end component;

     signal kod : std_logic_vector( 11 DOWNTO 0 ) := "101100010110";

    signal clock    : std_logic := '0';
    signal clk_in   : std_logic;
    signal data1_out : std_logic_vector( d_width-1 DOWNTO 0 );
    signal data2_out : std_logic_vector( d_width-1 DOWNTO 0 );
    signal start    : std_logic  := '0';
    signal stop    : std_logic  := '0';

    signal mosi_tb     : std_logic;

    signal counter : std_logic_vector( d_width DOWNTO 0 );-- := (others => '0');
    signal ss : std_logic;

    signal strb : std_logic  := '0';

begin
    start <= '1' after 110 ns;
    
    clk : PROCESS(clock)
    BEGIN
        IF clock = '1' THEN
              clock <= '0' after 25 ns;
          ELSIF true THEN
              clock <= '1' after 25 ns;
          END IF;
        clk_in <=  clock;
    END PROCESS;

    data : PROCESS(clk_in, start)
    BEGIN
        if(rising_edge(start)) then
            counter <= (others => '0');
        
        elsif(falling_edge(clk_in) and counter = d_width) then
            --counter <= (others => '0');
            stop <= '1';

            elsif(falling_edge(clk_in) and ss = '1') THEN
                mosi_tb <= kod(0);
                counter <= counter + 1;
                kod <= '0' & kod(d_width-1 downto 1);
        end if;
    END PROCESS;

    ss <= start and (not stop);
    
    spi_slave_0 : spi_slave
    port map
    (
        Clk => clk_in,
        Shift => ss,
        Mosi => mosi_tb,
        Data1 => data1_out,
        Data2 => data2_out,
        Strob => strb
    );
end SPI_test;
Go to the top of the page
 
+Quote Post
sazh
сообщение Oct 4 2012, 13:32
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



Цитата(kkosik @ Oct 4 2012, 15:34) *
После синтеза непонятно почему исчезают сигналы strob и data2!!
process(ss,clock)
begin
if(rising_edge(ss)) then
bit_counter <= (others => '0');
strob_start <= '0';
elsif(falling_edge(clock) and ss = '1') THEN
end SPI_test;


А у меня не синтезируется.
Error (10820): Netlist error at spi_slave.vhd(44): can't infer register for buff[0] because its behavior depends on the edges of multiple distinct clocks
В одном процессе работа по фронтам двух клоков.
В какой примитив это должно синтезироваться.
Go to the top of the page
 
+Quote Post
bogaev_roman
сообщение Oct 4 2012, 13:33
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082



Цитата(kkosik @ Oct 4 2012, 16:34) *
Написал код, моделирование до синтеза производится отлично - все сигналы на месте!
После синтеза непонятно почему исчезают сигналы strob и data2!!

У Вас strob и data2 (насколько я понял) комбинационные, синтезатор их убивает, надо смотреть buff_r1 и результат strob (как он его переиминует тоже можно посмотреть). И вообще Вы работаете по двум фронтам, т.е. во что это выльется вообще не понятно - в плисине таких триггеров нет, т.е. если это и будет синтезироваться, то в комбинационную схему, что не есть синхронный дизайн.
Go to the top of the page
 
+Quote Post
kkosik
сообщение Oct 4 2012, 13:47
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445



Ребят, сорри, не туда посмотрел - суть немного другая строба, он там нафиг не нужен, т.к. он входной, а не на выходе!!
Go to the top of the page
 
+Quote Post
Timmy
сообщение Oct 4 2012, 20:21
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



В соотвествии с принципами SPI сигнал slave select следует использовать, как асинхронный сброс приёмника по пассивному уровню ss(то есть когда приёмник не должен работать). Тогда получится избежать двухфронтовости в одном процессе, и синтезироваться нормально будет. Сбрасывать по ss только счётчик битов, а сдвиговый регистр сохранять.
Go to the top of the page
 
+Quote Post
kkosik
сообщение Oct 5 2012, 12:32
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445



Цитата
В соотвествии с принципами SPI сигнал slave select следует использовать, как асинхронный сброс приёмника по пассивному уровню ss(то есть когда приёмник не должен работать).

SPI тут не классический, поэтому по-другому немного. Переписал код, вроде бы всё синхронно сделал, но теперь после синтеза при моделировании не появляется выходной сигнал (строб есть). Хотя до синтеза всё в порядке...
Код
LIBRARY ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

ENTITY spi_slave IS
  GENERIC(
    d_width : INTEGER := 12);     --data width in bits
  PORT
    (
        Clk         : IN    STD_LOGIC;
        Shift       : IN    STD_LOGIC;
        Mosi        : IN    STD_LOGIC;
    
        Data1       : out   std_logic_vector(d_width-3 downto 0);
        Data2       : out   std_logic_vector(d_width-3 downto 0);

        Strob       : in std_logic
    );
END spi_slave;

ARCHITECTURE logic OF spi_slave IS
  signal buff    : STD_LOGIC_vector(d_width-1 downto 0) := (others => '0');
  signal mega_buff : STD_LOGIC_vector(d_width-1 downto 0);

  signal reg1    : STD_LOGIC_vector(d_width-3 downto 0);-- := (others => '0');
  signal reg2    : STD_LOGIC_vector(d_width-3 downto 0);-- := (others => '0');
  signal bit_counter : std_logic_vector (d_width-1 downto 0) := (others => '0');
  signal res : std_logic := '0';
  
BEGIN
    process(Shift,Clk)
    begin
        if(falling_edge(Clk) and Shift = '1') then
            if(bit_counter = d_width+1) then
                bit_counter <= (others => '0');
                else
                    buff <= Mosi & buff(d_width-1 downto 1);
                    bit_counter <= bit_counter + 1;
            end if;
        end if;
    end process;

    process(Strob, Clk)
    begin
            if(falling_edge(Clk) and Strob = '1') then
                case(buff(1)) is
                    when '0' => Data1 <= buff(d_width-1 downto 2);
                    when '1' => Data2 <= buff(d_width-1 downto 2);
                    when others => null;
                end case;
        end if;
    end process;
END logic;


TB:
Код
LIBRARY ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity testbench is
  GENERIC(
    d_width : INTEGER := 12);
end testbench;

architecture SPI_test of testbench is
    
    component spi_slave is
    port
    (
        Clk         : IN    STD_LOGIC;  --spi clk from master
        Shift          : IN    STD_LOGIC;  --active low slave select
        Mosi        : IN    STD_LOGIC;
        Strob       : in STD_LOGIC;
        Data1        : out   std_logic_vector(d_width-3 downto 0);
        Data2        : out   std_logic_vector(d_width-3 downto 0)
    );
    end component;

    signal kod : std_logic_vector( 11 DOWNTO 0 ) := "101100010110";

    signal clock    : std_logic := '0';
    signal clk_in   : std_logic;

    signal data1_out : std_logic_vector( d_width-3 DOWNTO 0 );
    signal data2_out : std_logic_vector( d_width-3 DOWNTO 0 );
    
    signal start    : std_logic  := '0';
    signal stop    : std_logic  := '0';

    signal start_strob    : std_logic  := '0';
    signal stop_strob     : std_logic  := '0';

    signal mosi_tb     : std_logic;

    signal counter : std_logic_vector( d_width-1 DOWNTO 0 ) :=(others => '0');
    signal strob_counter : std_logic_vector( d_width-1 DOWNTO 0 ) :=(others => '0');

    signal ss : std_logic := '0';
    signal stb : std_logic  := '0';

    begin
    start <= '1' after 110 ns;
    
    clk : PROCESS(clock)
    BEGIN
        IF clock = '1' THEN
              clock <= '0' after 25 ns;
          ELSIF true THEN
              clock <= '1' after 25 ns;
          END IF;
        clk_in <=  clock;
    END PROCESS;

    data : PROCESS(clk_in, start)
    BEGIN
        if(falling_edge(clk_in) and start = '1') then
            if(falling_edge(clk_in) and counter = d_width) then
                counter <= (others => '0');
                stop <= '1';
                start_strob <= '1';
                else
                    mosi_tb <= kod(0);
                    counter <= counter + 1;
                    kod <= '0' & kod(d_width-1 downto 1);
            end if;
        end if;
    END PROCESS;

    ss <= start and (not stop);
    stb <= start_strob and (not stop_strob);

    sb : process(stb, clk_in)
    begin
        if(falling_edge(clk_in) and stb = '1')then
            if(falling_edge(clk_in) and strob_counter = 2)then
                strob_counter <= (others => '0');
                stop_strob <= '1';
                else
                    strob_counter <= strob_counter + 1;
           end if;
        end if;
    end process;
    
    spi_slave_0 : spi_slave
    port map
    (
        Clk => clk_in,
        Shift => ss,
        Strob => stb,
        Mosi => mosi_tb,
        Data1 => data1_out,
        Data2 => data2_out

    );

end SPI_test;
Go to the top of the page
 
+Quote Post
bogaev_roman
сообщение Oct 5 2012, 13:08
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082



Цитата(kkosik @ Oct 5 2012, 16:32) *
Переписал код, вроде бы всё синхронно сделал, но теперь после синтеза при моделировании не появляется выходной сигнал (строб есть). Хотя до синтеза всё в порядке...

Что значит, не появляется? Его синтезатор убил, он не срабатывает или в состоянии X находится?
Go to the top of the page
 
+Quote Post
ISK
сообщение Oct 5 2012, 13:28
Сообщение #8


Участник
*

Группа: Свой
Сообщений: 59
Регистрация: 9-06-05
Из: Киев
Пользователь №: 5 857



Цитата(kkosik @ Oct 5 2012, 15:32) *
SPI тут не классический, поэтому по-другому немного. Переписал код, вроде бы всё синхронно сделал, но теперь после синтеза при моделировании не появляется выходной сигнал (строб есть). Хотя до синтеза всё в порядке...

Специально промоделировал.
Всё там у вас появляется. По крайней мере с выхода Data2 - "2с5". Data1 в "xx" потому что buff(1) равен '1' и для этого регистра не выполняется CASE.

А вообще странный код.
Go to the top of the page
 
+Quote Post
kkosik
сообщение Oct 5 2012, 13:38
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445



Цитата
Что значит, не появляется? Его синтезатор убил, он не срабатывает или в состоянии X находится?

В состоянии ХХХХХХ...

Цитата
Специально промоделировал. Всё там у вас появляется.

Моделировали после синтеза? или до? после синтеза описанная проблема появляется!

Цитата
А вообще странный код

В чем именно?
Go to the top of the page
 
+Quote Post
ISK
сообщение Oct 5 2012, 14:03
Сообщение #10


Участник
*

Группа: Свой
Сообщений: 59
Регистрация: 9-06-05
Из: Киев
Пользователь №: 5 857



Ну, скажем, bit_counter у вас объявлен как std_logic_vector, а потом сравнивается с d_width+1, который integer. И дальше есть строка где (bit_counter +1) .
И странно что компилятор не заругался. Хотя может это я от жизни отстал...
Go to the top of the page
 
+Quote Post
PetrovichKR
сообщение Oct 5 2012, 16:16
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 20-03-10
Пользователь №: 56 092



Цитата(ISK @ Oct 5 2012, 18:03) *
Ну, скажем, bit_counter у вас объявлен как std_logic_vector, а потом сравнивается с d_width+1, который integer. И дальше есть строка где (bit_counter +1) .
И странно что компилятор не заругался. Хотя может это я от жизни отстал...


Да ничего такого нет. Данные при синтезе преобразуются в нужный тип, и, соответственно, будут синтезироваться компаратор и инкремент. Тут наверняка подключены нужные для этого библиотеки. Я считаю, что использовать std_logic_vector здесь правильнее, поскольку можно явно задать разрядность счетчика, и сразу видно, какой сигнал описывает триггерные ячейки.
Go to the top of the page
 
+Quote Post
sazh
сообщение Oct 5 2012, 16:22
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



Цитата(PetrovichKR @ Oct 5 2012, 19:16) *
Я считаю, что использовать std_logic_vector здесь правильнее, поскольку можно явно задать разрядность счетчика, и сразу видно, какой сигнал описывает триггерные ячейки.


разрядность счетчика явно задается как clogb2 от параметра.
(Достаточно 4 разрядов)
Go to the top of the page
 
+Quote Post
kkosik
сообщение Oct 8 2012, 08:27
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445



Цитата
разрядность счетчика явно задается как clogb2 от параметра.

Круто, буду использовать!

А что по делу?
Go to the top of the page
 
+Quote Post
sazh
сообщение Oct 8 2012, 09:05
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



Цитата(kkosik @ Oct 8 2012, 11:27) *
А что по делу?


Найдите готовое описание здесь на форуме.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 14:35
Рейтинг@Mail.ru


Страница сгенерированна за 0.01497 секунд с 7
ELECTRONIX ©2004-2016