ну наконец-то!!!
плагины это всегда хорошо.
может теперь кто-то с прямыми руками (нет, я сам попробую, но моими руками плагины писать, что блоху кувалдой ковать) напишет так нужные мне:
«Продолжить нумерацию» — для ворда
«Обрезать/кадрировать изображение» — для всего пакета.
плагины это всегда хорошо.
плагины с модерацией это очень хорошо.
Справедливости ради замечу, что не проверял (на тот момент) сообщения анализатора частотных характеристик синтезируемой схемы. Более того, я применял упрощенный анализатор. Оказалось проще перейти к иному принципу достижения той же цели — перешел от деления к умножению и все заработало.
помню лишь саму суть:
считал что-то похожее на средне-арифметическое, но в знаменателе была не константа.
числа 32 битные.
проверял по signal-tap (вроде так пишется), в реальных условиях.
модуль работал интересно — при прочих равных мог отработать как надо, а мог и не как надо.
проверка данных на входе, выходе и внутри модуля показала, что на этапе деления произвольного (вычисляемого модулем числа) на произвольное (вычисляемое модулем число) результат деления не всегда был верным.
строка имел вид такой же, как я описывал выше (с другими именами регистров).
мне нужно было найти отношение максимума в массиве к его окрестности.
максимум вычислялся как среднее арифметическое центральных ячеек, а окрестность — как крайние точки массива.
отношение сравнивалось с задаваемым порогом.
и собственно однотактный делитель, синтезируемый компилятором, не хорошо справлялся с поставленной задачей.
справедливости ради замечу, что при делении на константу, такой делитель всегда дает верный результат деления.
у меня обычно было на оборот. проект на 100МГц, фиттер ругается, что максимум можно на 72МГц.
но при проверке «в полевых условиях» выявилось, что все прекрасно работает.
пожалуй мне стоит сделать оговорку, что 99,9% моих проектов писались в среде Quartus II. Как я понимаю, данная среда безбожно игнорирует требования стандарта SV. Это приводит к тому, что данная среда игнорирует множество конструкций. Они являются не синтезируемыми.
В том числе и блоки always_ff, always_comb, always_latch — независимо от применяемого слова синтезированная RTL-модель была одинаковая.
По факту в своих проектах из SV я использую малую толику.
Например очень удобно описывать состояния автомата через перечисления:
enum bit [0:7]
{
reset,
idle,
s00,
s01
}state, new_state;
Узлы-то отрастают, да вот знания теряются.
Более того, алкоголь сильно разрушает прочность кровеносных сосудов головного мозга, стенки истончаются.
Что приводит к:
первый вариант — стенка лопается и получаем инсульт;
второй вариант — из-за эластичности стенок происходит закупорка сосудов и развивается некроз головного мозга.
полностью согласен.
и крайне жаль, что системы синтеза не способны реализовать всю мощь его стандарта.
потому я делал (в коментариях) заметку, что из SV только часть описания модуля: тип logic, описание портов модуля.
для красоты always_ff — для тактирования переключения состояний автомата, always-comb — для отработки состояний автомата.
пробовал работать с задачами (task) и функциями — квартус пректы синтезировал, но они работали специфически — не всегда правильно.
это как запись вида
c = a/b; — квартус синтезирует однотактный делитель, которы иногда делит не верно.
(знаю, что так делать нельзя, и однотактное деление по сути зло)
про автоматическое выравнивагие:
прелесть языка в том, что он не запрещает вручную указывать разрядности ренистров.
иногда (в моей практике крайне редко) это мешает (выравнивание разрядности) но чаще это упрощает.
особенно если придерживаться хорошего правилаописания аппаратуры: текст описания отдельного модуля не должен превышать 1-2 листов формата А4
always_ff
это один из вариантов реализации блока события. который говорит компилятору, что данный блок надо стараться синтезировать на триггерной (?) логике.
второ тип always_comb (не уверен, что записал верно) — говорит, что данный блок необходимо синтезировать на комбинационной логике.
always — компилятор сам решает какой логикой реализовать блок.
по опыту (втом числе стороннему) always_ff и slways_comb применяются при описаниее конечных автоматов.
по опыту работы в Quartus — ему безразлично что писать вначеле блока. это влияет только на ошибки компиляции, но не на итоговую синтезированную схему (rtl-модель)
нельза инкрементировать значение регистра и сразу же его сравнивать и обнулять.
если же в вашем варианте заменить присвоение вида <= на =, то проект будет работать.
однако реаоизации на блокирующих присвоениях плохо синтезируются.
в данном примере cnt будет НЕ 8 битным.
но его разрядность как регистра может быть менее 32 если синтезатор посчитает, что в проекте его максимальное значение меньшей разрядности.
1. begin — end в SV уродует код в целом, согласен.
2. эта проблема решается интерфейсами и более того. если я правильно помню стандарт, то при объявлении модуля внутри тела другого модуля не требуется явное указание подключения для одноименных портов. .clk(clk) в этом случае выглядит как .clk().
3. не всегда требуется присоединение всех пинов к родителю (если я правильно понимаю о чем идет речь)
Мною приведен пример общего вида.
Каждый блок должен иметь четкое начало и конец. Будь то скобки '{', '}' для С++ или команды begin, end для SV.
Листинг должен быть однотипным, это существенно упрощает сопровождение проектов множеством разработчиков различного уровня подготовки.
И удобнее объединять под один блок always набор процессов, связанных с конкретной задачей.
Если переписать конструкцию
always@(posedge CLK) begin
if (cnt >= 13500000) begin
CLK_OUT <= 1;
end
else begin
CLK_OUT <= 0;
end
if (cnt == 27000000) begin
cnt <= 0;
end
else begin
cnt <= cnt + 1;
end
CNT_OUT <= cnt;
end
листингом, предлагаемом вами, то получим следующее:
Поверьте мне — начинающему разработчику такая запись покажется абракадаброй.
Не всегда более коротко записанный код, является более удобочитаемым.
Не стоит забывать, что большинство проектов для ПЛИС развивается внутри предприятий, что подразумевает сопровождение одного проекта различными разработчиками. По этой причине любое описание для ПЛИС должно иметь листинг понимаемый разработчиком любого уровня.
Потому я его и не сравнивал.
Что касается читаемости листинга. Основным аспектом является дело привычки.
Я же ориентировался на начинающих.
С точки зрения изучения языка с нуля SV гораздо проще.
плагины это всегда хорошо.
может теперь кто-то с прямыми руками (нет, я сам попробую, но моими руками плагины писать, что блоху кувалдой ковать) напишет так нужные мне:
«Продолжить нумерацию» — для ворда
«Обрезать/кадрировать изображение» — для всего пакета.
плагины это всегда хорошо.
плагины с модерацией это очень хорошо.
помню лишь саму суть:
считал что-то похожее на средне-арифметическое, но в знаменателе была не константа.
числа 32 битные.
проверял по signal-tap (вроде так пишется), в реальных условиях.
модуль работал интересно — при прочих равных мог отработать как надо, а мог и не как надо.
проверка данных на входе, выходе и внутри модуля показала, что на этапе деления произвольного (вычисляемого модулем числа) на произвольное (вычисляемое модулем число) результат деления не всегда был верным.
строка имел вид такой же, как я описывал выше (с другими именами регистров).
мне нужно было найти отношение максимума в массиве к его окрестности.
максимум вычислялся как среднее арифметическое центральных ячеек, а окрестность — как крайние точки массива.
отношение сравнивалось с задаваемым порогом.
и собственно однотактный делитель, синтезируемый компилятором, не хорошо справлялся с поставленной задачей.
справедливости ради замечу, что при делении на константу, такой делитель всегда дает верный результат деления.
но при проверке «в полевых условиях» выявилось, что все прекрасно работает.
В том числе и блоки always_ff, always_comb, always_latch — независимо от применяемого слова синтезированная RTL-модель была одинаковая.
По факту в своих проектах из SV я использую малую толику.
Например очень удобно описывать состояния автомата через перечисления:
Более того, алкоголь сильно разрушает прочность кровеносных сосудов головного мозга, стенки истончаются.
Что приводит к:
первый вариант — стенка лопается и получаем инсульт;
второй вариант — из-за эластичности стенок происходит закупорка сосудов и развивается некроз головного мозга.
и крайне жаль, что системы синтеза не способны реализовать всю мощь его стандарта.
потому я делал (в коментариях) заметку, что из SV только часть описания модуля: тип logic, описание портов модуля.
для красоты always_ff — для тактирования переключения состояний автомата, always-comb — для отработки состояний автомата.
пробовал работать с задачами (task) и функциями — квартус пректы синтезировал, но они работали специфически — не всегда правильно.
это как запись вида
c = a/b; — квартус синтезирует однотактный делитель, которы иногда делит не верно.
(знаю, что так делать нельзя, и однотактное деление по сути зло)
прелесть языка в том, что он не запрещает вручную указывать разрядности ренистров.
иногда (в моей практике крайне редко) это мешает (выравнивание разрядности) но чаще это упрощает.
особенно если придерживаться хорошего правилаописания аппаратуры: текст описания отдельного модуля не должен превышать 1-2 листов формата А4
это один из вариантов реализации блока события. который говорит компилятору, что данный блок надо стараться синтезировать на триггерной (?) логике.
второ тип always_comb (не уверен, что записал верно) — говорит, что данный блок необходимо синтезировать на комбинационной логике.
always — компилятор сам решает какой логикой реализовать блок.
по опыту (втом числе стороннему) always_ff и slways_comb применяются при описаниее конечных автоматов.
по опыту работы в Quartus — ему безразлично что писать вначеле блока. это влияет только на ошибки компиляции, но не на итоговую синтезированную схему (rtl-модель)
я ниразу не использовал подобную конструкцию, т.к. считаю что она усложняет понимание текста делая его не однотипным по стилю.
в целом я не использую его функционал в полной мере.
если же в вашем варианте заменить присвоение вида <= на =, то проект будет работать.
однако реаоизации на блокирующих присвоениях плохо синтезируются.
но это лишь пример, а не полноценный, кроссплатформенный проект.
но его разрядность как регистра может быть менее 32 если синтезатор посчитает, что в проекте его максимальное значение меньшей разрядности.
2. эта проблема решается интерфейсами и более того. если я правильно помню стандарт, то при объявлении модуля внутри тела другого модуля не требуется явное указание подключения для одноименных портов. .clk(clk) в этом случае выглядит как .clk().
3. не всегда требуется присоединение всех пинов к родителю (если я правильно понимаю о чем идет речь)
Каждый блок должен иметь четкое начало и конец. Будь то скобки '{', '}' для С++ или команды begin, end для SV.
Листинг должен быть однотипным, это существенно упрощает сопровождение проектов множеством разработчиков различного уровня подготовки.
И удобнее объединять под один блок always набор процессов, связанных с конкретной задачей.
Если переписать конструкцию
листингом, предлагаемом вами, то получим следующее:
Поверьте мне — начинающему разработчику такая запись покажется абракадаброй.
Не всегда более коротко записанный код, является более удобочитаемым.
Не стоит забывать, что большинство проектов для ПЛИС развивается внутри предприятий, что подразумевает сопровождение одного проекта различными разработчиками. По этой причине любое описание для ПЛИС должно иметь листинг понимаемый разработчиком любого уровня.
Что касается читаемости листинга. Основным аспектом является дело привычки.
Я же ориентировался на начинающих.
С точки зрения изучения языка с нуля SV гораздо проще.