Jump to content

    

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

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


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

 

Clipboard01.png.c4c0da5fdbf5436a148926b6c41b89f2.png

 

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

 

Clipboard02.thumb.png.22f23142e3a6419928af06880e98b5c3.png

 

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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 необъявленные состояния, Ваш автомат будет возвращатся в дефолтное состояние.

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

Share this post


Link to post
Share on other sites

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

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.

Share this post


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

Share this post


Link to post
Share on other sites
4 hours ago, MaratZuev said:

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

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

Share this post


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

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

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

Share this post


Link to post
Share on other sites
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. И никаких проблем не будет

Share this post


Link to post
Share on other sites

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

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.

Share this post


Link to post
Share on other sites

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

30 minutes ago, Nick_K said:

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


enum {ST_IDLE ....

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

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

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

 Удачи! Rob.

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

В первом случае  вы не можете сделать 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.

Share this post


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

С чего бы это?

Share this post


Link to post
Share on other sites

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

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.

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