Sirko 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба Есть модуль, у которого входы Clk, Reset и выходы Led, Address module MyModule( input wire Clk, input wire Reset, output reg [20:0]RAM_Address, output reg Led_Complete ); always @ (*) begin if (zero != 1'b0) begin RAM_Address <= 0; Led_Complete <= 1'b0; end else begin always @(posedge Clk) begin // Здесь какаято ошибка if(RAM_Address < 7) begin RAM_Address <= RAM_Address + 1; end else begin Led_Complete <= 1'b1; end end end end endmodule При компиляции возникает вот такая ошибка: Error (10170): Verilog HDL syntax error at Logger.v(65) near text "always"; expecting "end" Что я делаю не так? Вариант №2 module MyModule( input wire Clk, input wire Reset, output reg [20:0]RAM_Address, output reg Led_Complete ); always @ (Reset) begin RAM_Address <= 0; Led_Complete <= 1'b0; end always @ (posedge Clk) begin if(RAM_Address < 7)begin RAM_Address <= RAM_Address + 1'b0; end else begin // Led_Complete <= 1'b1; Если строку разкоментарить, то возникнет ошибка end end endmodule Здесь тоже обычное присвоение вызывает ошибки Error (10028): Can't resolve multiple constant drivers for net "Led_Complete" at Logger.v(42) Error (10029): Constant driver at Logger.v(48) в строках always @ (Reset) и always @ (posedge Clk) соответственно. Помогите понять суть проблемы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 67 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба Есть модуль, у которого входы Clk, Reset и выходы Led, Address end else begin always @(posedge Clk) begin // Здесь какаято ошибка if(RAM_Address < 7) begin endmodule При компиляции возникает вот такая ошибка: Error (10170): Verilog HDL syntax error at Logger.v(65) near text "always"; expecting "end" Что я делаю не так? Так пишет же, что ожидает end. Значит, количество begin не соответствует количество end. Посчитайте аккуратно. always @ (Reset) begin RAM_Address <= 0; Led_Complete <= 1'b0; end always @ (posedge Clk) begin if(RAM_Address < 7)begin RAM_Address <= RAM_Address + 1'b0; end else begin // Led_Complete <= 1'b1; Если строку разкоментарить, то возникнет ошибка end end endmodule Здесь тоже обычное присвоение вызывает ошибки Error (10028): Can't resolve multiple constant drivers for net "Led_Complete" at Logger.v(42) Error (10029): Constant driver at Logger.v(48) в строках always @ (Reset) и always @ (posedge Clk) соответственно. Помогите понять суть проблемы. И тут всё понятно. Вы пытаетесь присвоить Led_Complere значения в разных блоках, что при синтезе не разрешено, о чём вам синтезатор и сообщает. Сами подумайте, поставьте себя на место синтезатора - как бы вы реализовывали в железе этот код? Ведь это просто аппаратная коллизия. Именно поэтому синтезатор и не позволяет этого делать. Все присвоения переменной должны делаться в одном блоке. На симуляторе, конечно, такой код прокатит, но будут гонки и нестабильная работа кода, поэтому и для несинтезирумого кода так писать не надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sirko 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба Так пишет же, что ожидает endА где? Поштучно вроде как совпадает. Это весь код, не считая некоторых дополнительных входных и выходных параметров. Сами подумайте, поставьте себя на место синтезатораЯ бы поставил перед Led_Complete мультиплексор и в зависимости от значения Reset, подавал бы на Led_Complete либо "0" либо значения с другого модуля. Тоже относится и к RAM_Address. Понимаю, что я желаемое описываю неверно, но как должно быть, не представляю. Это самые первые мои шаги в освоении ПЛИС. Вернее, какие там шаги? Я еще носки обуть не знаю как. В голове упорно сидят СИшные представления и для их "искривления" нужно немножко времени и практики. А пока Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба Сделайте вот так: module MyModule( input wire Clk, input wire Reset, output reg [20:0]RAM_Address, output reg Led_Complete ); always @ (Reset or posedge Clk) if (Reset) begin RAM_Address <= 0; Led_Complete <= 1'b1; end else begin if(RAM_Address < 7)begin RAM_Address <= RAM_Address + 1'b0; end else begin Led_Complete <= 1'b1; end end endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sirko 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба А можно прокоментировать, почему сигнал Reset обязательно добавлять в перечень чувствительностей блока? По поводу "Сделайте вот так:"появляется вот такая ошибка Error (10122): Verilog HDL Event Control error at Logger.v(72): mixed single- and double-edge expressions are not supported Может у моего проекта какие-то настройки нужно поправить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 (изменено) · Жалоба А вы в какой среде работаете? Quartus? Попробуйте строчку на такую заменить: always @ (posedge Reset or posedge Clk), либо вообще always @ (posedge Clk), а остальное так же. Он как раз жалуется на то, что в условии два выражения. У меня в ModelSim нет такой проблемы. А можно прокоментировать, почему сигнал Reset обязательно добавлять в перечень чувствительностей блока?Вы имеете ввиду вместе с posedge Clk? Можно и не добавлять, тогда все будет выполняться от клока, впрочем так и должно быть. Просто если снаружи изменить reset, то условия выполнятся не дожидаясь переднего фронта clk в случае с такой конструкцией: always @ (posedge Reset or posedge Clk). Изменено 18 декабря, 2011 пользователем M@kar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flexz 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба always@(posedge Clk or posedge Rst) Касательно самого первого примера - а такие вложенные always-ы вообще допустимы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sirko 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба Среда Quartus 9.1. Добавление posedge к Reset - ошибку устранило. Но мне не ясно, почему на все триггеры компилятор не может просто завести сброс, минуя клок? На вопрос " а такие вложенные always-ы вообще допустимы?" я, пока-что, затрудняюсь ответить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба always@(posedge Clk or posedge Rst)В стандарте IEEE_Std_1364-2001 (Verilog) описаны такие конструкции. А вот как они будут синтезироваться я не знаю, но у Xilinx в примерах тоже встречал. Но мне не ясно, почему на все триггеры компилятор не может просто завести сброс, минуя клок?Почему нельзя, можно. Если вот такую конструкцию использовать always@(posedge Clk or posedge Reset), то так оно и будет. Просто если ты сделаешь, как предлагал в начале:always @ (Reset) begin RAM_Address <= 0; Led_Complete <= 1'b0; end always @ (posedge Clk) begin if(RAM_Address < 7)begin RAM_Address <= RAM_Address + 1'b0; end else begin // Led_Complete <= 1'b1; Если строку разкоментарить, то возникнет ошибка end end endmodule То при установке Reset у тебя будет выполняться присвоение в блоке always @ (Reset) begin и тут же по клоку в блоке always @ (posedge Clk) begin. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 67 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба Я бы поставил перед Led_Complete мультиплексор и в зависимости от значения Reset, подавал бы на Led_Complete либо "0" либо значения с другого модуля. Тоже относится и к RAM_Address. Понимаю, что я желаемое описываю неверно, но как должно быть, не представляю. С мультиплексором это будет совсем не то, что вы описываете. Мультиплексором надо тоже управлять. И если запись опять идёт в разных блоках, т.е. параллельно, то как быть с в случае, если управляющие сигналы на мультиплексор приходят одновременно? Какому из них отдать предпочтение? Вы себе аппаратную реализацию представьте: вот ваша эта переменная должна просинтезироваться в триггер. На вход триггера вы подаёте сигналы от двух источников сразу. Это аппаратная коллизия и ничего более. Поэтому присвоения переменным должны выполняться строго внутри одного и того же блока, это залог правильной работы как симуляционных моделей, так и аппаратной имплементации. Это самые первые мои шаги в освоении ПЛИС. Вернее, какие там шаги? Я еще носки обуть не знаю как. В голове упорно сидят СИшные представления и для их "искривления" нужно немножко времени и практики. А пока Это нормально, все через это проходят. Когда пишете на HDL, всегда держите в голове фоном, что тут все блоки работают параллельно во времени (HDL - это параллельные языки). Если хочется аналогий с С, то представьте, что у вас программа работает под управлением ОС, которая сама синхронизирует потоки выполнения в разных блоках (кстати, симулятор так и работает). А можно прокоментировать, почему сигнал Reset обязательно добавлять в перечень чувствительностей блока? Почему обязательно? Не обязательно. Если вы хотите получить триггер с асинхронным сбросом, то нужно добавить 'posedge clk', а если хотите синхронный сброс, то не надо добавлять: always *(posedge clk, posedge reset) begin if(reset) begin ... // асинхронный сброс end else begin ... // рабочая логика end end always *(posedge clk) begin if(reset) begin ... // синхронный сброс end else begin ... // рабочая логика end end А вообще, если юзаете квартус, то лучше юзать и SV'шые конструкции: always_ff, always_comb. И ещё совет. Если используете регистровый блок (т.е. который порождает триггеры), то рекомендуется использовать неблокирующие присваивания <=, а если комбинационный блок (т.е. где порождается только логика), то блокирующие =. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sirko 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба Спасибо всем за разъяснения. Буду кропать дальше. Пока, что для представления разницы между блокирующим и не блокирующим присваиванием, требуется некоторое напряжение извилин. А SV'шые конструкции: always_ff, always_comb впервые слышу. Так, что возвращаюсь к чтиву. P.S. Если кто встечал русскоязычные рессурсы с пошаговыми примерами на верилоге с квартусом, пожалуйста, поделитесь. Ориентируюсь пока что марсоходом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 18 декабря, 2011 Опубликовано 18 декабря, 2011 · Жалоба Пока, что для представления разницы между блокирующим и не блокирующим присваиванием, требуется некоторое напряжение извилин.Вот здесь об этом можно найти немного и на русском.verilog.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sirko 0 23 декабря, 2011 Опубликовано 23 декабря, 2011 · Жалоба Объясните, пожалуйста, такое поведение кода: module m1(clk, d0, d1, d2, d3, out, counter); input wire clk; input wire d0, d1, d2, d3; output reg out = 0; output reg [3:0] counter = 0; always @(clk ) begin counter = counter + 1; end endmodule Насколько я понимаю, то, при каждом изменении clk, должен увеличиваться счетчик. В симуляторе почему-то его выходы в неопределенном состоянии. Попробовал вот такой фокус: module m1(clk, d0, d1, d2, d3, out, counter); input wire clk; input wire d0, d1, d2, d3; output reg out = 0; output reg [3:0] counter = 0; reg [3:0] old = 0; always @(clk ) begin if (clk != old) begin old = clk; counter = counter + 1; out = counter[0]; end end endmodule но здесь совсем модуль ни к чему не прицеплен Кстати, а есть ли возможность в квартусе увидеть "принципиальную схему" скомпилированного блока? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sirko 0 23 декабря, 2011 Опубликовано 23 декабря, 2011 · Жалоба Объясните, пожалуйста, такое поведение кода: module m1(clk, d0, d1, d2, d3, out, counter); input wire clk; input wire d0, d1, d2, d3; output reg out = 0; output reg [3:0] counter = 0; always @(clk ) begin counter = counter + 1; end endmodule Насколько я понимаю, то, при каждом изменении clk, должен увеличиваться счетчик. В симуляторе почему-то его выходы в неопределенном состоянии. Попробовал вот такой фокус: module m1(clk, d0, d1, d2, d3, out, counter); input wire clk; input wire d0, d1, d2, d3; output reg out = 0; output reg [3:0] counter = 0; reg [3:0] old = 0; always @(clk ) begin if (clk != old) begin old = clk; counter = counter + 1; out = counter[0]; end end endmodule но здесь совсем модуль ни к чему не прицеплен Кстати, а есть ли возможность в квартусе увидеть "принципиальную схему" скомпилированного блока? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 24 декабря, 2011 Опубликовано 24 декабря, 2011 (изменено) · Жалоба Вам нужно сделать синхронизацию по фронту, тогда все будет работать: always @(posedge clk) begin module m1(clk, d0, d1, d2, d3, out, counter); input wire clk; input wire d0, d1, d2, d3; output reg out = 0; output reg [3:0] counter = 0; always @(posedge clk) begin counter <= counter + 1; end endmodule Изменено 24 декабря, 2011 пользователем M@kar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться