|
Тернарный оператор VS конструкция if-else, Какова логика языка? Почему одно не заменяет другое? |
|
|
|
Jun 7 2018, 06:53
|
Участник

Группа: Участник
Сообщений: 30
Регистрация: 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. В любом случае, синтезатор будет разворачивать эту конструкцию в комбинационную логику (причем, скорее всего в такую, как в первом примере). Так чего же он лезет на рожон (регистр ему подавай)? Какова логика языка? Почему так писать некорректно?
|
|
|
|
|
 |
Ответов
|
Jun 8 2018, 10:20
|
Частый гость
 
Группа: Свой
Сообщений: 134
Регистрация: 9-11-12
Из: г. Брянск
Пользователь №: 74 311

|
Ну вот такой теоретический пример CODE module cnt_test ( //Global input CLK_i , input nRESET_i ,
//Input input IN_PULSE0_i , input IN_PULSE1_i ,
//Control input ENA_CNT_i , input CLR_CNT_i ,
//Output of counter output [31:0] OUT_CNT0_o32 , output [31:0] OUT_CNT1_o32 );
reg [31:0] out_cnt0_o32; reg [31:0] out_cnt1_o32; assign OUT_CNT0_o32 = out_cnt0_o32; assign OUT_CNT1_o32 = out_cnt1_o32;
reg [7:0] state; //FSM localparam integer sIDLE = 0, sCOUNT = 1, sSTOP = 2;
reg cnt_1_en; reg cnt_1_clr;
always @(posedge CLK_i or negedge nRESET_i) begin if(~nRESET_i) begin out_cnt0_o32 <= 0; cnt_1_en <= 0; cnt_1_clr <= 0; state <= sIDLE; end else begin case(state)
sIDLE: begin cnt_1_clr <= 0; if(ENA_CNT_i) state <= sCOUNT; end
sCOUNT: begin if(ENA_CNT_i) begin if(IN_PULSE_i) begin out_cnt0_o32 <= out_cnt0_o32 + 1'b1; cnt_1_en <= 1'b1; end else cnt_1_en <= 0; end else begin cnt_1_en <= 0; state <= sSTOP; end end
sSTOP: begin state <= sIDLE; if(CLR_CNT_i) begin out_cnt0_o32 <= 0; cnt_1_clr <= 1'b1; end end
endcase end
end
always @(posedge CLK_i or negedge nRESET_i) begin if(~nRESET_i) begin out_cnt1_o32 <= 0; end else begin if(cnt_1_en) out_cnt1_o32 <= out_cnt1_o32 + 1'b1; else if(cnt_1_clr) out_cnt1_o32 <= 0; end end
endmodule Два счетчика. Один работает напрямую из автомата, второй через сигналы разрешения и сброса. Насчет упрощения кода при выносе счетчика из автомата я ошибся - проще не получилось. Для работы встроенного счетчика достаточно всего двух строк. Выносного счетчика - целых 5. Вынос счетчика усложнил код. Плюс на выносной счетчик будет работать с задержкой в один такт. И это надо учитывать там, где критично. Но с точки зрения времянок выносной счетчик выиграет. Как раз за счет промежуточных триггеров на сигналах разрешения/сброса. На практике я это не проверял, это просто рассуждения. Warning from admin: Используйте codebox для оформления длинных блоков кода. Не загромождайте сообщения!
Сообщение отредактировал makc - Jun 8 2018, 10:27
Причина редактирования: предупреждение про codebox
|
|
|
|
|
Jun 8 2018, 10:50
|

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

|
Цитата(dima32rus @ Jun 8 2018, 13:20)  Да собственно с точки зрения синтезатора - ему без разницы где счетчик описан. Внутри FSM, или снаружи. Лично проверял когда только-только начинал изучать FPGA. Выдача сигнала разрешения автоматом, либо счет счетчика в каком-то из состояний синтезируются в одно и тоже. Тут дело в другом, как я считаю. При стиле описания "все в одном": 1. Легче допустить ошибку в описании счетчика - и сложнее её обнаружить. 2. Увеличивается количество строк кода, что неизменно ухудшает его читаемость. Да и документировать такой код становится несколько сложнее. А документирование кода очень, и очень важная составляющая HDL проектов. 3. Увеличивается время отладки. Ибо чем больше строк в коде - тем дольше этот код отлаживать. При стиле описания "Автомат управляет счетчиком": 1. Легче описывать автомат, т.е нет необходимости описывать счетчики. Счетчик пишется один раз, и далее используется повторно. 2. Упрощается автомат - банально меньше писанины. И вместо инкрементирования счетчика внутри автомата - автомат выдает сигнал разрешения работы счетчику. 3. Упрощается тестирование - не работает счтчик, значит проблема в автомате. Проще найти ошибку. 4. Отдельному описанию счетчика можно задать кучу параметров: остановка счета при максимальном значении, максимальное значение счета, направление счета, вывод своего состояния на консоль и пр. И главное - счетчик описан один раз, и дальше повторно используется, и совершенствуется добавлением новых параметров. При таком подходе - мы имеем собственную проверенную библиотеку, которая имеет 100% работоспособность. И из этой библиотеки мы собираем свои проекты как из конструктора. За счет всевозможных настроек имеем большую гибкость, и уменьшение вероятности совершить "глупую" ошибку, которую, как правило, найти сложнее всего. Я от такого подхода вижу только полюсы. Цитата И это еще простой случай - а если еще надо загружать разные счетчики разными значениями и считать их вверх/вниз/поперек? wacko.gif Обычный счетчик с синхронной загрузкой, и сигналом разрешения загрузки. Автомат выдает сигнал разрешения загрузки и выдает данные, которые надо загрузить.
|
|
|
|
|
Jun 8 2018, 11:30
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую! Цитата(Flip-fl0p @ Jun 8 2018, 13:50)  Обычный счетчик с синхронной загрузкой, и сигналом разрешения загрузки. Автомат выдает сигнал разрешения загрузки и выдает данные, которые надо загрузить.  Ну и прикинте во что это выливается со внешним счетчиком. Фактически в автомате Вы сделаете все кроме непосредственного инкремента. А если считать надо не на +/-1 ? В общем случае для счетчика нужно 4 сигнала управления - set, set_value, count, count_value. Получается: Цитата(Flip-fl0p @ Jun 8 2018, 13:50)  Тут дело в другом, как я считаю. При стиле описания "все в одном": 1. Легче допустить ошибку в описании счетчика - и сложнее её обнаружить. 2. Увеличивается количество строк кода, что неизменно ухудшает его читаемость. Да и документировать такой код становится несколько сложнее. А документирование кода очень, и очень важная составляющая HDL проектов. 3. Увеличивается время отладки. Ибо чем больше строк в коде - тем дольше этот код отлаживать. Встроенный счетчик в FSM 2 линий для переменных cnt_cur, cnt_next 2 линий для сброса и cnt_cur<=cnt_next 1 линии начале FSM (default value) cnt_next <= cnt_cur 1 линия в каждой ветви где счетчиком надо управлять. Цитата(Flip-fl0p @ Jun 8 2018, 13:50)  При стиле описания "Автомат управляет счетчиком": 1. Легче описывать автомат, т.е нет необходимости описывать счетчики. Счетчик пишется один раз, и далее используется повторно. 2. Упрощается автомат - банально меньше писанины. И вместо инкрементирования счетчика внутри автомата - автомат выдает сигнал разрешения работы счетчику. При раздельном описании 9 линий кода для инстацирования модуля счетчика, 5 линии кода для описания сигналов управления, и собственно счетчика 4 линии для сигналов управления в начале FSM (default value) 2 (в среднем) линии для сигналов управления в каждой ветви где счетчиком надо управлять. Интересная экономия на размере кода получается  Цитата(Flip-fl0p @ Jun 8 2018, 13:50)  . Отдельному описанию счетчика можно задать кучу параметров: остановка счета при максимальном значении, максимальное значение счета, направление счета, вывод своего состояния на консоль и пр. И главное - счетчик описан один раз, и дальше повторно используется, и совершенствуется добавлением новых параметров. Это из другой оперы - тут счетчик полностью управляется FSM и не может считать как ему хочется. Удачи! Rob.
|
|
|
|
|
Jun 8 2018, 11:49
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую! Цитата(Flip-fl0p @ Jun 8 2018, 14:39)  Экономия получается на отладке в Modelsim...., которая занимает ~80% времени. На чем именно экономия? Ведь отлаживать Вы будете генерацию сигналов управления в FSM точно так же. А кода при этом как минимум в 2 раза больше. Удачи! Rob.
|
|
|
|
|
Jun 8 2018, 12:08
|

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

|
Цитата(RobFPGA @ Jun 8 2018, 14:49)  .... При раздельном описании 9 линий кода для инстацирования модуля счетчика, 5 линии кода для описания сигналов управления, и собственно счетчика 4 линии для сигналов управления в начале FSM (default value) 2 (в среднем) линии для сигналов управления в каждой ветви где счетчиком надо управлять. .... Приветствую! На чем именно экономия? Ведь отлаживать Вы будете генерацию сигналов управления в FSM точно так же. А кода при этом как минимум в 2 раза больше. Удачи! Rob. Вот только мы экономим не строчки кода, а время. И из всех строчек кода мы фактически должны проверить только сигналы управления счетчиком. Ибо все остальное было проверено и отлажено ранее. Если взять счетчик с сигналом разрешения работы, и синхронной загрузкой мы в FSM формируем только эти сигналы, ну возможно ещё данные, которые загружаем в счетчик, соответственно и проверяем только их. Остальное мы отладили раньше. А если в счетчике есть параметр вывода его значения на консоль - то мы можем вообще смотреть в консоли то что выдает счетчик. Или вообще писать все это добро в файл. И включать этот режим очень быстро и просто - в настройках модуля. А вообще спор ни о чем. Каждый делает так, как считает правильным . Ибо так как правильно зависит от личного опыта, и субъективного взгляда на организацию HDL проектов.
|
|
|
|
Сообщений в этой теме
flammmable Тернарный оператор VS конструкция if-else Jun 7 2018, 06:53 Flip-fl0p Цитата(flammmable @ Jun 7 2018, 09:53)
1... Jun 7 2018, 07:20 iosifk Цитата(Flip-fl0p @ Jun 7 2018, 10:20... Jun 7 2018, 08:14  flammmable Цитата(Flip-fl0p @ Jun 7 2018, 10:20... Jun 7 2018, 10:32   iosifk Цитата(flammmable @ Jun 7 2018, 13:32) Ко... Jun 7 2018, 11:45    flammmable Цитата(iosifk @ Jun 7 2018, 14:45) Для на... Jun 7 2018, 12:26     iosifk Цитата(flammmable @ Jun 7 2018, 15:26) Т.... Jun 7 2018, 12:30      flammmable Цитата(iosifk @ Jun 7 2018, 15:30) Тогда ... Jun 7 2018, 15:17    flammmable Цитата(iosifk @ Jun 7 2018, 14:45) Если В... Jun 13 2018, 08:31     iosifk Цитата(flammmable @ Jun 13 2018, 11:31) к... Jun 13 2018, 08:49   RobFPGA Приветсвую!
Цитата(flammmable @ Jun 7 201... Jun 7 2018, 12:16   sazh Цитата(flammmable @ Jun 7 2018, 13:32) 1.... Jun 7 2018, 19:20  Viktuar Цитата(iosifk @ Jun 7 2018, 09:14) Вот та... Jun 7 2018, 17:27   iosifk Цитата(Viktuar @ Jun 7 2018, 20:27) Прост... Jun 7 2018, 18:18    RobFPGA Приветствую!
Цитата(iosifk @ Jun 7 2018,... Jun 7 2018, 18:39     Bad0512 Цитата(RobFPGA @ Jun 8 2018, 01:39) Приве... Jun 8 2018, 02:18      flammmable Цитата(Bad0512 @ Jun 8 2018, 05:18) Думаю... Jun 8 2018, 05:31       Bad0512 Цитата(flammmable @ Jun 8 2018, 12:31) Бу... Jun 8 2018, 06:58     dima32rus Цитата(RobFPGA @ Jun 7 2018, 21:39) Прост... Jun 8 2018, 06:43      RobFPGA Приветствую!
Цитата(dima32rus @ Jun 8 20... Jun 8 2018, 08:35 RobFPGA Приветсвую!
Цитата(flammmable @ Jun 7 20... Jun 7 2018, 08:05 andrew_b Цитата(flammmable @ Jun 7 2018, 09:53) Пр... Jun 7 2018, 08:22 Dantist2k17 ЦитатаНо почему не прокатывает следующий вариант?
... Jun 7 2018, 11:30 lembrix Цитата(flammmable @ Jun 7 2018, 13:32) Пр... Jun 8 2018, 07:39 Flip-fl0p Цитата(lembrix @ Jun 8 2018, 10:39)
Я бы... Jun 8 2018, 07:43 RobFPGA Приветствую!
Цитата(dima32rus @ Jun 8 201... Jun 8 2018, 10:48  dima32rus Цитата(RobFPGA @ Jun 8 2018, 13:48) Вот о... Jun 8 2018, 11:06   Flip-fl0p Цитата(dima32rus @ Jun 8 2018, 14:06) Сог... Jun 8 2018, 11:26 dima32rus Переделал модуль. Теперь счетчик, вынесенный из ав... Jun 8 2018, 12:19
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|