Sirko 0 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Задачка пустяковая - начать постижение верилога. По сути - описать сторожевой таймер. Но, блин, не могу даже скомпилить проект. Если "на пальцах", то вот... При отсутствии сигнала Activate, счетчики должны находится в "нулях" и выход Alarm тоже. В рабочем режиме - выход Alarm в нуле до тех пор, пока частота сигнала Charge выше, чем 50 раз за 10 секунд. Пытался и в одном always блоке описать, и в отдельных, но что-то не складывается. module PumpControl( input clk_1Hz, input pump, input activate, output reg alarm ); //------------------------------------------------------------------------------------------- reg [0:7] charge = 8'd0; // Счетчик необходимого кол-ва импульсов с датчика reg [0:3] timer = 4'd0; // Таймер времени ожидания, по истечению которого - авария parameter countMin = 8'd50; // Кол-во импульсов с датчика, меньше которого - появится ошибка parameter waitingTime = 4'd10; // Время, за которое должно появится достаточное кол-во импульсов always @(posedge pump) begin if(!activate || charge >= countMin) begin charge = 8'd0; end else begin charge <= charge + 1'b1; end end wire resetTimer; assign resetTimer = (charge) ? 1'b1 : 1'b0; always @(posedge clk_1Hz or posedge resetTimer) begin if(!activate) begin timer = 4'd0; alarm = 1'b0; end else if(timer < waitingTime) begin timer <= timer + 1'b1; end else if(timer >= waitingTime) begin alarm = 1'b1; end end endmodule Если закоментировать содержимое второго always, то проект собирается. А в чем причина? И как правильно реализовать сброс и синхронно и асинхронно одновременно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
masics 0 15 апреля, 2015 Опубликовано 15 апреля, 2015 · Жалоба Во втором always сигнал resetTimer описан как сброс, но внутри никак не используется. Посмотрите в логах почему компилятор ругается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба И как правильно реализовать сброс и синхронно и асинхронно одновременно? Все асинхронные сигналы управления, перечисленные в always, должны быть в начале блока в условиях if, тогда они станут асинхронными сигналами управления. always @(posedge clk_1Hz or posedge resetTimer) if (resetTimer) begin ... async ... end else begin ... sync ... end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hose 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Ужасный код. Зачем вы используете > и <, вы не уверены что счетчик считает до 50? Зачем разрядность 8 если вы считаете до 50? Иф (цнт==0) Цнт <=49 Елсе Цнт <= цнт - 1 Операция ==0 значительно дешевле <Х Асинхронное формирование сигнала сброса из 8-и разрядного регистра чревато возникновением паразитных фронтов (до 8шт), и ложных фронтов. Правильнее даже сказать они там будут всегда, но быстродействие фпга не позволит отработать большую часть из них. Результат первого счетчика используется для формиования сигнала, который нигде не используется, компилятор его сократил. Во втором счетчике ничего не регулирует регистр таймер. Аларм всегда будет 1. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Вот, как-то так: Промежуточные выходы конца счета сделаны отдельными дополнительными регистрами, чтобы избежать там глитчей. Но, управление от "cnt1Q" я бы сделал асинхронным, так как не уверен, что он будет длиться достаточно, чтобы синхронно сбросить второй счетчик. То есть, схема может быть глючной изначально, по самой схеме. reg [5:0] cnt1; reg [3:0] cnt2; reg Alarm; reg Stop; reg cnt1Q; /* First counter */ always @(posedge Charge or posedge Activate) if (Activate) cnt1 <= 6'd0; else if (Stop || cnt1Q) cnt1 <= 6'd0; else cnt1 <= cnt1 + 1'b1; always @(posedge Charge or posedge Activate) if (Activate) cnt1Q <= 1'b0; else if (Stop) cnt1Q <= 1'b0; else cnt1Q <= (cnt1 == 6'd48); /* Second counter */ always @(posedge clk1hz or posedge Activate) if (Activate) cnt2 <= 4'd0; else if (!Stop) if (cnt1Q) cnt2 <= 4'd0; else cnt2 <= cnt2 + 1'b1; always @(posedge clk1hz or posedge Activate) if (Activate) Stop <= 1'b0; else if (!Stop) Stop <= (cnt2 == 4'd8); /* Alarm */ always @* if (Activate || cnt1Q) Alarm <= 1'b0; else if (Stop) Alarm <= 1'b1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба always @(posedge Charge or posedge Activate) if (Activate) cnt1 <= 6'd0; else if (Stop || cnt1Q) cnt1 <= 6'd0; else cnt1 <= cnt1 + 1'b1; Как же вы пишите компактно блин.... мне кажется ваша страсть экономить заставила вас сэкономить на размере монитора:) always @(posedge Charge or posedge Activate) begin if (Activate) cnt1 <= 6'd0; else if (Stop || cnt1Q) cnt1 <= 6'd0; else cnt1 <= cnt1 + 1'b1; end А еще для ТС хочу добавить что верилог позволяет описывать не только схему, но и поведение. Иногда можно просто описать что хочется, и поглядеть какая из этого получиться схема. Правда многие такой подход отрицают:). Что известно про сигнал charge относительная клока 1 КГц? Потому что по схеме это асинхронные сигналы, и получиться их надо как-то синхронизовать, а то метастабильность, обсурд и коррупция... И еще надо забывать программисткие перестраховки потому что >= жрет ресурсов больше чем ==, i <= 0; ... i <= i + 1; if(i > 5) ... жрет больше чем i <= 5; ... i <= i - 1; if(i == 0) ... много приемчиков как сэкономить лутики.... >7 проверять труднее чем == 8, если последние проверять по тому что появился четвертый бит и от 0 до 7 считать больше ресурсов чем от 1 до 8 в итоге:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба И еще надо забывать программисткие перестраховки потому что >= жрет ресурсов больше чем ==,В машинах состояний такие перестраховки строго обязательны, иначе зависнет. много приемчиков как сэкономить лутики.... >7 проверять труднее чем == 8, если последние проверять по тому что появился четвертый бит и от 0 до 7 считать больше ресурсов чем от 1 до 8 в итоге:)Если мы говорим об экономии лутиков, и сравнение реализовано на лутах, то не всё ли равно, какую функцию над входными битами делать на этих лутах? Если на раскиданных XORах - то другое дело, наверное, не проверял... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба В машинах состояний такие перестраховки строго обязательны, иначе зависнет. С чего вдруг? Это неверно! Если все правильно сделано ничего не зависнет. Даже default не нужен, если исключить помехи... Если мы говорим об экономии лутиков, и сравнение реализовано на лутах, то не всё ли равно, какую функцию над входными битами делать на этих лутах? если сравнение векторов - ЛУТ, если 1 бит, то без ЛУТа... и вопрос числа лутов, если сравнивать 32 битный вектор - много ЛУТов, если 1 бит из него то может и без ЛУТов... так что экономия по любому Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба ничего не зависнет. Даже default не нужен, если исключить помехи...Вот не надо их исключать. Сталкивался с изменением состояния регистров, которые никто не трогал просто от наводки по эфиру. Рядом работал лазер. Всякое бывает. Вопрос вероятности. Я бы обязательно поставил default или аналог. если сравнение векторов - ЛУТ, если 1 бит, то без ЛУТа... и вопрос числа лутов, если сравнивать 32 битный вектор - много ЛУТов, если 1 бит из него то может и без ЛУТов... так что экономия по любомуДак как можно сравнивать на больше однобитный сигнал? Речь идёт о шине. Значит о ЛУТе. Пусть 32-битная шина. Какая разница ЛУТу, какую функцию сравнения делать? У него всё равно таблица. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Вот не надо их исключать. Сталкивался с изменением состояния регистров, которые никто не трогал просто от наводки по эфиру. Рядом работал лазер. Всякое бывает. Вопрос вероятности. Я бы обязательно поставил default или аналог. А вы знаете что ISE в ходе оптимизации его выкинет если у вас не стоит опции сделать безопасный автомат, а если стоит то насильно добавит с переходом в заданное состояние восстановления:) потому во всяком случае для ISE и для кейза в автоматах это без не имеет смысла, даже с помехами... Дак как можно сравнивать на больше однобитный сигнал допустим вам надо что-то отсчитать и когда стало больше 6 что-то сделать... написав if(... > 6) - вы получаете сравнение с вектором... но если вы начнете считать не с 0 до 7 (больше 6), а с 1 до 8, а в сравнении будет if(counter[3] == 1) - это будет 1 битный сигнал который может напрямую пойти на разрешение... Битность сравнения тоже важна, лут то имеет ограниченное число входов 1- 4 бита - 1 ЛУТ, а 5-8 битов уже 3, по одному на каждые 4 бита и 1 на результат лутов... даже имеет значение если addr - one hot как записать case(addr) 1: 2: 4: .... или if (addr[1] == 1) if (addr[2] == 1) if (addr[4] == 1) .... причем иногда как-то катастрофически имеет значение:( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба А вы знаете что ISE в ходе оптимизации его выкинет если у вас не стоит опции сделать безопасный автомат, а если стоит то насильно добавит с переходом в заданное состояние восстановления:) потому во всяком случае для ISE и для кейза в автоматах это без не имеет смысла, даже с помехами...В любом случае нужно иметь в виду, что помехи собьют автомат, и делать всё возможное, включая то, что Вы описали выше. Но также включая и сравнение не просто ==, а >. но если вы начнете считать не с 0 до 7 (больше 6), а с 1 до 8, а в сравнении будет if(counter[3] == 1) - это будет 1 битный сигнал который может напрямую пойти на разрешение...Ну это уже мелкие хитрости, я их не подразумевал, когда писал своё изначальное возражение. Тут цепи переноса являются этим самым сравнивателем, заместо лутов. Битность сравнения тоже важна, лут то имеет ограниченное число входов 1- 4 бита - 1 ЛУТ, а 5-8 битов уже 3, по одному на каждые 4 бита и 1 на результат лутов...В любом случае, если сравнение делается на лутах, то для выдачи результата той же шины на 32 бита потребуется каскадное соединение того же количества лутов, что при проверке на равенство, что при проверке больше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Потому вторая хитрость проверять не на == константе, а на == 0, или меньше 0. В первом случае проверка ИЛИ по всем битам, во втором случае проверяем вообще знаковый бит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба А что толку, что это ИЛИ, если это на лутах реализовано? Лутам без разницы, какая функция. Съеденных лутов от этого не меньше Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба ну может быть... но перевести проверку на 1 бит всяко экономно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба что при проверке на равенство, что при проверке больше. А вот тут Вы в корне не правы. Проверка на > или < - это сумматор (вычитатель, точнее), со всеми вытекающими цепями переноса. Проверка на == и != это древесная структура XOR - OR - ... - OR, которая в принципе быстрее сумматора, причем убыстрение растет экспоненциально с увеличением разрядности. А автор темы вообще пропал... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться