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

О синхронных схемах

Добрый день.

Последний год, делая проекты на ПЛИС, я придерживался правила, что в момент переключения триггера все сигналы на его входе должны быть постоянны. Поэтому, когда работал с каскадом, триггер за триггером, то условно говоря четные переключались по передним фронтам, а нечетные по задним. Таким образом я всегда был уверен, что на входе тригера в момент переключения все стабильно.

 

Эту идею тут на форуме раскритиковали, сказав, что такой дизайн получается плохим и надо делать все по одному фронту, а задержка и так будет, синтезатор все за меня сделает. Я попробовал эту технику и у меня возникли вопросы.

 

Для простоты рассмотрим сферического коня в вакууме - регистр сдвига на трех триггерах.

c4bc03f8145f.png

 

По своей прошлой методике я бы переключал 1 и 3 по переднему фронту, 2 по заднему. Попробовал описать все переднему фронту.

 module SHIFTER
     (input INP,CLK,RST,
     output OUTP);

    reg s1,s2,s3;
    


    always @(posedge CLK)
        begin
            if (RST)
                begin
                  s1=0;
                end
            else
                s1=INP;
            end
    always @(posedge CLK)
        begin
            if (RST)
                begin
                  s2=0;
                end
            else
                s2=s1;
            end
    always @(posedge CLK)
        begin
            if (RST)
                begin
                  s3=0;
                end
            else
                s3=s2;
            end
        
assign OUTP=s3;
endmodule

И вот что получается, если я делаю пост-синтезную или пост-разводочную симуляцию, то все ожидаемо хорошо, Time Analyzer проблем не находит, WaveForm соответствует ожидаемой - задержка выхода от входа на 3 такта.

346590f13b73.png

Однако, пред-синтезная, функциональная симуляция, так же ожидаемо не проходит, никакой задержки на 3 такта нет, так как для логического синтеза никакой задержки на распространение нет и сигнал пролетает "насквозь" все 3 триггера.

396e3610b607.png

 

У меня вопросы

1) Чем же плоха система "четные по фронту, нечетные по спаду", кроме того, что мне надо держать в голове какой по какому фронту работает? Я вижу очевидный плюс, в том что я знаю точно, что когда переключается, исключается "гонка сигналов", так всегда есть время на распространение равное в пол-такта. Так же получается, что система работает на удвоенной частоте, тогда как физическая частота прежняя -> меньше потребляемая мощность, нет?

2) Если работать по одному фронту, то получается, что я вынужден полностью отказаться от предсинтезной симуляции, так как ее результаты не соответствуют реальности. Но это сразу значительно усложняет процедуру симуляции, после каждого изменения кода запускать синтез. Да или нет?

3) Я что то делаю не так? Можно ли при функциональном моделировании задать некую каждому триггеры условную "задержку", чтобы результаты досинтезного моделирования соответствовали постсинтезному?

 

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


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

1).Очевидно,что в таком случае максимальная тактовая снизится в 2 раза.

2) и 3) непонятно о чём речь,никогда таких проблем не видел.Я делаю только функциональную симуляцию,времянки смотрю по отчёту STA.

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


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

_Anatoliy - Функциональная симуляция - нет задержки, результат неверн, постсинтезная - есть задержка, результат соответствует ожидаемому. Результат на скринах. На лицо проблема. Как быть?

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


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

Как быть?

 

1. начать наконец то писать регистровую логику правильно, с помощью неблокирующих присвоений %)

2. в чистом верилоге, есть неопределенность движка в исполнении присвоений, поэтому часто в V проектах делали так

 

`timescale 1ns/1ps

parameter T = 1; 

always @(posedge clk) begin 
  pipa <= #T popa; 
end

 

этим моделировали Tco триггера. В SV проектах этого делать ненадо, при использовании always_ff. Более того, это запрещено стандартом, хотя я видел код, где сделано именно так %)

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


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

masics, ого, помогло! Спасибо! Пойду читать про операторы присваивания :-)

 

des00 2. в чистом верилоге, есть неопределенность движка в исполнении присвоений, поэтому часто в V проектах делали так

Я только начинаю кодить на Verilog'e, поэтому прошу прощения, если ответ на мой вопрос содержиться в мануалах, но зачем делать эту задержку в #T, если при смене оператора присваивания = на <= все заработало нормально? И во что потом синтезируется вот эта конструкция? pipa <= #T popa; ? Сообразит ли синтезатор выкинуть эту искуственную задержку?

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


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

Я что то делаю не так?

always@(posedge clk) 
  a=b;
always@(posedge clk) 
  b=a;

эквивалентно либо:

always@(posedge clk) begin 
  a=b;
  b=a;
end

либо:

always@(posedge clk) begin 
  b=a;
  a=b;
end

- как кости лягут.

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

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


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

зачем делать эту задержку в #T, если при смене оператора присваивания = на <= все заработало нормально?

это в вашем текущем симуляторе заработало нормально, а каком нить икарус верилоге может вылезти %) Кроме того, некоторым разработчикам нравиться зырить вейвформы близкие к железу.

 

И во что потом синтезируется вот эта конструкция? pipa <= #T popa; ? Сообразит ли синтезатор выкинуть эту искуственную задержку?

синтезаторы игнорируют все конструкции контроля времени и все синтезируется как надо. Но вообще от вас удивительно слышать подобное %)

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


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

Я правильно понимаю, что разница между = и <= в Верилоге такая же, как в VHDL? Первое присваивает передает переменной значение в тот же момент, в VHDL применимо для variable, а второе выполняется по завершению процесса, то есть как к Signal в VHDL. Все так?

 

Leka А вот такой код

always@(posedge clk) begin
  b<=a;
  a<=b;
end

2 триггера, соединенных в кольцо.

 

По аналогии с VHDL - так как переменная непонятно во что синтезируется, то старался их использовать крайней ограничено, только для счетчиков. Правильно ли я понимаю, что в Верилоге присваивание = синтезируется непонятно как, и надо стараться пользовать <=?

 

 

 

des00 Системами контроля времени я пользовался только в ТестБенчах, поэтому даже из люопытства не пробовал их скармливать синтезатору, поэтому спросил :-)

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


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

Правильно ли я понимаю, что в Верилоге присваивание = синтезируется непонятно как, и надо стараться пользовать <=?

 

Неправильно. У Полякова почитайте об этих операторах.

В Вашем примере и функциональная симуляция должна соответствовать временной. Ибо все в разных процессах описано.

(Посмотрите, сколько триггеров реально получилось на вашем целевом кристалле).

module shifter
(
input INP,CLK,RST,
output OUTP
);

reg s1,s2,s3;

always @(posedge CLK)
begin
if (RST)
    begin
    s3=0;
    s2=0;
    s1=0;
    end
else
    begin
    s3=s2;
    s2=s1;
    s1=INP;
    end
end

assign OUTP=s3;

endmodule

 

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


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

sazh, по коду приведенному коду получилось 3 триггера, то что насинтезировалось представлено на 1 рисунке. Sinplify Synthethis.

 

А в 2 словах можно, почему нет? Пока я вижу, что все именно так. В приведенном вами коде действительно синтезируется 3 триггера, так как присваивания выполняются тут же, от старшего к младшему, одно за другим. Однако если написать в обратном порядке s1=INP .... SN=SN-1, то все промежуточные Sk синтезатор выкидывает и сразу присваивает вход выходу, синтезирует 1 триггер.

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


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

по коду приведенному коду получилось 3 триггера, то что насинтезировалось представлено на 1 рисунке. Sinplify Synthethis.

 

Тогда и задержка должна быть на 3 такта.

Короче используйте оператор <= и не заморачивайтесь с порядком описания в одном процессе.

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


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

По аналогии с VHDL - так как переменная непонятно во что синтезируется
Не надо ля-ля. Всё там понятно.

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


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

Кстати, ещё надо писать always @(posedge clk or posedge rst),

а то сброс проходит неправильно, что видно на диаграммах.

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


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

У меня вопросы

1) Чем же плоха система "четные по фронту, нечетные по спаду", кроме того, что мне надо держать в голове какой по какому фронту работает? Я вижу очевидный плюс, в том что я знаю точно, что когда переключается, исключается "гонка сигналов", так всегда есть время на распространение равное в пол-такта. Так же получается, что система работает на удвоенной частоте, тогда как физическая частота прежняя -> меньше потребляемая мощность, нет?

2) Если работать по одному фронту, то получается, что я вынужден полностью отказаться от предсинтезной симуляции, так как ее результаты не соответствуют реальности. Но это сразу значительно усложняет процедуру симуляции, после каждого изменения кода запускать синтез. Да или нет?

3) Я что то делаю не так? Можно ли при функциональном моделировании задать некую каждому триггеры условную "задержку", чтобы результаты досинтезного моделирования соответствовали постсинтезному?

 

 

1) Mожете описать сдвиговый регистр нагляднее (используя <= ):

 

reg [2:0] shift_rg;

always @(posedge CLK posedge RST)
begin
            if (RST)
                 shift_rg[2:0] <= {3{1'b0}};
            else
                // Сдвиг влево
                shift_rg[2:0] <= {shift_rg[1:0],INP};

end
        
assign OUTP=shift_rg[2];

 

2) "Чем же плоха система "четные по фронту, нечетные по спаду" - тем что максимальная тактовая частота в 2 раза ниже

3) " я знаю точно, что когда переключается, исключается "гонка сигналов", так всегда есть время на распространение равное в пол-такта" - это очень большое заблуждениен!

При роботе по одному фронту - у Вас будет аж ЦЕЛЫЙ такт.

Время распространения контролируется синтезатором (точнее плейсером+роутером+clock tree инсертером) а никак не Вами.

В этом и есть суть синхронного дизайна и забота тулзы.

Подумайте, как увеличение задержки в линии влияет на HOLD тайм destination тригера - улутшает или ухудшает это требование?

4) "физическая частота прежняя -> меньше потребляемая мощность" мощность потребления зависит от КОЛИЧЕСТВА и ЧАСТОТЫ переключения тригеров. В Вашем случае, количество=конст и частота переключения=конст. Мощность потребления=клнст соотв.

5) "Если работать по одному фронту, то получается, что я вынужден полностью отказаться от предсинтезной симуляции, так как ее результаты не соответствуют реальности" - а зачем-же по Вашему существуют RTL симуляторы? У Вас просто ошибка в коде.

6) "Можно ли при функциональном моделировании задать некую каждому триггеры условную "задержку", чтобы результаты досинтезного моделирования соответствовали постсинтезному?" - Можна, но не нужно. В технологии <=0.35u существенно влияют задержки в линии чем задержки гейта. Их как задавать будете (после синтеза все цепи обычно переименовываються)?

 

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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