jenya7 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба Можно использовать такую конструкцию? Я встречаю ее в тестбенчах. Вопрос можно ли сделать так when ST_CHIP_ERASE_2 => while(ready='0') loop --read until rdy_by=1 wb_stb_i <='1'; wb_we_i <='0'; --read wb_addr_i <= "0100"; --rdy_by register address --wait for 60 ns; del := del + 1; if (del = 6) then del := 0; ready <= wb_dat_o(0); wb_stb_i <= '0'; end if; end loop; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба Вообще-то никто не запрещает так делать. Другой вопрос как оно засинтезирует (если вопрос именно в "сделать так для синтеза").А вообще лучше просто разделать действия на отдельные компоненты. Что-то типа этого: when ST_CHIP_ERASE_2 => while(ready='0') loop --read until rdy_by=1 wb_stb_i <='1'; wb_we_i <='0'; --read wb_addr_i <= "0100"; --rdy_by register address del := del + 1; end loop; if (del = 6) then del := 0; ready <= wb_dat_o(0); wb_stb_i <= '0'; end if; Опять же, что while...loop, что for() - результат одинаковый Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 1 hour ago, Nick_K said: Вообще-то никто не запрещает так делать. Другой вопрос как оно засинтезирует (если вопрос именно в "сделать так для синтеза").А вообще лучше просто разделать действия на отдельные компоненты. Что-то типа этого: Опять же, что while...loop, что for() - результат одинаковый я так понимаю там нужно дергать строб сигнал wb_stb_i в while . это циклическое действие. вопрос я остаюсь в цикле или все таки каждый клок захожу в стейт ST_CHIP_ERASE_2 ? тогда if (del = 6) можно вынести наружу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 4 minutes ago, jenya7 said: я так понимаю там нужно дергать строб сигнал wb_stb_i в while . это циклическое действие. вопрос я остаюсь в цикле или все таки каждый клок захожу в стейт ST_CHIP_ERASE_2 ? тогда if (del = 6) можно вынести наружу. Вы так и не сказали, конструкция для синтеза или для симуляции. При синтезе мультиплексор case'а (when ST_CHIP_ERASE_2) будет переключен на соответствующий порт, а цикл по сути - это adder с проверкой выхода на переполнение (=6) + некая логика. Для симуляции ситуация приблизительно такая же (постоянно проверка case'а + ready = '0') с попутным заходом в цикл. Но как Вы понимаете, перестановка слагаемых сумму не меняет. Особенно на VHDL Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 16 июля, 2019 Опубликовано 16 июля, 2019 (изменено) · Жалоба 1 hour ago, Nick_K said: Вы так и не сказали, конструкция для синтеза или для симуляции. При синтезе мультиплексор case'а (when ST_CHIP_ERASE_2) будет переключен на соответствующий порт, а цикл по сути - это adder с проверкой выхода на переполнение (=6) + некая логика. Для симуляции ситуация приблизительно такая же (постоянно проверка case'а + ready = '0') с попутным заходом в цикл. Но как Вы понимаете, перестановка слагаемых сумму не меняет. Особенно на VHDL я хочу перевести тест бенч в реальный код. в тестбенче так ---------------------------------------------------------------chip erase command ------------write 4 to wb_code register wait until clk'event and clk='1'; wait for 1 ns; wb_stb_i<='1'; wb_we_i<='1'; --//write wb_addr_i <= "0101" ; --// wb_code register address wb_dat_i <= x"0004"; --// for chip erase,command code is 4 ready<='0'; wait for 40 ns; wb_stb_i <= '0' ; ---------------read until rdy_by=1,that indicate the nor flash finish the chip erase operation. while(ready='0') loop -- //read until rdy_by=1 wait until clk'event and clk='1'; wait for 1 ns; wb_stb_i<='1'; wb_we_i<='0'; --//read wb_addr_i <= "0100" ; --// rdy_by register address wait for 60 ns; ready<=wb_dat_o(0); wb_stb_i <= '0' ; end loop; у меня получилось так -------------------------------- CHIP ERASE ----------------------------- when ST_CHIP_ERASE_1 => --write 4 to wb_code register wb_stb_i <='1'; wb_we_i <='1'; --write wb_addr_i <= "0101"; --wb_code register address wb_dat_i <= x"0004"; --for chip erase,command code is 4 ready<='0'; --wait for 40 ns; del := del + 1; if (del = 4) then wb_stb_i <= '0'; del := 0; FlashState <= ST_CHIP_ERASE_2; end if; when ST_CHIP_ERASE_2 => while(ready='0') loop --read until rdy_by=1 wb_stb_i<='1'; wb_we_i<='0'; --read wb_addr_i <= "0100"; --rdy_by register address --wait for 60 ns; del := del + 1; if (del = 6) then del := 0; ready <= wb_dat_o(0); wb_stb_i <= '0'; end if; end loop; FlashState <= ST_IDLE; хотя мне while loop не очень нравиться. Изменено 16 июля, 2019 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 14 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 27 минут назад, jenya7 сказал: я остаюсь в цикле или все таки каждый клок захожу в стейт ST_CHIP_ERASE_2 ? Вы остаётесь в цикле. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 8 minutes ago, jenya7 said: хотя мне while loop не очень нравиться. Ну так поменяйте while loop на обычное if else: if del = 6 then del := 0; ready <= wb_dat_o(0); wb_stb_i <= '0'; else del := del + 1; wb_stb_i<='1'; end if; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 16 июля, 2019 Опубликовано 16 июля, 2019 (изменено) · Жалоба 1 hour ago, andrew_b said: Вы остаётесь в цикле. стоит использовать такую конструкцию? или лучше when ST_CHIP_ERASE_2 => if (ready='0') then --read until rdy_by=1 wb_stb_i<='1'; wb_we_i<='0'; --read wb_addr_i <= "0100"; --rdy_by register address --wait for 60 ns; del := del + 1; if (del = 6) then del := 0; ready <= wb_dat_o(0); wb_stb_i <= '0'; FlashState <= ST_CHIP_ERASE_3; end if; else FlashState <= ST_IDLE; end if; when ST_CHIP_ERASE_3 => wb_stb_i <= '0'; FlashState <= ST_CHIP_ERASE_2; Изменено 16 июля, 2019 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 14 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 38 минут назад, jenya7 сказал: стоит использовать такую конструкцию? Я бы не стал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZwergNase 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 5 hours ago, Nick_K said: Вообще-то никто не запрещает так делать. Другой вопрос как оно засинтезирует (если вопрос именно в "сделать так для синтеза").А вообще лучше просто разделать действия на отдельные компоненты. Что-то типа этого: when ST_CHIP_ERASE_2 => while(ready='0') loop --read until rdy_by=1 wb_stb_i <='1'; wb_we_i <='0'; --read wb_addr_i <= "0100"; --rdy_by register address del := del + 1; end loop; if (del = 6) then del := 0; ready <= wb_dat_o(0); wb_stb_i <= '0'; end if; Опять же, что while...loop, что for() - результат одинаковый Мне кажется, что while(ready..) и if(del..) внутри when ST_CHIP_ERASE_2 будут выполняться последовательною В результате, проверка del=6 будет сделана только после выхода из loop, а не внутри loop, как в исходном варианте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 16 июля, 2019 Опубликовано 16 июля, 2019 (изменено) · Жалоба 1 hour ago, Zwerg_nase said: Мне кажется, что while(ready..) и if(del..) внутри when ST_CHIP_ERASE_2 будут выполняться последовательною В результате, проверка del=6 будет сделана только после выхода из loop, а не внутри loop, как в исходном варианте. ушел от этой конструкции while - loop. проверяю с if. мне так понятней. Изменено 16 июля, 2019 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 37 minutes ago, Zwerg_nase said: Мне кажется, что while(ready..) и if(del..) внутри when ST_CHIP_ERASE_2 будут выполняться последовательною В результате, проверка del=6 будет сделана только после выхода из loop, а не внутри loop, как в исходном варианте. Где Вас таких программистов понабирали? Это всё является описанием полупроводниковой логики. Соответственно после синтеза будет схема, в которой будет присутствовать синхронный сумматор на +1, а на выходе будет элемент сравнения, который при получении сигнала del=6 на выходе установит елиницу, которая в свою очередь сбросит синхронный триггер wb_stb_i в '0' (то есть значение появится на следующем такте, параллельно с переходом автомата FlashState в ST_IDLE). Какое последовательно? Какая проверка после выхода из loop? В каком внутри loop??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZwergNase 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 1 hour ago, Nick_K said: Какое последовательно? Какая проверка после выхода из loop? В каком внутри loop??? Из вашего кода не следует, что это синхронная логика, т.к. в нём не описан список чувствительности. А Case может использоваться и в ассинхронной. Согласно вашему описанию, должна быть синтезирована схема, которая, по изменению некоего сигнала из списка чувствительности (например, положительному фронту клока) при выполнении условия ST_CHIP_ERASE_2 должна выполнить два оператора: while ... loop и затем, а не параллельно, if...else. В стандарте IEEE 1076 указано, что внутри when указываются sequential-statement: case-statement –› [ case-label ‘:’ ] case expression is when choices ‘=>’ { sequential-statement } { when choices ‘=>’ { sequential-statement } } end case [ case-label ] ‘;’ Про которые раннее в том же стандарте написано, что "Sequential statements differ from concurrent VHDL statements in that they are executed in the order they are written. Sequential statements include the following types of statements: ... - If, case, loop, next, return statements - Wait statements" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 11 minutes ago, Zwerg_nase said: Из вашего кода не следует, что это синхронная логика, т.к. в нём не описан список чувствительности. А Case может использоваться и в ассинхронной. Во-первых код не мой, а автора темы. Во-вторых, если пролистать чуточку выше, то найдёте забавный комментарий в тексте: ... --wait for 60 ns; del := del + 1; if (del = 6) then del := 0; ... Из чего следует, что: 1. Нужно синтезировать задержку, а значит это клоковый модуль. 2. Частота работы блока 100MHz 14 minutes ago, Zwerg_nase said: Про которые раннее в том же стандарте написано, что "Sequential statements differ from concurrent VHDL statements in that they are executed in the order they are written. Sequential statements include the following types of statements: ... - If, case, loop, next, return statements - Wait statements" А это всё чистой воды слова для тестирования в симуляторе и не имеет вообще никакого отношения к реально синтезированному, а тем более Place&Route, проекту, в котором различия могут быть во временных задержках и типах элементов, до банальных слаков. 19 minutes ago, Zwerg_nase said: должна выполнить два оператора: while ... loop и затем, а не параллельно, if...else вот тут я согласен, если разговор о различных клоковых доменах или оперировании Латчами. Но в одном клоковом домене,а тем более в одном состоянии FSM Ваша последовательность - это безсмысленное нагромождение мультиплексоров, которое влечёт слаки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZwergNase 0 17 июля, 2019 Опубликовано 17 июля, 2019 · Жалоба 20 hours ago, Nick_K said: Во-первых код не мой, а автора темы. Я имею в виду ваш код, который вы написали в своём первом комменте: 23 hours ago, Zwerg_nase said: Что-то типа этого: when ST_CHIP_ERASE_2 => while(ready='0') loop --read until rdy_by=1 wb_stb_i <='1'; wb_we_i <='0'; --read wb_addr_i <= "0100"; --rdy_by register address del := del + 1; end loop; if (del = 6) then del := 0; ready <= wb_dat_o(0); wb_stb_i <= '0'; end if; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться