|
|
  |
SPI подобный интерфейс, Проблемы с синтезом |
|
|
|
Oct 4 2012, 12:34
|
Участник

Группа: Участник
Сообщений: 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;
|
|
|
|
|
Oct 4 2012, 13:32
|
Гуру
     
Группа: Свой
Сообщений: 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 В одном процессе работа по фронтам двух клоков. В какой примитив это должно синтезироваться.
|
|
|
|
|
Oct 4 2012, 13:47
|
Участник

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

|
Ребят, сорри, не туда посмотрел - суть немного другая строба, он там нафиг не нужен, т.к. он входной, а не на выходе!!
|
|
|
|
|
Oct 5 2012, 12:32
|
Участник

Группа: Участник
Сообщений: 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;
|
|
|
|
|
Oct 5 2012, 13:28
|
Участник

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

|
Цитата(kkosik @ Oct 5 2012, 15:32)  SPI тут не классический, поэтому по-другому немного. Переписал код, вроде бы всё синхронно сделал, но теперь после синтеза при моделировании не появляется выходной сигнал (строб есть). Хотя до синтеза всё в порядке... Специально промоделировал. Всё там у вас появляется. По крайней мере с выхода Data2 - "2с5". Data1 в "xx" потому что buff(1) равен '1' и для этого регистра не выполняется CASE. А вообще странный код.
|
|
|
|
|
Oct 5 2012, 13:38
|
Участник

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

|
Цитата Что значит, не появляется? Его синтезатор убил, он не срабатывает или в состоянии X находится? В состоянии ХХХХХХ... Цитата Специально промоделировал. Всё там у вас появляется. Моделировали после синтеза? или до? после синтеза описанная проблема появляется! Цитата А вообще странный код В чем именно?
|
|
|
|
|
Oct 5 2012, 14:03
|
Участник

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

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

Группа: Участник
Сообщений: 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 здесь правильнее, поскольку можно явно задать разрядность счетчика, и сразу видно, какой сигнал описывает триггерные ячейки.
|
|
|
|
|
Oct 8 2012, 08:27
|
Участник

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

|
Цитата разрядность счетчика явно задается как clogb2 от параметра. Круто, буду использовать! А что по делу?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|