реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Вопрос по работе CASE в Verilog, CASE в Verilog
jurist
сообщение Aug 11 2018, 19:53
Сообщение #1





Группа: Новичок
Сообщений: 4
Регистрация: 11-08-18
Из: Санкт-Петербург
Пользователь №: 106 717



Всем привет!
Осваиваюсь с Verilog и с ПЛИС. Возник вопрос по работе оператора CASE.
Значение регистра dig в приведённом коде должно(в моём понимании) становиться становиться 4'b0010, либо 4'b1000, либо 4'b0001 и должно меняться в трёх случаях:
когда значение disp_dat становится 0, 1 или 4.
На деле же оно меняется и тогда, когда disp_dat становится 2 и 5. В этих случаях оно становится 4'b0010 и 4'b1001.
Но у меня даже числа такие нигде в коде не фигурируют. Вопрос: почему dig меняется и в случаях, когда disp_dat становится 2 и 5?

Прилагаю код и скриншот отладки в SignalTap Quartus 2.11
CODE

module sled(seg,dig,clock,disp_dat);
input clock;
output [7:0] seg;
output [3:0] dig;
reg [7:0] seg;
reg [3:0] dig;
output reg [3:0] disp_dat;
reg [36:0] count;


always @ (posedge clock )
begin
count = count + 1'b1;
end

always @ (count[24])
begin
disp_dat = {count[28:25]};
end
always @ (disp_dat)
begin
case (disp_dat)
4'h0 : begin
seg <= 8'hc0; //"0"
dig <= 4'b0010;
end
4'h1 : begin
seg <= 8'hf9; //"1"
dig <= 4'b1000;
end
4'h2 : begin
seg <= 8'ha4; //"2"
end
4'h3 : begin
seg <= 8'hb0; //"3"
end
4'h4 : begin
seg <= 8'h99; //"4"
dig<=4'b0001;
end
4'h5 : seg <= 8'h92; //"5"
4'h6 : seg <= 8'h82; //"6"
4'h7 : seg <= 8'hf8; //"7"
4'h8 : seg <= 8'h80; //"8"
4'h9 : seg <= 8'h90; //"9"
4'ha : seg <= 8'h88; //"a"
4'hb : seg <= 8'h83; //"b"
4'hc : seg <= 8'hc6; //"c"
4'hd : seg <= 8'ha1; //"d"
4'he : seg <= 8'h86; //"e"
4'hf : seg <= 8'h8e; //"f"
endcase

end
endmodule




Сообщение отредактировал jurist - Aug 11 2018, 19:55
Go to the top of the page
 
+Quote Post
eugen_pcad_ru
сообщение Aug 12 2018, 03:52
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 641
Регистрация: 15-11-07
Пользователь №: 32 353



Дефолтного значения не увидел... его нет?


--------------------
Правильно сформулированый вопрос содержит в себе половину ответа.
P.S.: Некоторые модераторы в качестве ответа так навязчиво предлагают посетить свой сайт, что иначе как саморекламу такие действия интерпретировать сложно.
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Aug 12 2018, 07:01
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 972
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(jurist @ Aug 11 2018, 22:53) *
Код
always @ (count[24])
begin
disp_dat = {count[28:25]};
end

Здесь что-то странное. Что вы хотели тут сделать?
Go to the top of the page
 
+Quote Post
jurist
сообщение Aug 12 2018, 08:53
Сообщение #4





Группа: Новичок
Сообщений: 4
Регистрация: 11-08-18
Из: Санкт-Петербург
Пользователь №: 106 717



eugen_pcad_ru
Значение disp_dat состоит из 4 бит и чисто физически может принимать значения от 0h до Fh. Все 16 состояний у меня описаны и последовательно отрабатываются. Это видно по приложенной к первому сообщению картинке - все значения строго от 0h до Fh.
Я слышал, что в Verylog бывают неопределённые состояния... Даже если предположить, что в disp_dat могло попасть другое значение, оно было бы проигнорировано, т.к. не подходит ни под одно из условий CASE.

Для верности, дописал обработку для значения default, запустил на отладочной плате, но ничего не поменялось.


andrew_b
Каждый раз, когда меняется значение count[24], в disp_dat заносятся 4 бита count[28] - count[25].
Можно заменить count[24] на count[25] или на posedge clock, на конечный результат в данном случае это никак не повлияет.

И ещё, Verilog пишет следующее предупреждение, касательно dig: Warning (13012): Latch dig[0]$latch has unsafe behavior
Нашёл статью по теме: https://marsohod.org/verilog/155-verilogmux
Но всё равно пока не могу понять, как значения могут меняться на самопроизвольные, если я конкретно описал нужные мне случаи и значения?
Go to the top of the page
 
+Quote Post
_4afc_
сообщение Aug 12 2018, 09:41
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 260
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



Мне в этом коде не нравится:
1 в always стоят не клоки
2 входные данные внутри always не зафиксированы на предыдущем такте / полутакте.

CODE

module sled(seg,dig,clock,disp_dat);
input clock;
output [7:0] seg;
output [3:0] dig;
reg [7:0] seg;
reg [3:0] dig;
output reg [3:0] disp_dat;
reg [36:0] count;


always @ (posedge clock ) //count changes on poedge
begin
count = count + 1'b1;
end


always @ (posedge clock ) //disp_dat_CE changes on posedge
begin
disp_dat_CE =...
end

always @ (negedge clock ) //disp_dat changes on negedge
begin
if (disp_dat_CE) disp_dat = {count[28:25]};
end


always @ (negedge clock ) //dseg_dig_CE changes on negedge
begin
dseg_dig_CE = …
end

always @ (posedge clock ) //seg & dig changes on posedge
begin
if (dseg_dig_CE)
case (disp_dat)
4'h0 : begin
seg <= 8'hc0; //"0"
dig <= 4'b0010;
end
4'h1 : begin
seg <= 8'hf9; //"1"
dig <= 4'b1000;
end
4'h2 : begin
seg <= 8'ha4; //"2"
end
4'h3 : begin
seg <= 8'hb0; //"3"
end
4'h4 : begin
seg <= 8'h99; //"4"
dig<=4'b0001;
end
4'h5 : seg <= 8'h92; //"5"
4'h6 : seg <= 8'h82; //"6"
4'h7 : seg <= 8'hf8; //"7"
4'h8 : seg <= 8'h80; //"8"
4'h9 : seg <= 8'h90; //"9"
4'ha : seg <= 8'h88; //"a"
4'hb : seg <= 8'h83; //"b"
4'hc : seg <= 8'hc6; //"c"
4'hd : seg <= 8'ha1; //"d"
4'he : seg <= 8'h86; //"e"
4'hf : seg <= 8'h8e; //"f"
endcase

end
endmodule


пишу по памяти, но идея должна быть понятна...

PS: значение disp_dat_CE должно быть равно 1 или то от чего оно зависит должно меняться на negedge
значение dseg_dig_CE должно быть равно 1 или то от чего оно зависит должно меняться на posedge

Go to the top of the page
 
+Quote Post
iosifk
сообщение Aug 12 2018, 09:51
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 4 006
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(_4afc_ @ Aug 12 2018, 12:41) *
Мне в этом коде не нравится:
1 в always стоят не клоки
2 входные данные внутри always не зафиксированы на предыдущем такте / полутакте.

...

PS: значение disp_dat_CE должно быть равно 1 или то от чего оно зависит должно меняться на negedge
значение dseg_dig_CE должно быть равно 1 или то от чего оно зависит должно меняться на posedge


Т.е. ТС надо почитать о "синхронном проектировании". И о метастабильности... И прочитать, когда в case образуются latch...
Делалась ли RTL симуляция? Или сразу непроверенный код - в железо?


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Aug 12 2018, 09:52
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 972
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(jurist @ Aug 12 2018, 11:53) *
Каждый раз, когда меняется значение count[24], в disp_dat заносятся 4 бита count[28] - count[25].
Каждый раз меняется -- это оба фронта, да? Во-первых, вы заводите на тактовый вход триггера нетактовый сигнал. Это неправильно, в FPGA это не приветствуется. Во-вторых, в FPGA нет триггеров, работающих по обоим фронтам. Вы смотрели результат синтеза, он вас устраивает?
Цитата
Можно заменить [...] на posedge clock
Не можно, а нужно. Гуглите "синхронный дизайн".
Цитата
на конечный результат в данном случае это никак не повлияет.
Тем более.
Go to the top of the page
 
+Quote Post
jurist
сообщение Aug 12 2018, 19:31
Сообщение #8





Группа: Новичок
Сообщений: 4
Регистрация: 11-08-18
Из: Санкт-Петербург
Пользователь №: 106 717



Цитата(_4afc_ @ Aug 12 2018, 09:41) *
Мне в этом коде не нравится:
1 в always стоят не клоки
2 входные данные внутри always не зафиксированы на предыдущем такте / полутакте.

Цитата(andrew_b @ Aug 12 2018, 09:52) *
...... Во-первых, вы заводите на тактовый вход триггера нетактовый сигнал. ...

_4afc_, Идею с программой, к сожалению, не совсем понял, но Вы сказали ключевую фразу. andrew_b тоже указал на это. Спасибо!
Поставил один always с "posedge clock" всё заработало как должно. biggrin.gif
Даже приведу новый код:
CODE
module sled(seg,dig,clock,disp_dat);
input clock;
output [7:0] seg;
output [3:0] dig;
reg [7:0] seg;
reg [3:0] dig;
output reg [3:0] disp_dat;
reg [36:0] count;

always @ (posedge clock )
begin
count = count + 1'b1;
disp_dat = {count[28:25]};

case (disp_dat)
4'h0 : begin
seg <= 8'hc0; //"0"
dig <= 4'b0010;
end
4'h1 : begin
seg <= 8'hf9; //"1"
dig <= 4'b1000;//
end
4'h2 : begin
seg <= 8'ha4; //"2"
end
4'h3 : begin
seg <= 8'hb0; //"3"
end
4'h4 : begin
seg <= 8'h99; //"4"
dig<=4'b0001; //
end
4'h5 : seg <= 8'h92; //"5"
4'h6 : seg <= 8'h82; //"6"
4'h7 : seg <= 8'hf8; //"7"
4'h8 : seg <= 8'h80; //"8"
4'h9 : seg <= 8'h90; //"9"
4'ha : seg <= 8'h88; //"a"
4'hb : seg <= 8'h83; //"b"
4'hc : seg <= 8'hc6; //"c"
4'hd : seg <= 8'ha1; //"d"
4'he : seg <= 8'h86; //"e"
4'hf : seg <= 8'h8e; //"f"
endcase
end
endmodule
Программа была из набора примеров для отладочной платы, а я решил с ней поковыряться. Думал, что примеры пишут более подготовленные люди.

Цитата(iosifk @ Aug 12 2018, 09:51) *
Т.е. ТС надо почитать о "синхронном проектировании". И о метастабильности... И прочитать, когда в case образуются latch...
Делалась ли RTL симуляция? Или сразу непроверенный код - в железо?
В RTL Viever смотрел, но мне на данном этапе сложно читать программу в виде логических элементов.

Правило с правильным тактированием я усвоил. Но я ещё не осознал, почему я указываю изменение всех данных строго после изменения disp_dat, а они меняются сами, как попало. Статьи на рекомендованные темы обязательно прочитаю и постараюсь разобраться.
Go to the top of the page
 
+Quote Post
iosifk
сообщение Aug 12 2018, 19:44
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 4 006
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(jurist @ Aug 12 2018, 22:31) *
В RTL Viever смотрел, но мне на данном этапе сложно читать программу в виде логических элементов.

Я спрашивал не о " RTL Viever", а о RTL-симуляции. Это совершенно разные вещи...


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
_4afc_
сообщение Aug 13 2018, 10:39
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 260
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



Цитата(jurist @ Aug 12 2018, 23:31) *
_4afc_, Идею с программой, к сожалению, не совсем понял, но Вы сказали ключевую фразу. andrew_b тоже указал на это. Спасибо!
Поставил один always с "posedge clock" всё заработало как должно. biggrin.gif


Если у вас будет 1 always и вместо <= вы будете писать =, то безусловно синтаксис верилога приблизится к си и всё будет работать.

Только:
1 очень медленно
2 такой стиль не приблизит вас к освоению верилог и ПЛИС

Go to the top of the page
 
+Quote Post
jurist
сообщение Aug 13 2018, 19:47
Сообщение #11





Группа: Новичок
Сообщений: 4
Регистрация: 11-08-18
Из: Санкт-Петербург
Пользователь №: 106 717



Цитата(iosifk @ Aug 12 2018, 19:44) *
Я спрашивал не о " RTL Viever", а о RTL-симуляции. Это совершенно разные вещи...
До симуляторов ещё не добрался.

Цитата(_4afc_ @ Aug 13 2018, 10:39) *
Если у вас будет 1 always и вместо <= вы будете писать =, то безусловно синтаксис верилога приблизится к си и всё будет работать.

Только:
1 очень медленно
2 такой стиль не приблизит вас к освоению верилог и ПЛИС
_4afc_, благодарю за грамотные советы!
Go to the top of the page
 
+Quote Post
iosifk
сообщение Aug 13 2018, 20:00
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 4 006
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(jurist @ Aug 13 2018, 22:47) *
До симуляторов ещё не добрался.

Тут можно сказать только одно.
ПЛИС - это не микроконтроллер. Тут совсем другая технология. Без симуляции вообще нет смысла браться за стартовый набор. Мало того, верилог - это не программа, это описание железа. И оно тоже делается не так, как программа. Другим методом. Если хотите, то могу об этом рассказать по скайпу. Мне так будет проще.


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th September 2018 - 01:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.00921 секунд с 7
ELECTRONIX ©2004-2016