Jump to content

    

Конструкция while - loop

Можно использовать такую конструкцию? Я встречаю ее в тестбенчах. Вопрос можно ли сделать так

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;

 

Share this post


Link to post
Share on other sites

Вообще-то никто не запрещает так делать. Другой вопрос как оно засинтезирует (если вопрос именно в "сделать так для синтеза").А вообще лучше просто разделать действия на отдельные компоненты. Что-то типа этого:

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() - результат одинаковый

Share this post


Link to post
Share on other sites
1 hour ago, Nick_K said:

Вообще-то никто не запрещает так делать. Другой вопрос как оно засинтезирует (если вопрос именно в "сделать так для синтеза").А вообще лучше просто разделать действия на отдельные компоненты. Что-то типа этого:

Опять же, что while...loop, что for() - результат одинаковый

я так понимаю там нужно дергать строб сигнал wb_stb_i в while . это циклическое действие. вопрос я остаюсь в цикле или все таки каждый клок захожу в стейт ST_CHIP_ERASE_2 ? тогда if (del = 6) можно вынести наружу.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 не очень нравиться.

Edited by jenya7

Share this post


Link to post
Share on other sites
27 минут назад, jenya7 сказал:

я остаюсь в цикле или все таки каждый клок захожу в стейт ST_CHIP_ERASE_2 ?

Вы остаётесь в цикле.

Share this post


Link to post
Share on other sites
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;

 

Share this post


Link to post
Share on other sites
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;

 

Edited by jenya7

Share this post


Link to post
Share on other sites
38 минут назад, jenya7 сказал:

стоит использовать такую конструкцию?

Я бы не стал.

Share this post


Link to post
Share on other sites
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, как в исходном варианте.

Share this post


Link to post
Share on other sites
1 hour ago, Zwerg_nase said:

Мне кажется, что while(ready..) и if(del..) внутри when ST_CHIP_ERASE_2 будут выполняться последовательною В результате, проверка del=6 будет сделана только после выхода из loop, а не внутри loop, как в исходном варианте.

ушел от этой конструкции while - loop. проверяю с if. мне так понятней.

Edited by jenya7

Share this post


Link to post
Share on other sites
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???

Share this post


Link to post
Share on other sites
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"

 

Share this post


Link to post
Share on other sites
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 Ваша последовательность - это безсмысленное нагромождение мультиплексоров, которое влечёт слаки.

Share this post


Link to post
Share on other sites
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;   

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now