Перейти к содержанию
    

Доступ к переменной из разных процессов.

Я принимаю пакеты данных в одном процессе, кладу его в свой слот и считываю пакет в другом процессе. И есть статусный регистр который показывает какой слот полный, чтоб знать какой слот считывать. То есть если я прочитал статусный регистр и он = 5 то я знаю что слоты 0 и 2 надо считать. В каждом сообщении есть номер слота куда оно запишеться.

В процессе записи по принятию данных я выставляю флаг установки

set_rx_stat <= '1';

В процессе чтения после чтения я выставляю флаг очистки

clr_rx_stat <= '1';

флаги дляться один такт.

И есть отдельный процесс который отслеживает эти флаги

signal rx_mailbox_busy_status : std_logic_vector(31 downto 0) := X"00000000";


VAR_INTERFACE : process (REG_CLK)
begin 
    if (rising_edge(REG_CLK)) then

	 case VarState is
		  
	     when  ST_VAR_IDLE =>
              if (set_rx_stat = '1') then
		     VarState <= ST_SET_RX_STAT;
		 elsif (clr_rx_stat = '1') then
		     VarState <= ST_CLR_RX_STAT;	
          end if;

           when ST_SET_RX_STAT =>
		 if (mailbox_idx < MAILBOX_COUNT) then			 
		     rx_mailbox_busy_status(mailbox_idx) <= '1';
		 end if;		  
		 VarState <= ST_VAR_IDLE;
				
	     when ST_CLR_RX_STAT =>
		 if (mailbox_idx < MAILBOX_COUNT) then
		     rx_mailbox_busy_status(mailbox_num) <= '0';
		 end if;		  
		 VarState <= ST_VAR_IDLE;

           when others => VarState <= ST_VAR_IDLE;
					 
      end case;

    end if;

end process VAR_INTERFACE;

mailbox_num определен как глобальная переменная и вычисляется в процессе получения команды чтения или автоматически при записи в слот.

shared variable mailbox_num : integer range 0 to 255 := 0;

Все пишеться и читается. НО! Иногда я получаю лишнее сообщение. Начал дебагировать и увидел что иногда я считываю статусный регистр с лишней единичкой.

Например я послал сообщение для слота 0. А считал rx_mailbox_busy_status = 5 то есть как будто в слоте 2 есть сообщение хотя я его не посылал и я вижу что считал старое сообщение из слота 2.

Сижу уже пару дней не могу понять откуда рыба писает.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь как минимум не хватает кода, который меняет mailbox_num, а так же пояснения - вы пока моделируете или все это в железе происходит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 minutes ago, alexadmin said:

Здесь как минимум не хватает кода, который меняет mailbox_num, а так же пояснения - вы пока моделируете или все это в железе происходит?

все работает реально в железе.

 

при записи

when ST_MCP25625_TO_RAM_7 =>
    if ( (temp_id and (not mailbox_mask)) = (mailbox_id and (not mailbox_mask)) ) then
	    mailbox_idx := idx1;
        RamState_b <= ST_MCP25625_TO_RAM_8;
    else
        idx1 := idx1 + 1;  --next mailbox number
        RamState_b <= ST_MCP25625_TO_RAM_2;  --check next mailbox		 
    end if;

при чтении я получаю команду по СПИ

COMMAND_READ_MAILBOX  MAILBOX_NUM

соответственно mailbox_num = MAILBOX_NUM

 

да. тут я забыл сказать что я оперерирую двумя переменными

shared variable mailbox_num : integer range 0 to 255 := 0;
shared variable mailbox_idx : integer range 0 to 255 := 0;

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 минут назад, jenya7 сказал:

Все пишеться и читается. НО! Иногда я получаю лишнее сообщение. Начал дебагировать и увидел что иногда я считываю статусный регистр с лишней единичкой.

Например я послал сообщение для слота 0. А считал rx_mailbox_busy_status = 5 то есть как будто в слоте 2 есть сообщение хотя я его не посылал.

Сижу уже пару дней не могу понять откуда рыба писает.

В приведённом участке кода вроде ничего "криминального" нет...
единственное чего, конструкция case <VarState> и изменение сигнала прямо в теле "case"   VarState<=

возможно стоит разбить автомат на 2 этапа, передний фронт
case <VarState1>
VarState2<= ....
а по заднему фронту (в этом же процессе) VarState1<=VarState2; 

У меня похожая ситуация была когда часть сигналов изменялась синхронно (в синхронных процессах), а часть была организована как "логика" без синхронизации.
Похоже на "гонку"... 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 minutes ago, serj1979 said:

Похоже на "гонку"... 

или времянка сыпется

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Потеряете ли вы что-нибудь глобально, если перепишите разделяемые переменные на сигналы? Я весьма смутно представляю семантику shared variables при синтезе, если только они не описывают двухпортовую память.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, alexadmin said:

Потеряете ли вы что-нибудь глобально, если перепишите разделяемые переменные на сигналы? Я весьма смутно представляю семантику shared variables при синтезе, если только они не описывают двухпортовую память.

я думаю что переписать можно. это может быть причиной проблемы?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это первое что сделал бы лично я, поскольку я плохо понимаю как shared variable будет реализовываться в железе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Трудно понять логику дизайна по неполным его кусочкам 

           when ST_SET_RX_STAT =>
		 if (mailbox_idx < MAILBOX_COUNT) then			 
		     rx_mailbox_busy_status(mailbox_idx) <= '1';
		 end if;		  
		 VarState <= ST_VAR_IDLE;
				
	     when ST_CLR_RX_STAT =>
		 if (mailbox_idx < MAILBOX_COUNT) then
		     rx_mailbox_busy_status(mailbox_num) <= '0';
		 end if;		  
		 VarState <= ST_VAR_IDLE;

Почему в одном случае mailbox_idx а во втором  mailbox_num?

Если в одном такте будет set_rx_stat и clr_rx_stat то clr_rx_stat не отработает так как по приоритету ниже а устанавливается (по вашим словам) только на 1 такт. 

Удачи! Rob. 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 minutes ago, RobFPGA said:

Приветствую!

Трудно понять логику дизайна по неполным его кусочкам 


           when ST_SET_RX_STAT =>
		 if (mailbox_idx < MAILBOX_COUNT) then			 
		     rx_mailbox_busy_status(mailbox_idx) <= '1';
		 end if;		  
		 VarState <= ST_VAR_IDLE;
				
	     when ST_CLR_RX_STAT =>
		 if (mailbox_idx < MAILBOX_COUNT) then
		     rx_mailbox_busy_status(mailbox_num) <= '0';
		 end if;		  
		 VarState <= ST_VAR_IDLE;

Почему в одном случае mailbox_idx а во втором  mailbox_num?

Если в одном такте будет set_rx_stat и clr_rx_stat то clr_rx_stat не отработает так как по приоритету ниже а устанавливается (по вашим словам) на 1 такт. 

Удачи! Rob. 

 

я решил использовать две разных переменных для установки - mailbox_idx и очистки - mailbox_num. Почему? Ну если идет процесс записи в один слот а я в это время считываю другой слот - в случае с одной переменной она перепишется.

а так отдельный индекс для установки и очистки.

 

правильней будет так?

when  ST_VAR_IDLE =>

    if (set_rx_stat = '1') then
	    VarState <= ST_SET_RX_STAT;
    end if;  
                                  
	if (clr_rx_stat = '1') then
		 VarState <= ST_CLR_RX_STAT;	
    end if;

конечно, теоретически два флага могут выставится одновременно. но тут особо ничего не поделаешь?

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

6 minutes ago, jenya7 said:

правильней будет так?

Так вы только поменяете приоритет - clr_rx_stat будет выше чем set_rx_stat. Но одновременно вы обрабатывать оба сигнала в этой реализации не сможете. 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, RobFPGA said:

Приветствую!

Так вы только поменяете приоритет - clr_rx_stat будет выше чем set_rx_stat. Но одновременно вы обрабатывать оба сигнала в этой реализации не сможете. 

Удачи! Rob.

а что можно обработать сигналы одновременно? разбить на два процеса?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 minutes ago, jenya7 said:

а что можно обработать сигналы одновременно? разбить на два процеса?

Логику переписать, которая обеспечивает корректное декодирование. Думал вы в стимуляторе все вылизали, а оказывается нет. Зря. Либо, в вашем случае, можно арбитраж сделать, с удержанием запроса и подтверждением ответа. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Зачем два процесса? Вы же одну переменную (rx_mailbox_busy_status) менять хотите.

Надо что то типа такого: (простите за корявый VHDL) 

  variable set_bits, clr_bits ...: 
...
  set_bits := shift_left(set_rx_stat , mailbox_idx);
  clr_bits := shift_left(clr_rx_stat , mailbox_num);

  -- prioritet set выше чем clear
  rx_mailbox_busy_status <= (rx_mailbox_busy_status and (not clr_bits)) or set_bits;
  -- prioritet clear выше чем set
  rx_mailbox_busy_status <= (rx_mailbox_busy_status or set_bits) and (not clr_bits);
...                                                  

 Удачи Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 minutes ago, RobFPGA said:

Приветствую!

Зачем два процесса? Вы же одну переменную (rx_mailbox_busy_status) менять хотите.

Надо что то типа такого: (простите за корявый VHDL) 


  variable set_bits, clr_bits ...: 
...
  set_bits := shift_left(set_rx_stat , mailbox_idx);
  clr_bits := shift_left(clr_rx_stat , mailbox_num);

  -- prioritet set выше чем clear
  rx_mailbox_busy_status <= (rx_mailbox_busy_status and (not clr_bits)) or set_bits;
  -- prioritet clear выше чем set
  rx_mailbox_busy_status <= (rx_mailbox_busy_status or set_bits) and (not clr_bits);
...                                                  

 Удачи Rob.

а эти действия

 set_bits := shift_left(set_rx_stat , mailbox_idx);
 clr_bits := shift_left(clr_rx_stat , mailbox_num);

по какому ивенту делать? 

 

 

19 minutes ago, des00 said:

Логику переписать, которая обеспечивает корректное декодирование. Думал вы в стимуляторе все вылизали, а оказывается нет. Зря. Либо, в вашем случае, можно арбитраж сделать, с удержанием запроса и подтверждением ответа. 

в симуляторе я проблемы не видел. она недавно вылезла при довольно серьезных стрессовых нагрузках на систему.

кстати у себя воспроизвести проблему не получается. 1000 послал 1000 принял. на определенных таймингах я начинаю терять пакеты но лишние не вижу.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...