alexPec 3 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба Всем доброго дня. Прошу просвятить по присваиванию значений регистрам. Я в верилоге не совсем новичок, но и не гуру. Пару раз натыкался на подобные случаи в своих кодах, решал их, но без четкого понимания почему так. Имеется вот такой кусок кода: reg [127:0] save_reg; assign avm_m0_writedata = was_wait ? save_reg : ram_read_data; always @(posedge csi_clock_clk) ... ... burstY_write: begin if (!avm_m0_waitrequest) begin if (burst_counter == 0) begin m0_state = burstY_last; end burst_counter--; save_reg=ram_read_data; ram_read_adr++; end else begin was_wait=1; save_reg=ram_read_data; m0_state=burstY_WS; ram_read_adr++; end end burstY_WS: begin if (!avm_m0_waitrequest) begin if (burst_counter == 0) begin m0_state = burstY_last; end was_wait=0; burst_counter--; m0_state = burstY_write; save_reg=ram_read_data; ram_read_adr++; end end burstY_last: begin if (!avm_m0_waitrequest) begin avm_m0_write = 1'b0; m0_state = burstY_end; y_ptr_bofs+=frame_w; ram_read_adr++; end else begin save_reg=ram_read_data; was_wait=1; end end ... ... end save_reg нигде больше на записывается. Читается save_reg только в первой строчке кода и больше нигде не используется. Расчитывал, что в save_reg окажется значение ram_read_data с предыдущего такта. ram_read_data - это выход сгенерированной RAM. В симуляторе же вижу такое. Видно, что где выделено синим, значения ram_read_data и save_reg не сдвинуты на 1 такт. НО! почему-то в самом начале (выделено желтым) значения все-же сдвинуты... Пробовал ставить везде, где присваивается save_reg присваивание " <= " - ничего не поменялось. Как сделать присваивание так, чтобы значение гарантировано оказалось в регистре НА СЛЕДУЮЩЕМ такте? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба Или совсем простой, тестовый пример: reg [127:0] save_reg; assign avm_m0_writedata = was_wait ? save_reg : ram_read_data; always @(posedge csi_clock_clk) begin save_reg<=ram_read_data; if (!avm_m0_waitrequest) ram_read_adr++; if (ram_read_adr[2]) was_wait=1; else was_wait=0; end Видно, что save_reg ни на такт не сдвинут от ram_read_data. Что я не так пишу??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 14 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба 45 минут назад, alexPec сказал: Что я не так пишу??? Зачем вы вообще используете в always @(posedge clk) блокирующие присваивания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба 42 minutes ago, alexPec said: Или совсем простой, тестовый пример: reg [127:0] save_reg; assign avm_m0_writedata = was_wait ? save_reg : ram_read_data; always @(posedge csi_clock_clk) begin save_reg<=ram_read_data; if (!avm_m0_waitrequest) ram_read_adr++; if (ram_read_adr[2]) was_wait=1; else was_wait=0; end Видно, что save_reg ни на такт не сдвинут от ram_read_data. Что я не так пишу??? Во-первых Вы пишете на Systemverilog. В обычном Верилоге нет оператора ++. Соответственно для описания регистра лучше использовать always_ff (или always_latch) тогда возможно проблема пройдёт. И второй момент где нужно посмотреть: Не используйте неблокирующее присваивание для комбинационной логики и читайте Warning'и. У вас в коде есть неблокирующее и блокирующее присваивание (++ и was_wait=1) поэтому может интерпретироваться криво/не правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба 1 час назад, Nick_K сказал: И второй момент где нужно посмотреть: Не используйте неблокирующее присваивание для комбинационной логики и читайте Warning'и. У вас в коде есть неблокирующее и блокирующее присваивание (++ и was_wait=1) поэтому может интерпретироваться криво/не правильно. Немного добавлю... Не пишите счетчики и регистры в общей куче кода. Напишите их отдельно и у них должны быть сигналы разрешения счета, загрузки, синхронного сброса и тд... вот их и используйте в "куче"... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба Всем спасибо за помощь! 1 час назад, andrew_b сказал: Зачем вы вообще используете в always @(posedge clk) блокирующие присваивания? Я же писал выше, это я от безнадеги уже попробовал оператор <=. Так уже давно не делал. Разницы нет если оставить оператор "=" вместо "<=" Цитата Во-первых Вы пишете на Systemverilog. В обычном Верилоге нет оператора ++. Соответственно для описания регистра лучше использовать always_ff (или always_latch) тогда возможно проблема пройдёт. Попробовал always_ff - то же самое (с оператором "="). А с always_latch появляется ворнинг в коде и при симуляции ругается ошибкой. Цитата Немного добавлю... Не пишите счетчики и регистры в общей куче кода. Напишите их отдельно и у них должны быть сигналы разрешения счета, загрузки, синхронного сброса и тд... вот их и используйте в "куче"... Я оставил уже совсем все просто (с разделением счетчика и данных памяти): reg [127:0] save_reg; assign avm_m0_writedata = was_wait ? save_reg : ram_read_data; always_ff @(posedge csi_clock_clk) begin if (csi_clock_reset) ram_read_adr='0; else ram_read_adr++; end always_ff @(posedge csi_clock_clk) begin save_reg=ram_read_data; end Результат тот же: Сейчас то что не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба 1 minute ago, alexPec said: Сейчас то что не так? Блокирующее присваивание = даёт именно такой результат. Исправте все Ваши схемы на правильные (и избавьтесь от ++, заменив суммой - да дико, но схемотехнически "по феншую") И проверьте выхлоп. Подозреваю, что симулятор очень правильный и делает что пиркажут, поэтому блокирующее присваивание обрабатывает в лоб и не ругается даже. И вопрос ещё один: а это весь синтезируемый код, или всё это внутри функции или может быть под дженериком? Ибо там поведение будет значительно отличаться в отличии от програмистских решений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба 2 часа назад, alexPec сказал: Результат тот же: С save_reg вроде все нормально, а с ram_read_data - непонятно. Попробуйте вывести save_reg и ram_read_data через $display always @(save_reg) $display($time, save_reg); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Strob 0 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба Just now, alexPec said: Я же писал выше, это я от безнадеги уже попробовал оператор <=. Так уже давно не делал. Разницы нет если оставить оператор "=" вместо "<=" Лучше не от безнадеги, а с терпением почитайте про блокирующие и неблокирующие присвоения. Мне кажется Вы создали себе проблему, а теперь героически ее решаете. На некоторое время забудьте, что в always @(posedge clk) можно использовать =, ++, += и прочее. Когда у Вас возникнет потребность в подобном синтаксисе, тогда как раз появится понимание когда его можно использовать, а когда не стоит. Используйте только <=. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 12 июля, 2021 Опубликовано 12 июля, 2021 · Жалоба 3 минуты назад, Strob сказал: Лучше не от безнадеги, а с терпением почитайте про блокирующие и неблокирующие присвоения. Мне кажется Вы создали себе проблему, а теперь героически ее решаете. На некоторое время забудьте, что в always @(posedge clk) можно использовать =, ++, += и прочее. Когда у Вас возникнет потребность в подобном синтаксисе, тогда как раз появится понимание когда его можно использовать, а когда не стоит. Используйте только <=. Да я в принципе четко понимаю разницу между = и <=. Потому и начал и то и другое пробовать, что не совпала теория с практикой Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexx 0 13 июля, 2021 Опубликовано 13 июля, 2021 (изменено) · Жалоба ++ можно использовать только в блокирующем присваивании. Применяйте только то в чем уверены на 100%, чем проще, тем лучше. Изменено 13 июля, 2021 пользователем lexx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 13 июля, 2021 Опубликовано 13 июля, 2021 · Жалоба 1 час назад, lexx сказал: ++ можно использовать только в блокирующем присваивании. Применяйте только то в чем уверены на 100%, чем проще, тем лучше. Есть разработчики "ремесленники", А есть разработчики "гении"... "ремесленник" всегда применяет шаблон, там где этот шаблон надёжно работает и тогда всё, что не шаблон - там нужно искать ошибку.. соответственно, чем больше шаблонов, тем меньше вероятность появления ошибки в тексте.. А вот у "гениев" другая доктрина поведения. он пишется "шедевр". Но, к сожалению, часто этот шедевр не работает и искать место возникновения ошибки можно по всему тексту. соответственно гений проводит массу изысканий по тексту, чтобы выяснить, где будет работать и где не будет работать и так далее... Ну а какой путь лучше, каждый для себя решает сам... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexx 0 14 июля, 2021 Опубликовано 14 июля, 2021 · Жалоба 15 hours ago, iosifk said: "ремесленник" всегда применяет шаблон, там где этот шаблон надёжно работает и тогда всё, что не шаблон - там нужно искать ошибку.. Verilog довольно "короткий" язык, там не так и много шаблонов, особенно если мы говорим о синтезируемой области. Можно, что угодно говорить, но поиски "своего" пути это как этап обучения и рано или поздно приходишь к насыщению, повторно использовать "странные" конструкции языка всего лишь потеря времени. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 14 июля, 2021 Опубликовано 14 июля, 2021 · Жалоба Приветствую! 16 hours ago, iosifk said: Есть разработчики "ремесленники", А есть разработчики "гении"... Но есть еще разработчики-инженеры которые пытаются понять почему и когда нужно применять те или иные шаблоны, а когда надо и "гения" включать. А не тупо штамповать шаблонами потому что так кто-то когда-то сказал. On 7/12/2021 at 10:14 PM, alexPec said: Да я в принципе четко понимаю разницу между = и <=. Потому и начал и то и другое пробовать, что не совпала теория с практикой У вас в коде непонятно где и как как данные в ram_read_data попадают. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitzap 0 14 июля, 2021 Опубликовано 14 июля, 2021 (изменено) · Жалоба По всей видимости, вам нужно конструкцию save_reg=ram_read_data; оформить в виде комбинационной логики. Для этого вынести это присваивание и условия в еще один always @(*) if (условие) save_reg=ram_read_data; Либо сделать save_reg как wire и оформить в виде тетрарной операции - нечто вроде assign save_reg = (условие) ? ram_read_data : save_reg Но в любом случае надо представлять, в виде каких конструкций этот код синтезируется. Изменено 14 июля, 2021 пользователем vitzap Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться