|
|
|
Вопрос по работе CASE в Verilog, CASE в Verilog |
|
|
|
Aug 11 2018, 19:53
|
Группа: Новичок
Сообщений: 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
|
|
|
|
|
Aug 12 2018, 08:53
|
Группа: Новичок
Сообщений: 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Но всё равно пока не могу понять, как значения могут меняться на самопроизвольные, если я конкретно описал нужные мне случаи и значения?
|
|
|
|
|
Aug 12 2018, 09:41
|
Профессионал
Группа: Свой
Сообщений: 1 262
Регистрация: 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
|
|
|
|
|
Aug 12 2018, 09:52
|
Профессионал
Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757
|
Цитата(jurist @ Aug 12 2018, 11:53) Каждый раз, когда меняется значение count[24], в disp_dat заносятся 4 бита count[28] - count[25]. Каждый раз меняется -- это оба фронта, да? Во-первых, вы заводите на тактовый вход триггера нетактовый сигнал. Это неправильно, в FPGA это не приветствуется. Во-вторых, в FPGA нет триггеров, работающих по обоим фронтам. Вы смотрели результат синтеза, он вас устраивает? Цитата Можно заменить [...] на posedge clock Не можно, а нужно. Гуглите "синхронный дизайн". Цитата на конечный результат в данном случае это никак не повлияет. Тем более.
|
|
|
|
|
Aug 12 2018, 19:31
|
Группа: Новичок
Сообщений: 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" всё заработало как должно. Даже приведу новый код: 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, а они меняются сами, как попало. Статьи на рекомендованные темы обязательно прочитаю и постараюсь разобраться.
|
|
|
|
|
Aug 13 2018, 10:39
|
Профессионал
Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565
|
Цитата(jurist @ Aug 12 2018, 23:31) _4afc_, Идею с программой, к сожалению, не совсем понял, но Вы сказали ключевую фразу. andrew_b тоже указал на это. Спасибо! Поставил один always с "posedge clock" всё заработало как должно. Если у вас будет 1 always и вместо <= вы будете писать =, то безусловно синтаксис верилога приблизится к си и всё будет работать. Только: 1 очень медленно 2 такой стиль не приблизит вас к освоению верилог и ПЛИС
|
|
|
|
|
Aug 13 2018, 19:47
|
Группа: Новичок
Сообщений: 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_, благодарю за грамотные советы!
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|