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

FSM или как попасть в default

Всем много добра!


Занимаюсь разборками с покрытием кода. Интересует покрытие операторов (и не только, но об этом пока речь не идёт).
ModelSim показывает, что покрыто всё, за исключением машин состояний, а именно состояний default, куда я, по его мнению, никогда не попадаю.

 

Clipboard01.png.c4c0da5fdbf5436a148926b6c41b89f2.png

 

По временной диаграмме, в принципе, я тоже не вижу, что я когда-либо нахожусь в этом непонятном мне состоянии:

 

Clipboard02.thumb.png.22f23142e3a6419928af06880e98b5c3.png

 

Вопрос: что же делать, чтобы обеспечить 100% покрытие, как того требует стандарт: выкинуть default из проекта, но что-то подсказывает, что это не есть комильфо, или умудриться всё-таки войти в него, но как?!

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


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

Сделайте ваш Кейс unique и выкиньте состояние dafault. Тогда Вы точно никогда не попадёте в него. Вообще default используется для явного кодирования, когда есть регистр на 3 разряда, а кодирует он, к примеру, только 6 значений. Тогда 2 состояния остаются непокрытыми и в случае ошибки, сбоя и т.д. и переходе в эти самые 2 необъявленные состояния, Ваш автомат будет возвращатся в дефолтное состояние. Когда же тип кодирования не задано (часто он one_hot) тогда в регистровом слове все состояния закодированы, а что ненужно, то оптимизированно (по крайней мере так задумывается). Соответственно необходимость в defolt'е отпадает, но прагмы синтексиса не разрешают писать без него.

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


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

57 minutes ago, Кнкн said:

force/release в тестбенче? 

 34   initial begin 
 35       force dut_main.dut_module1.state = default;
 36       force dut_main.dut_module2.state = default;
 37       #10ns release dut_main.dut_module1.state;
 38             release dut_main.dut_module2.state;
 39   end

Даёт:

# ** Error: (vlog-13069) ../../Project/dut_tb.sv(35): near "default": syntax error, unexpected default.
# ** Error: (vlog-13069) ../../Project/dut_tb.sv(36): near "default": syntax error, unexpected default.

 

1 hour ago, Nick_K said:

Тогда 2 состояния остаются непокрытыми и в случае ошибки, сбоя и т.д. и переходе в эти самые 2 необъявленные состояния, Ваш автомат будет возвращатся в дефолтное состояние.

Могу я как-то смоделировать это?

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


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

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

27 minutes ago, MaratZuev said:

# ** Error: (vlog-13069) ../../Project/dut_tb.sv(35): near "default": syntax error, unexpected default.

Вы не можете присвоить default. Это ключевое слово а не значение.  Мне кажется вам надо присваивать state значение которое неопределенно в  enum для этого state или которого нет в case где этот state используется.

Как пример:   force state = e_STATE_t'(ST_LAST_DEFINED + 1);  или  force state =  e_STATE_t'('x);

Удачи! Rob.

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


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

29 minutes ago, MaratZuev said:

Могу я как-то смоделировать это?

Да, можно. Нужно найти enum сигнал с названиями стейтов и фактически поприсваивать ему разные переменные. Обычно enum в SV кодируется десятичными числами от 0, соответственно в Вашем enum {ST_IDLE, ST_INIT ...} state переменные будут закодированы ST_IDLE=0 , ST_INIT=1 и т.д. если присвоить в state 6 и 7 (там вроде бы всего 6 состояний), то должно сработать. Но есть нюансы: интерпретация симулятором может отличаться от синтезируемой конструкции. Тут можно посоветовать только явно указать значения для каждого елемента enum.

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


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

4 hours ago, MaratZuev said:

Вопрос: что же делать, чтобы обеспечить 100% покрытие, как того требует стандарт: выкинуть default из проекта, но что-то подсказывает, что это не есть комильфо, или умудриться всё-таки войти в него, но как?!

как раз для этого существует механизм исключений строк кода из анализа покрытия. Делается на этапе компиляции. Посмотрите внимательного документацию. 

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


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

On 12/5/2019 at 11:45 AM, RobFPGA said:

Как пример:   force state = e_STATE_t'(ST_LAST_DEFINED + 1);  или  force state =  e_STATE_t'('x);

Боюсь показаться тупым, но как это будет выглядеть для

enum {ST_IDLE, ST_INIT, ST_ADDR, ST_DATA, ST_CRC8, ST_PULS} state;

?

23 hours ago, Nick_K said:

Вашем enum {ST_IDLE, ST_INIT ...} state переменные будут закодированы ST_IDLE=0 , ST_INIT=1 и т.д. если присвоить в state 6 и 7 (там вроде бы всего 6 состояний), то должно сработать.

Увы и ах:

dut.sv:
9 enum {ST_IDLE = 0, ST_INIT = 1, ST_ADDR = 2, ST_DATA = 3, ST_CRC8 = 4, ST_PULS = 5} state;
dut_tb.sv:
34    int state;
35
36    initial begin 
37        state = 6;
38        force dut.state = state;
39        #10ns release dut.state;
40    end
ModelSim:
# ** Error (suppressible): (vsim-8386) ../../Project/dut_tb.sv(38): Illegal assignment to type 'dut_tb.dut.enum int ' from type 'int': An enum variable may only be assigned the same enum typed variable or one of its values.
#    Time: 0 ps  Iteration: 0  Instance: /dut_tb File: ../../Project/dut_tb.sv
# Error loading design
# Error: Error loading design

 

21 hours ago, des00 said:

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

Разве есть не является подтасовкой результатов? Ведь так я могу и весь код исключить, чтобы лишней, как по мне, работой не заниматься!

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


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

42 minutes ago, MaratZuev said:

Увы и ах:

Значит неиспользуемые состояния триггера 

enum {ST_IDLE = 0, ST_INIT = 1, ST_ADDR = 2, ST_DATA = 3, ST_CRC8 = 4, ST_PULS = 5} state

оптимизируются тестовой  средой. В таком случае смело выбрасывайте состояние default но сам кейс сделайте unique. И никаких проблем не будет

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


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

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

2 minutes ago, MaratZuev said:

enum {ST_IDLE, ST_INIT, ST_ADDR, ST_DATA, ST_CRC8, ST_PULS} state;

Когда вы просто объявляете enum то тип этого enum анонимен и вы не можете сделать статический cast к этому анонимному типу.  А сделать это через динамический $cast() не получится 

  if (!$cast (state,  ST_PULS+1)  ... // cast bad 

Поэтому  только  небольшим  изменением  через статический cast - 

2 minutes ago, MaratZuev said:

typedef enum {ST_IDLE, ST_INIT, ST_ADDR, ST_DATA, ST_CRC8, ST_PULS} state_t;  state_t state;

....

 force dut.state = state_t'(ST_PULS+1);  // Ну или  state = state_t'(6);

Но так как правильность static cast не проверяется надо иметь ввиду базовый тип enum по умолчанию. Так как в SV это обычно  int (bit base) то  каcтануть его к 'x  не получится :unknw: . Это можно делать только для logic base типов . Так же как и если базовый тип  typedef enum [1:0] {....} state_t, а попытаться присвоить значение > 3. 

Удачи! Rob.

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


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

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

30 minutes ago, Nick_K said:

Значит неиспользуемые состояния триггера ...


enum {ST_IDLE ....

оптимизируются тестовой  средой. В таком случае смело выбрасывайте состояние default но сам кейс сделайте unique. И никаких проблем не будет

Тестовой средой ничего не оптимизируется. При таком объявление enum представлен как int  в 32 бита.  И в коде при желании можно запросто воткнуть ему любое значение. 

Кстати и синтезаторы  тоже не всегда нормально оптимизируют разрядность enum. В частности Qu периодически норовить синтезировать enum переменные в полные 32 бита если не обрезать разрядность до требуемой при объявлении.

 Удачи! Rob.

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


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

Я уже не знаю, кому отвечать!
Но до сих пор не могу взять в толк, в чём моя проблема?
 

dut.sv 
typedef enum {ST_IDLE = 0, ST_INIT = 1, ST_ADDR = 2, ST_DATA = 3, ST_CRC8 = 4, ST_PULS = 5} state_t;
state_t state;

Вариант 1
dut_tv.sv
34    initial begin 
35        force dut.state = dut.state'(6);
36        #10ns release dut.state;
37    end
ModelSim
# ** Error: (vsim-8220) dut_tb.sv(35): This or another usage of 'dut.state' inconsistent with 'register' object.
#    Time: 0 ps  Iteration: 0  Instance: /dut_tb File: dut_tb.sv
# ** Error: (vsim-3044) dut_tb.sv(35): Usage of 'dut.state' inconsistent with 'register' object.
#    Time: 0 ps  Iteration: 0  Instance: /dut_tb File: dut_tb.sv

Вариант 2
dut_tv.sv
34    initial begin 
35        force dut.state = dut.state_t'(6);
36        #10ns release dut.state;
37    end
ModelSim
# ** Error: (vsim-8220) dut_tb.sv(35): This or another usage of 'dut.state_t' inconsistent with 'typedef' object.
#    Time: 0 ps  Iteration: 0  Instance: /dut_tb File: dut_tb.sv
# ** Error: (vsim-3044) dut_tb.sv(35): Usage of 'dut.state_t' inconsistent with 'typedef' object.
#    Time: 0 ps  Iteration: 0  Instance: /dut_tb File: dut_tb.sv
# ** Error (suppressible): (vsim-8386) dut_tb.sv(35): Illegal assignment to type 'dut_tb.dut.enum int ' from type 'bit signed[-1:0]': An enum variable may only be assigned the same enum typed variable or one of its values.
#    Time: 0 ps  Iteration: 0  Instance: /dut_tb File: dut_tb.sv

Готов признать себя тупым, только подскажите ЧЯДНТ?!

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


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

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

В первом случае  вы не можете сделать static cast так как state это переменная а не тип.

А во втором  случае вы натыкаетесь на область видимости типов.  Если вы объявили  тип enum в модуле  то этот тип локален - вы не можете видеть его вне модуля. Обидно понимаешь ли  :cray:  Хотите видеть снаружи - объявляете тип  в package и импортируйте куда нужно. 

Поэтому  в вашем случае:

либо переносить все в package  - идеологически  правильно но муторно.

либо  забит  на строгость ModelSIm  и отрубить ошибку несоответствия типов (через -suppress vsim-8386)  и делать force dut.state = 6;

либо  :wink2: .... взять  болт с левой резьбой:  force dut.state = dut.ST_PULS + dut.ST_PULS;  :biggrin:  (или даже dut.state.last() + dut.state.last() )

Хотя чревато это тем что на этот болт когда нибудь найдется своя задница. 

Удачи! Rob.

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


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

2 hours ago, RobFPGA said:

dut.state.last() + dut.state.last()

Спасибо! Этот болт мне нравится больше всего. Странно только, что на такой же болт но с меньшим количеством витков dut.state.last() + dut.state.first() ModelSim ругается:

# ** Error (suppressible): (vsim-8386) dut_tb.sv(37): Illegal assignment to type 'dut_tb.dut.enum int ' from type 'bit signed[31:0]': 
An enum variable may only be assigned the same enum typed variable or one of its values.

С чего бы это?

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


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

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

16 minutes ago, MaratZuev said:

С чего бы это?

Ну так болт же - а вот к нему и задница :declare:.   

В ModelSIm это работает если складываются две одинаковые  величины - ...state.last()+...state.last(),  ...state.first()+...state.first(),  dut.ST_PULS + dut.ST_PULS,  даже ...state.next()+...state.next(), :shok:  А вот разные значения  даже одного enum ни ни!  А почему так увы не знаю :unknw:

Удачи! Rob.

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


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

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

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

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

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

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

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

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

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

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