Перейти к содержанию
    

Детский вопрос по присваиванию

Всем доброго дня.

Прошу просвятить  по присваиванию значений регистрам. Я в верилоге не совсем новичок, но и не гуру. Пару раз натыкался на подобные случаи в своих кодах, решал их, но без четкого понимания почему так.

Имеется вот такой кусок кода:
 

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  присваивание " <= " - ничего не поменялось. Как сделать присваивание так, чтобы значение гарантировано оказалось в регистре НА СЛЕДУЮЩЕМ такте?

476216468_.thumb.png.920ad2fced48b71a1995b99097a613ec.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или совсем простой, тестовый пример:

 

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

 

 

863533178_.thumb.png.e75cc98ebf6abb10d6603e300c0972be.png

 

Видно, что save_reg ни на такт не сдвинут от ram_read_data.

Что я не так пишу???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

45 минут назад, alexPec сказал:

Что я не так пишу???

Зачем вы вообще используете в always @(posedge clk) блокирующие присваивания?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

863533178_.thumb.png.e75cc98ebf6abb10d6603e300c0972be.png

 

Видно, что save_reg ни на такт не сдвинут от ram_read_data.

Что я не так пишу???

Во-первых Вы пишете на Systemverilog. В обычном Верилоге нет оператора ++. Соответственно для описания регистра лучше использовать always_ff (или always_latch) тогда возможно проблема пройдёт.

И второй момент где нужно посмотреть: Не используйте неблокирующее присваивание для комбинационной логики и читайте Warning'и. У вас в коде есть неблокирующее и блокирующее присваивание (++ и  was_wait=1) поэтому может интерпретироваться криво/не правильно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Nick_K сказал:

И второй момент где нужно посмотреть: Не используйте неблокирующее присваивание для комбинационной логики и читайте Warning'и. У вас в коде есть неблокирующее и блокирующее присваивание (++ и  was_wait=1) поэтому может интерпретироваться криво/не правильно.

Немного добавлю...

Не пишите счетчики и регистры в общей куче кода. Напишите их отдельно и у них должны быть сигналы разрешения счета, загрузки, синхронного сброса и тд... вот их и используйте в "куче"...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем спасибо за помощь!

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

Результат тот же:

1467018990_.thumb.png.162f4267b5b53b9622a2cad800546288.png

Сейчас то что не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, alexPec said:

Сейчас то что не так?

Блокирующее присваивание = даёт именно такой результат. Исправте все Ваши схемы на правильные (и избавьтесь от ++, заменив суммой - да дико, но схемотехнически "по феншую") И проверьте выхлоп. Подозреваю, что симулятор очень правильный и делает что пиркажут, поэтому блокирующее присваивание обрабатывает в лоб и не ругается даже.

И вопрос ещё один: а это весь синтезируемый код, или всё это внутри функции или может быть под дженериком? Ибо там поведение будет значительно отличаться в отличии от програмистских решений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, alexPec сказал:

Результат тот же:

С save_reg вроде все нормально, а с ram_read_data - непонятно.

Попробуйте вывести save_reg и ram_read_data через $display

always @(save_reg) $display($time, save_reg);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, alexPec said:

Я же писал выше, это я от безнадеги уже попробовал оператор <=. Так уже давно не делал. Разницы нет если оставить оператор "=" вместо "<="

Лучше не от безнадеги, а с терпением почитайте про блокирующие и неблокирующие присвоения. Мне кажется Вы создали себе проблему, а теперь героически ее решаете.

На некоторое время забудьте, что в always @(posedge clk) можно использовать =, ++, += и прочее. Когда у Вас возникнет потребность в подобном синтаксисе, тогда как раз появится понимание когда его можно использовать, а когда не стоит.

Используйте только <=.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, Strob сказал:

Лучше не от безнадеги, а с терпением почитайте про блокирующие и неблокирующие присвоения. Мне кажется Вы создали себе проблему, а теперь героически ее решаете.

На некоторое время забудьте, что в always @(posedge clk) можно использовать =, ++, += и прочее. Когда у Вас возникнет потребность в подобном синтаксисе, тогда как раз появится понимание когда его можно использовать, а когда не стоит.

Используйте только <=.

Да я в принципе четко понимаю разницу между = и <=. Потому и начал и то и другое пробовать, что не совпала теория с практикой

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

++ можно использовать только в блокирующем присваивании.

Применяйте только то в чем уверены на 100%, чем проще, тем лучше.

Изменено пользователем lexx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, lexx сказал:

++ можно использовать только в блокирующем присваивании.

Применяйте только то в чем уверены на 100%, чем проще, тем лучше.

Есть разработчики "ремесленники", А есть разработчики "гении"...

"ремесленник" всегда применяет шаблон, там где этот шаблон надёжно работает и тогда всё, что не шаблон - там нужно искать ошибку..

соответственно, чем больше шаблонов, тем меньше вероятность появления ошибки в тексте.. А вот у "гениев" другая доктрина поведения. он пишется "шедевр". Но, к сожалению, часто этот шедевр не работает и искать место возникновения ошибки можно по всему тексту. соответственно гений проводит массу изысканий по тексту, чтобы выяснить, где будет работать и где не будет работать и так далее...

Ну а какой путь лучше, каждый для себя решает сам...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 hours ago, iosifk said:

"ремесленник" всегда применяет шаблон, там где этот шаблон надёжно работает и тогда всё, что не шаблон - там нужно искать ошибку..

Verilog довольно "короткий" язык,  там не  так и много шаблонов, особенно если мы говорим о синтезируемой области. Можно, что угодно говорить, но поиски "своего" пути это как этап обучения и рано или поздно приходишь к насыщению, повторно использовать "странные" конструкции языка всего лишь потеря времени.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

16 hours ago, iosifk said:

Есть разработчики "ремесленники", А есть разработчики "гении"...

Но есть еще разработчики-инженеры  которые пытаются понять почему и когда нужно применять те или иные шаблоны,  а когда надо и "гения" включать. 
А не тупо штамповать шаблонами потому что так кто-то когда-то сказал.  :sad:

On 7/12/2021 at 10:14 PM, alexPec said:

Да я в принципе четко понимаю разницу между = и <=. Потому и начал и то и другое пробовать, что не совпала теория с практикой

У вас в коде непонятно где и как как данные в ram_read_data попадают.  

 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По всей видимости, вам нужно конструкцию save_reg=ram_read_data; оформить в виде комбинационной логики. Для этого вынести это присваивание и условия в еще один

always @(*)

  if (условие)

         save_reg=ram_read_data;

 

Либо сделать save_reg как wire и оформить в виде тетрарной операции - нечто вроде

assign save_reg = (условие) ? ram_read_data : save_reg

 

Но в любом случае надо представлять, в виде каких конструкций этот код синтезируется.

Изменено пользователем vitzap

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...