jenya7 0 December 1, 2021 Posted December 1, 2021 (edited) · Report post Есть такой тестбенч Spoiler LIBRARY ieee; USE ieee.std_logic_1164.ALL; entity qspi_tb is end qspi_tb; architecture behavior of qspi_tb is component QUADSPI is port ( CLK : in std_logic; RST : in std_logic := '0'; SPI_CS : in std_logic; SPI_CLK : in std_logic; SPI_DATA : inout std_logic_vector(3 downto 0); DATA_OUT : out std_logic_vector(7 downto 0); DATA_IN : in std_logic_vector(7 downto 0); READY_READ : out std_logic; READY_WRITE : out std_logic ); end component; signal reset : std_logic := '1'; signal clock : std_logic; signal qspi_cs : std_logic := '1'; signal qspi_clk : std_logic; signal qspi_data : std_logic_vector(3 downto 0); signal s_spi_data_out : std_logic_vector(7 downto 0); signal s_spi_data_in : std_logic_vector(7 downto 0); signal s_ready_read : std_logic; signal s_ready_write : std_logic; constant clk_period : time := 40 ns; constant spi_clk_period : time := 10 ns; signal clk_ena : std_logic; signal clk_count : std_logic_vector(7 downto 0); begin U_QSPI : QUADSPI port map ( CLK => clock, RST => reset, SPI_CS => qspi_cs, SPI_CLK => qspi_clk, SPI_DATA => qspi_data, DATA_OUT => s_spi_data_out, DATA_IN => s_spi_data_in, READY_READ => s_ready_read, READY_WRITE => s_ready_write ); --clk_process :process --begin --clock <= '0'; --wait for clk_period/2; --clock <= '1'; --wait for clk_period/2; --end process; spi_clk_process : process begin --if (qspi_cs = '0') then qspi_clk <= '0'; wait for spi_clk_period/2; qspi_clk <= '1'; wait for spi_clk_period/2; --end if; end process; stim_proc: process variable clk_count : integer range 0 to 255 := 0; begin qspi_cs <= '0'; if (rising_edge(clock)) then if (rising_edge(qspi_clk)) then clk_count := clk_count + 1; end if; case clk_count is --instruction when 0 => when 1 => qspi_data <= X"0"; when 2 => qspi_data <= X"7"; --address when 3 => qspi_data <= X"0"; when 4 => qspi_data <= X"0"; when 5 => qspi_data <= X"1"; when 6 => qspi_data <= X"2"; when 7 => qspi_data <= X"3"; when 8 => qspi_data <= X"4"; --alt when 9 => qspi_data <= X"A"; when 10 => qspi_data <= X"B"; --dummy when 11 => qspi_data <= X"5"; when 12 => qspi_data <= X"5"; --data when 13 => qspi_data <= X"8"; when 14 => qspi_data <= X"8"; when 15 => qspi_data <= X"9"; when 16 => qspi_data <= X"9"; when others => clk_count := 0; qspi_cs <= '1'; end case; end if; wait; end process stim_proc; end behavior; Открываю проект в ModelSim загружаю файлы, компилирую, всё хорошо ошибок нет. загружаю сигналы в Wave. clock определяю как системный clock . Нажимаю Run, симуляция бежит но clock и сигналы не генерируются. В чем может быть проблема? Edited December 1, 2021 by jenya7 Quote Share this post Link to post Share on other sites More sharing options...
FakeDevice 0 December 1, 2021 Posted December 1, 2021 · Report post так у вас же процесс формирования сигнала clock закомментирован Quote --clk_process :process --begin --clock <= '0'; --wait for clk_period/2; --clock <= '1'; --wait for clk_period/2; --end process; Quote Share this post Link to post Share on other sites More sharing options...
jenya7 0 December 1, 2021 Posted December 1, 2021 · Report post 15 minutes ago, FakeDevice said: так у вас же процесс формирования сигнала clock закомментирован я пробовал генерировать из тестбенча но он не генерировался в Wave. Так я в Wave его определяю Right click -> Clock... так тоже не генерируется. Quote Share this post Link to post Share on other sites More sharing options...
FakeDevice 0 December 1, 2021 Posted December 1, 2021 · Report post Форсировать clock из "wave" -- точно неправильно. Разбирайтесь, добивайтесь того, чтобы из тест-бенча генерировался. Quote Share this post Link to post Share on other sites More sharing options...
jenya7 0 December 1, 2021 Posted December 1, 2021 (edited) · Report post я немного изменил тестбенч Spoiler LIBRARY ieee; USE ieee.std_logic_1164.ALL; entity qspi_tb is end qspi_tb; architecture behavior of qspi_tb is component QUADSPI is port ( CLK : in std_logic; RST : in std_logic := '0'; SPI_CS : in std_logic; SPI_CLK : in std_logic; SPI_DATA : inout std_logic_vector(3 downto 0); DATA_OUT : out std_logic_vector(7 downto 0); DATA_IN : in std_logic_vector(7 downto 0); READY_READ : out std_logic; READY_WRITE : out std_logic ); end component; signal reset : std_logic := '1'; signal clock : std_logic; signal qspi_cs : std_logic := '1'; signal qspi_clk : std_logic; signal qspi_data : std_logic_vector(3 downto 0); signal s_spi_data_out : std_logic_vector(7 downto 0); signal s_spi_data_in : std_logic_vector(7 downto 0); signal s_ready_read : std_logic; signal s_ready_write : std_logic; constant clk_period : time := 40 ns; constant spi_clk_period : time := 400 ns; signal clk_ena : std_logic; signal clk_count : std_logic_vector(7 downto 0); begin U_QSPI : QUADSPI port map ( CLK => clock, RST => reset, SPI_CS => qspi_cs, SPI_CLK => qspi_clk, SPI_DATA => qspi_data, DATA_OUT => s_spi_data_out, DATA_IN => s_spi_data_in, READY_READ => s_ready_read, READY_WRITE => s_ready_write ); clk_process :process begin clock <= '0'; wait for clk_period/2; clock <= '1'; wait for clk_period/2; end process; spi_clk_process : process begin qspi_clk <= '0'; wait for spi_clk_period/2; qspi_clk <= '1'; wait for spi_clk_period/2; end process; stim_proc: process variable clk_count : integer range 0 to 255 := 0; begin qspi_cs <= '1'; wait for 80 ns; qspi_cs <= '0'; if (rising_edge(clock)) then if (rising_edge(qspi_clk)) then clk_count := clk_count + 1; end if; case clk_count is --instruction when 0 => when 1 => qspi_data <= X"0"; when 2 => qspi_data <= X"7"; --address when 3 => qspi_data <= X"0"; when 4 => qspi_data <= X"0"; when 5 => qspi_data <= X"1"; when 6 => qspi_data <= X"2"; when 7 => qspi_data <= X"3"; when 8 => qspi_data <= X"4"; --alt when 9 => qspi_data <= X"A"; when 10 => qspi_data <= X"B"; --dummy when 11 => qspi_data <= X"5"; when 12 => qspi_data <= X"5"; --data when 13 => qspi_data <= X"8"; when 14 => qspi_data <= X"8"; when 15 => qspi_data <= X"9"; when 16 => qspi_data <= X"9"; when others => clk_count := 0; qspi_cs <= '1'; end case; end if; wait; end process stim_proc; end behavior; клоки генерируются. Но не ивента qspi_cs хотя я вначале генерирую его qspi_cs <= '1'; wait for 80 ns; qspi_cs <= '0'; я что то упускаю? Edited December 1, 2021 by jenya7 Quote Share this post Link to post Share on other sites More sharing options...
FakeDevice 0 December 1, 2021 Posted December 1, 2021 · Report post 3 minutes ago, jenya7 said: Но не ивента qspi_cs хотя я врачале генерирую его я что то упускаю? Начать можно с того, что на картинке шкалы времени не видно. Возможно, в начале симуляции что-то и было. Quote Share this post Link to post Share on other sites More sharing options...
jenya7 0 December 1, 2021 Posted December 1, 2021 (edited) · Report post 14 minutes ago, FakeDevice said: Начать можно с того, что на картинке шкалы времени не видно. Возможно, в начале симуляции что-то и было. таки да. в начале есть qspi_cs и клоки генерируются. а компонент не работает. значит что то не так с моим QUADSPI или я что то упускаю в таймингах. Edited December 1, 2021 by jenya7 Quote Share this post Link to post Share on other sites More sharing options...
FakeDevice 0 December 1, 2021 Posted December 1, 2021 · Report post 4 minutes ago, jenya7 said: или я что то упускаю в таймингах. Есть немного. Во-первых, непонятно, что с сигналом RST. на waveform его не видно, в тест-бенче он после инициализации тоже нигде не формируется. Ну и то, что прям по старту симуляции у вас на модуль идет управляющий сигнал SPI_CS -- тоже, как правило, неверно. Подождите хотя бы с 10-20 тактов, потом подавайте. Возможно, какая-то завязка есть. Затем, из картинки видно, что и на SPI_DATA постоянно подается "UUUU". Как должна реагировать в данном случае схема? Я тоже не знаю. В общем, проверяйте сигнал за сигналом, чтобы полностью соответствовало временным диаграммам из документации, для начала. А потом, если ВСЕ условия окажутся соблюденными, но так и не заработает -- будет иметь смысл разбираться дальше. Вы не торопитесь, тут больше зависит от внимательности и тщательности. Методом перебора здесь вы ничего хорошего не добьетесь. Quote Share this post Link to post Share on other sites More sharing options...
jenya7 0 December 1, 2021 Posted December 1, 2021 (edited) · Report post Вот теперь я понимаю почему я люблю SignalTap. В диаграме мы видим - clk3 исправно генерируется. а s_counter = 0. хотя я добавил в условие if (clk3 = '1') then s_counter <= s_counter + '1'; clk_count := clk_count + 1; end if; ну хорошо - мой косяк :)). вот сгенерировался вполне логичный случай видим в ST_INSTR - два clk3. и s_counter инкрементируется. when ST_INSTR => if (clk3 = '1') then clk_count := clk_count + 1; end if; case clk_count is when 1 => s_instruction(7 downto 4) <= SPI_DATA; when 2 => s_instruction(3 downto 0) <= SPI_DATA; clk_count := 0; QSpiState <= ST_ADDR; when others => clk_count := 0; --QSpiState <= ST_ADDR; end case; SPI_DATA = U. ну съехали тайминги получил другое значение на SPI_DATA. но U? Edited December 1, 2021 by jenya7 Quote Share this post Link to post Share on other sites More sharing options...
FakeDevice 0 December 1, 2021 Posted December 1, 2021 · Report post 16 minutes ago, jenya7 said: хотя я добавил в условие if (clk3 = '1') then s_counter <= s_counter + '1'; clk_count := clk_count + 1; end if; Это лишь часть правды. Выкладывайте весь модуль )) Quote Share this post Link to post Share on other sites More sharing options...
jenya7 0 December 1, 2021 Posted December 1, 2021 (edited) · Report post 6 minutes ago, FakeDevice said: Это лишь часть правды. Выкладывайте весь модуль )) quadspi.vhdqspi_tb.vhd это модуль и тест бенч. Я понял - это та ещё проблема синхронизировать модуль и тест бенч. тест бенчи нужно уметь писать. Edited December 1, 2021 by jenya7 Quote Share this post Link to post Share on other sites More sharing options...
FakeDevice 0 December 1, 2021 Posted December 1, 2021 · Report post 35 minutes ago, jenya7 said: SPI_DATA = U. ну съехали тайминги получил другое значение на SPI_DATA. но U? Не факт. В тестбенче у вас qspi_data зависит от некоторых сигналов. Например, от clk_count. Вы уверены, что clk_count и, соответственно, qspi_data формируются так, как вы ожидаете? Ну и сразу замечу, что конструкции типа Quote if (rising_edge(clock)) then if (rising_edge(qspi_clk)) then являются некорректными. Вложенный rising_edge -- это неправильно. Плюс, вопрос на засыпку... Согласно тест-бенчу, как часто должно обновляться значение счетчика clk_count? Судя по коду -- оно вообще не будет обновляться. Процесс доходит до строки "wait;" и всё, до рестарта симуляции в этом процессе больше ничего не произойдет. Т.е. процесс нужно переписать либо так, чтобы он каждый раз срабатывал по очередному клоку, либо нужно будет использовать цикл, в котором последовательно, с учетом ожиданий следующих тактов, менялись бы значения clk_count и qspi_data. Но я бы для начала рекомендовал бы первый вариант, "перезапускаемый" процесс без оператора "wait;" А счётчик clk_count вообще можно вынести в другой процесс. Quote Share this post Link to post Share on other sites More sharing options...
jenya7 0 December 1, 2021 Posted December 1, 2021 · Report post мне кажется тестбенч должен писать тестировщик иначе есть соблазн подогнать тестбенч под правильный ответ :) Quote Share this post Link to post Share on other sites More sharing options...
Flip-fl0p 2 December 1, 2021 Posted December 1, 2021 · Report post 2 часа назад, jenya7 сказал: мне кажется тестбенч должен писать тестировщик иначе есть соблазн подогнать тестбенч под правильный ответ :) Хороший ПЛИСовик должен уметь писать тесты. Иначе никак. Quote Share this post Link to post Share on other sites More sharing options...
andrew_b 9 December 1, 2021 Posted December 1, 2021 · Report post По-хорошему, надо начинать с тестбенча. Сначала вы "рисуете" входные воздействия для вашего модуля, а потом у же пишете сам модуль, который их обрабатывает. Quote Share this post Link to post Share on other sites More sharing options...