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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Тернарный оператор VS конструкция if-else, Какова логика языка? Почему одно не заменяет другое?
flammmable
сообщение Jun 7 2018, 06:53
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 4-06-18
Пользователь №: 104 848



Предположим, есть конечный автомат, который в работе должен пробрасывать тактовую частоту через себя, а в состоянии IDLE установить выход тактовой частоты в единицу.

Тогда код может быть следующий:
Код
wire clk_in;
wire clk_out;
reg state;

assign clk_out = clk_in | ~(state^IDLE);

Т.е. если state и IDLE совпадают бит-в-бит, то их побитовый XOR будет равен нулю. Инвертированный ноль - это единица. Единица или clk_in - единица. В противном случае, ноль или clk_in - это clk_in.
Всё абсолютно прозрачно синтезируется.

Или код может быть такой:
Код
wire clk_in;
wire clk_out;
reg state;

assign clk_out = clk_in | (state == IDLE);//На месте синтезатора я заменил бы данную конструкцию на предыдущую


Или такой:
Код
wire clk_in;
wire clk_out;
reg state;

assign clk_out =(state == IDLE) ? 1 : clk_in;


Но почему не прокатывает следующий вариант?
Код
wire clk_in;
wire clk_out;
reg state;

always @(state)
begin
if(state == IDLE) begin
  clk_out = 1;
end
else begin
  clk_out = clk_in;
end
end

В таком варианте Квартус ругается на то, что "10137: Object on left-hand side of assignment must have a variable data type".

Не, ну нельзя, так - нельзя. Но эмм... в списке чувствительности отсутствуют posedge/negedge. В любом случае, синтезатор будет разворачивать эту конструкцию в комбинационную логику (причем, скорее всего в такую, как в первом примере). Так чего же он лезет на рожон (регистр ему подавай)? Какова логика языка? Почему так писать некорректно?

Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Jun 7 2018, 07:20
Сообщение #2


В поисках себя...
****

Группа: Свой
Сообщений: 698
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(flammmable @ Jun 7 2018, 09:53) *

1. Я бы вообще никаких манипуляций с частотой не производил.
2. Если уж так нужно, обратите внимание на: altera clkctrl
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Jun 7 2018, 08:05
Сообщение #3


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

Группа: Свой
Сообщений: 1 182
Регистрация: 23-12-04
Пользователь №: 1 643



Приветсвую!

Цитата(flammmable @ Jun 7 2018, 09:53) *
...
...
Но почему не прокатывает следующий вариант?
Код
wire clk_in;
wire clk_out;
reg state;

always @(state)
...
  clk_out = clk_in;
...
end

В таком варианте Квартус ругается на то, что "10137: Object on left-hand side of assignment must have a variable data type".

Не, ну нельзя, так - нельзя. Но эмм... в списке чувствительности отсутствуют posedge/negedge. В любом случае, синтезатор будет разворачивать эту конструкцию в комбинационную логику (причем, скорее всего в такую, как в первом примере). Так чего же он лезет на рожон (регистр ему подавай)? Какова логика языка? Почему так писать некорректно?
Это не Квартус лезет на рожон скорее это Вы пристаете к синтезатору с классическим вопросом "...Закурить найдется?" sm.gif А он Вам вежливо - не курю не могу присвоить значение переменной типа wire в процедурном блоке. Для wire допустимо использование только assign (так пацаны на сходке решили еще аж 1995 году). Если Вы смелы то объявите
Код
reg clk_out;
Тогда Квартус примет Вас за своего и получите сигаретку назначение переменной в процедурном блоке wink.gif

Удачи! Rob.
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jun 7 2018, 08:14
Сообщение #4


Гуру
******

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



Цитата(Flip-fl0p @ Jun 7 2018, 10:20) *
1. Я бы вообще никаких манипуляций с частотой не производил.
2. Если уж так нужно, обратите внимание на: altera clkctrl

Без обид.
Смотрите внимательно, то что я напишу.
Для одних - ПЛИС это кусок хлеба. И форум - это товарищи, которые помогают начать прилично зарабатывать. Поэтому их советы ценятся. Потому что на работе надо давать результат, иначе не будет зарплаты, причем результат нужен каждый день, а не когда-то потом. И я помню, что сам был в такой же ситуации. До этого я писал на VHDL, пришел на новую работу и там сказали - только Verilog. И я учился "в бою". И мне абсолютно некогда было "изобретать художества". Брал проверенные шаблоны и из них делал код, в том числе и по выходным, чтобы успеть.
А для других ПЛИС - это игра. Им результат как таковой не нужен. Они "проводят изыскания" в кусках кода, в "триггерах, нарисованных вьюерами" и т.д. Им советы, выдаваемые на форуме вроде как и нужны, но они все равно все сделают по-своему, "через Альпы".
Вот так и здесь. Есть основы:
клоки не изобретать и проект делать синхронным;
"внутри автоматов не плодить счетчики и не делать клоки.

И это написано практически во всех руководствах. Ну и что? Это же так интересно, написать что-то принципиально "свое", а потом задавать об этом вопросы на форуме. Чтобы все, кто готов помочь, бросились объяснять очевидные вещи.
Беда в том, что правильный ответ игруну вообще не нужен, потому что он быстро приводит к правильному результату. Тут как раз все надо делать все совершенно наоборот. Надо дать ссылку на кучу литературы, на методики, на головоломные статьи. Так чтобы до результата стало как можно дальше. Тогда игрун ощутит себя бесконечно крутым.
Вот как-то так....


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Jun 7 2018, 08:22
Сообщение #5


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

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



Цитата(flammmable @ Jun 7 2018, 09:53) *
Предположим, есть конечный автомат, который в работе должен пробрасывать тактовую частоту через себя, а в состоянии IDLE установить выход тактовой частоты в единицу.

Тогда код может быть следующий:
Код
wire clk_in;
wire clk_out;
reg state;

assign clk_out = clk_in | ~(state^IDLE);

Т.е. если state и IDLE совпадают бит-в-бит, то их побитовый XOR будет равен нулю. Инвертированный ноль - это единица. Единица или clk_in - единица. В противном случае, ноль или clk_in - это clk_in.
Это в идеале. IRL из-за всяких задержек вы получите на clk_out хороший такой дребезг. Нельзя просто так взять и смешать клок с обычным сигналом, тем более многоразрядным.

Цитата
Но эмм... в списке чувствительности отсутствуют posedge/negedge. В любом случае, синтезатор будет разворачивать эту конструкцию в комбинационную логику (причем, скорее всего в такую, как в первом примере). Так чего же он лезет на рожон (регистр ему подавай)? Какова логика языка? Почему так писать некорректно?
Про разницу reg/wire вам уже сказали. Добавлю, что если в always описывается комбинационная схема, в списке чувствительности должны присутствовать все сигналы, от которых зависит выход. У вас там не хватает clk_in, поэтому вы получите не комбинационную схему, а latch.
Go to the top of the page
 
+Quote Post
flammmable
сообщение Jun 7 2018, 10:32
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 4-06-18
Пользователь №: 104 848



Цитата(Flip-fl0p @ Jun 7 2018, 10:20) *
1. Я бы вообще никаких манипуляций с частотой не производил.

Конкретная задача. FPGA соединена с PC при помощи моста "USB - что_угодно" FT2232H, который способен работать в режиме асинхронного FIFO. У моста есть два буфера - TX и RX. Для передачи данных в FPGA мосту надо стробировать nRD. Для отправки на PC (и захвата данных во входной буфер) этому мосту надо стробировать nWR. Правильнее было бы описать дергание стробов в состояниях конечного автомата?

Цитата(RobFPGA @ Jun 7 2018, 11:05) *
Приветсвую!

Это не Квартус лезет на рожон скорее это Вы пристаете к синтезатору с классическим вопросом "...Закурить найдется?" sm.gif А он Вам вежливо - не курю не могу присвоить значение переменной типа wire в процедурном блоке. Для wire допустимо использование только assign (так пацаны на сходке решили еще аж 1995 году). Если Вы смелы то объявите
Код
reg clk_out;
Тогда Квартус примет Вас за своего и получите сигаретку назначение переменной в процедурном блоке wink.gif

Удачи! Rob.

Добрый день!
Про то, что с доп.регистром всё заработает - это да. Только этот же регистр всё равно не синтезируется. Всё сведется к XOR-у + лог.ИЛИ (как в первом примере). И это понятно по отсутствию posedge/negedge в списке чувствительности. Чем руководствовались пацаны в 1995 году, когда так договаривались? От чего они пытались оградить программистов? Не собираются ли пацаны выпустить новый стандарт? Ибо тернарный оператор выглядит костылеобразно (не круто).
Спасибо!

Цитата(andrew_b @ Jun 7 2018, 11:22) *
Это в идеале. IRL из-за всяких задержек вы получите на clk_out хороший такой дребезг. Нельзя просто так взять и смешать клок с обычным сигналом, тем более многоразрядным.

Спасибо за ценное замечание. Действительно, если клок управляется значением шины hAA и шина переключается из состояния h0F в hF0 не синхронно а как бы по пути h0F->h0A->hAA->hA0->hF0 может произойти неприятное.

Цитата(andrew_b @ Jun 7 2018, 11:22) *
Добавлю, что если в always описывается комбинационная схема, в списке чувствительности должны присутствовать все сигналы, от которых зависит выход. У вас там не хватает clk_in, поэтому вы получите не комбинационную схему, а latch.

Точно. Ну в любом случае синтезатор не даст такой синтаксической конструкции собраться.

Цитата(iosifk @ Jun 7 2018, 11:14) *
Без обид.

Без обид, разумеется.
Ув.iosifk мне кажется есть два (как минимум) случая, когда "ориентированность на результат" приведет к негативным последствиям:
1. Конструкция языка/библиотеки/устройства претерпела изменения за последнее время (или такое изменение напрашивается в ближайшем будущем).
Пример: инициализация регистров при запуске ПЛИС "в железе". На сколько понял читая материалы в сети, в 90-е регистры инициализировались исключительно нулями. Сейчас ситуация поменялась, но ряд комментаторов по старой памяти утверждают, что это невозможно и сами не используют эту удобную опцию.
2. Хрестоматийный пример, на который нужно равняться, содержит незаметную ошибку.
Пример: в LabVIEW есть пример работы с высокоскоростными модулями HSDIO. Коротко, работа с HSDIO представляет последовательность Init->Transmit/Receive->Close. Но Close может быть двух типов - "Закрыть по завершении Transmit/Receive" и "Закрыть немедленно". Так вот в официальном примере использовано "Закрыть немедленно". HSDIO в режиме Transmit/Receive работает автономно от PC и обычно гораздо быстрее. Так что программы на основе примера работают корректно. Но если забить буфер HSDIO под завязку, и выставить частоту работы по минимуму, "хвост" передачи будет обрублен. Причем без каких-либо эксепшенов.

Таким образом, если времени нет, разумеется приходится "ориентироваться на результат". Но если оно есть, почему бы не выяснить как именно работает тот или иной подход и почему именно так.

Кроме того есть замечательное руководство "Как правильно задавать вопросы на технических ресурсах". Надеюсь я правильно истолковываю данный кодекс, полагая что вопрос в духе "вот моя плата на 100 микросхем, вот мой код на 10.000 строк, тут что-то не работает" хуже, чем вопрос "Вот три строчки кода, которые не работают. Вот стремный воркэраунд на десять строчек, который работает. Можно ли написать красивее и правильнее?". И если у меня возникает вопрос первого типа, его нужно свести к вопросу второго типа и только потом обращаться за помощью.

Сообщение отредактировал flammmable - Jun 7 2018, 11:27
Go to the top of the page
 
+Quote Post
Dantist2k17
сообщение Jun 7 2018, 11:30
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 30-11-17
Пользователь №: 100 439



Цитата
Но почему не прокатывает следующий вариант?
Код
wire clk_in;
wire clk_out;
reg state;

always @(state)
begin
if(state == IDLE) begin
  clk_out = 1;
end
else begin
  clk_out = clk_in;
end
end

В таком варианте Квартус ругается на то, что "10137: Object on left-hand side of assignment must have a variable data type".

Все что формируется в блоке always, не зависимо от того, что вы хотите видеть после синтеза (последовательностный элемент или комбинационный) должно быть типа reg.
А вообще вы описали защелку (latch). Я бы тоже с клоками не баловался подобным образом, но если уж на то пошло, то:
Код
wire clk_in;
reg clk_out;
reg state;

always @(*)
begin
if(state == IDLE) begin
  clk_out = 1;
end
else begin
  clk_out = clk_in;
end
end


-----------------------------------------------------------------------------
Упс, повторяюсь за выше отписавшимися...

Сообщение отредактировал Dantist2k17 - Jun 7 2018, 11:36
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jun 7 2018, 11:45
Сообщение #8


Гуру
******

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



Цитата(flammmable @ Jun 7 2018, 13:32) *
Конкретная задача. FPGA соединена с PC при помощи моста "USB - что_угодно" FT2232H, который способен работать в режиме асинхронного FIFO. У моста есть два буфера - TX и RX. Для передачи данных в FPGA мосту надо стробировать nRD. Для отправки на PC (и захвата данных во входной буфер) этому мосту надо стробировать nWR. Правильнее было бы описать дергание стробов в состояниях конечного автомата?

Таким образом, если времени нет, разумеется приходится "ориентироваться на результат". Но если оно есть, почему бы не выяснить как именно работает тот или иной подход и почему именно так.


Для начала - http://www.sunburst-design.com/
Ищем статьи отцов-основателей.
Вот здесь: http://www.sunburst-design.com/papers/
И если поискать, то найдете, что когда пишите assert, то это для wire... А когда есть события - на которые указывает "@", то это все в основном для регистров.
Если Вы знаете, что такое "автомат", то попробуйте представить себе набор автоматов - мастер-слэйв-слэйв. Нижний работает только на уровне бита при последовательной передаче или слова при параллельной. Средний - передает слова или кадры. А верхний - сообщения, которые могут состоять из нескольких кадров.
Причем "внутри" описания автомата я не рекомендую врезать какие-либо счетчики или что-то еще. Автомат должен только лишь выдавать стробы для управления всеми другими узлами.
Что еще? Основной "подход" - это не тонкости описания, а именно то, как Вы строите архитектуру вычислительного узла. Вот скажем проблема со стробами nWR Вас интересует, а протокол передачи данных по линии связи видимо пока еще нет. А парсер протокола делать будете?


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Jun 7 2018, 12:16
Сообщение #9


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

Группа: Свой
Сообщений: 1 182
Регистрация: 23-12-04
Пользователь №: 1 643



Приветсвую!
Цитата(flammmable @ Jun 7 2018, 13:32) *
Про то, что с доп.регистром всё заработает - это да. Только этот же регистр всё равно не синтезируется. Всё сведется к XOR-у + лог.ИЛИ (как в первом примере).
Увы тип reg ввоодит в заблуждение - переменная этого типа не всегда синтезируется в регистр как многие ожидают от названия. Это зависит где и как Вы работаете с этой переменной.
Цитата(flammmable @ Jun 7 2018, 13:32) *
И это понятно по отсутствию posedge/negedge в списке чувствительности. Чем руководствовались пацаны в 1995 году, когда так договаривались? От чего они пытались оградить программистов? Не собираются ли пацаны выпустить новый стандарт? Ибо тернарный оператор выглядит костылеобразно (не круто).
Пацаны руководствовались тем что было - бригада собралась молодая, дерзкая, но ума/силенок на первых порах не хватало - приходилось отбиваться от банды с соседнего VHDL двора. maniac.gif
Сейчас уже поумнев добавили возможность разработчикам использовать always @(*) или даже always_comb. A чтобы не путать неокрепшие умы молодой братвы вместо reg использовать bit или logic. Но тернарный оператор не обижайте! - я за него "...пасть порву, моргалы выколю ..." ®Доцент sm.gif

Главное в любой разработке (а не только для FPGA) это не тупое использование чьих-то шаблонов для заработка куска хлеба
а старание понять почему и для чего они сделаны. От чего зависит применении тех или иных конструкций языка. Во что это выливается в конкретном симуляторе/синтезаторе/железе. И Ваше желание разобраться в этом похвально. Тогда со временем сможете намазать чем то FPGAшный кусок хлеба ну или сами начнете писать тупые шаблоны для других wink.gif.

Удачи! Rob.
Go to the top of the page
 
+Quote Post
flammmable
сообщение Jun 7 2018, 12:26
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 4-06-18
Пользователь №: 104 848



Цитата(iosifk @ Jun 7 2018, 14:45) *
Для начала - http://www.sunburst-design.com/
Ищем статьи отцов-основателей.
Вот здесь: http://www.sunburst-design.com/papers/
И если поискать, то найдете, что когда пишите assert, то это для wire... А когда есть события - на которые указывает "@", то это все в основном для регистров.
Если Вы знаете, что такое "автомат", то попробуйте представить себе набор автоматов - мастер-слэйв-слэйв. Нижний работает только на уровне бита при последовательной передаче или слова при параллельной. Средний - передает слова или кадры. А верхний - сообщения, которые могут состоять из нескольких кадров.
Причем "внутри" описания автомата я не рекомендую врезать какие-либо счетчики или что-то еще. Автомат должен только лишь выдавать стробы для управления всеми другими узлами.
Что еще? Основной "подход" - это не тонкости описания, а именно то, как Вы строите архитектуру вычислительного узла. Вот скажем проблема со стробами nWR Вас интересует, а протокол передачи данных по линии связи видимо пока еще нет. А парсер протокола делать будете?

Т.к. я пишу и клиентскую часть и прошивку для FPGA, то протокол могу менять сам, подстраивая его под возможности и ограничения оборудования. Процесс итеративен - я смотрю что можно "выжать" из LabVIEW, FT2232H и MAX-10 по максимуму. И как это правильнее сделать, что бы это не был "write only code".
Огромное спасибо, ув.iosifk за Ваши советы!

Go to the top of the page
 
+Quote Post
iosifk
сообщение Jun 7 2018, 12:30
Сообщение #11


Гуру
******

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



Цитата(flammmable @ Jun 7 2018, 15:26) *
Т.к. я пишу и клиентскую часть и прошивку для FPGA, то протокол могу менять сам, подстраивая его под возможности и ограничения оборудования. Процесс итеративен - я смотрю что можно "выжать" из LabVIEW, FT2232H и MAX-10 по максимуму. И как это правильнее сделать, что бы это не был "write only code".
Огромное спасибо, ув.iosifk за Ваши советы!

Тогда вот

Прикрепленные файлы
Прикрепленный файл  wave_gen_ver_v6.zip ( 416.35 килобайт ) Кол-во скачиваний: 22
 


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
flammmable
сообщение Jun 7 2018, 15:17
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 4-06-18
Пользователь №: 104 848



Цитата(iosifk @ Jun 7 2018, 15:30) *
Тогда вот

О!! Большое спасибо.
Go to the top of the page
 
+Quote Post
Viktuar
сообщение Jun 7 2018, 17:27
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 18-12-16
Пользователь №: 94 676



Цитата(iosifk @ Jun 7 2018, 09:14) *
Вот так и здесь. Есть основы:
клоки не изобретать и проект делать синхронным;
"внутри автоматов не плодить счетчики и не делать клоки.


Простите, а что плохого в счетчиках внутри автоматов?


Цитата(flammmable @ Jun 7 2018, 11:32) *
инициализация регистров при запуске ПЛИС "в железе". На сколько понял читая материалы в сети, в 90-е регистры инициализировались исключительно нулями. Сейчас ситуация поменялась, но ряд комментаторов по старой памяти утверждают, что это невозможно и сами не используют эту удобную опцию.

Я сам с Альтерой не работал, но слышал, что там до сих пор инициализация только нулями. У lattice тоже не у всех семейств поддерживается инициализация.
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jun 7 2018, 18:18
Сообщение #14


Гуру
******

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



Цитата(Viktuar @ Jun 7 2018, 20:27) *
Простите, а что плохого в счетчиках внутри автоматов?

Синхронный проект должен работать по клокам.
Если Вы из автомата даете только одиин сигнал разрешения, то счетчик и будет работать по клокам. И по разрядам счетчика разойдется только один сигнал...
А если при описании автомата, Вы запихиваете счетчик "внутрь" комбинационной части, то что будет подано на тактовые входы счетчика? Но даже если компилятор сообразит подать туда клоки, то все равно, к комбинационной части добавятся еще N разрядов счетчика. И все это надо будет уложить в период тактовой частоты.
Поэтому я так стараюсь никогда не делать.
Вообще, примите методу проектирования, когда автомат только роздает управляющие воздействия и более ничего.
И тогда проект становится значительно легче. Вы делаете "исполнительные узлы" и потом в нужные моменты времени автоматом только даете управляющие воздействия.
Если хотите, то могу росказать подробнее.


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Jun 7 2018, 18:39
Сообщение #15


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

Группа: Свой
Сообщений: 1 182
Регистрация: 23-12-04
Пользователь №: 1 643



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

Цитата(iosifk @ Jun 7 2018, 21:18) *
Синхронный проект должен работать по клокам.
Если Вы из автомата даете только одиин сигнал разрешения, то счетчик и будет работать по клокам. И по разрядам счетчика разойдется только один сигнал...
А если при описании автомата, Вы запихиваете счетчик "внутрь" комбинационной части, то что будет подано на тактовые входы счетчика? Но даже если компилятор сообразит подать туда клоки, то все равно, к комбинационной части добавятся еще N разрядов счетчика. И все это надо будет уложить в период тактовой частоты.
Поэтому я так стараюсь никогда не делать.

Простите но это просто глупость - Вы действительно считаете что счетчик описанный в FSM будет по другому синтезирован чем счетчик описанный вне FSM? Может приведете примеры такого "безобразия" ?

Успехов! Rob.



Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th August 2018 - 12:19
Рейтинг@Mail.ru


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