Как стать автором
Обновить

Комментарии 19

Все это дает основания полагать....

Все это дает основание предполагать, что нормальные люди используют асинхронный ресет триггеров в схеме, по включению питания, а не городят костыли :)

reg[7:0]

always (posedge async_rst_i, posedge clk) begin
   if(async_rst_i) reg <= 8'b1010_0101;
   else            reg <= ХХ;
end

Ну тогда уж и схему приложите.
У Вас сброс с тактами местами перепутаны. И «уха» между always и скобками нет.
А ещё регистр неправильно объявлен. И, кстати говоря, сигнала сброса в конструкции нет — его тоже нужно предварительно сформировать. В остальном согласен — правильнее делать так, как Вы сказали.
Схему чего? Того как синтезируется и разложится в фпга конструкция, которую я привел?
Поясните пожалуйста, я не понял.
Схему, которая подключена ко входу async_rst_i
Сигнал сброса можно сформировать из регистра. Так как инициализация регистров по включению питания в MAX7000 выполняется только в ноль, то сигнал сброса можно сделать так:

reg pon_reset_reg = 0;

always @( posedge clk )
  pon_reset_reg <= 1'b 1;

То есть сброс получился отрицательным. Соответственно в других always в качестве сброса нужно будет использовать negedge pon_reset_reg:

always @( posedge clk, negedge pon_reset_reg )
begin
  if( !pon_reset_reg )
  begin
    // Здесь инициализируем регистры в то, что надо.
  end
  else
  begin
    // Здесь выполняем действия по фронту тактов
  end
end

Уже после того, как написал, заметил, что Вы сброс уже сформировали, причём целый счётчик для этого дела замутили :) Думаю, одного такта будет достаточно (как в моём примере). Проверьте.
Господин выше все правильно описал, да.
Если есть возможноть сделать кнопку, то общесхемный асинхронный ресет триггеров заводят на неё (правда после кнопки конечно нужно будет поставить триггер, подзащелкивающий этот ресет, чтобы он случайно не попал на фронт клока).
Если нет возможности сделать кнопку, то да, как описано ниже — через initial. Но вообще я бы старался максимально избавляться от initial-ов для триггеров. Это костыль. А для ASIC так вообще несинтезируемая конструкция

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

Что-бы этого избежать надо загнать асинхронный сброс в нужный клоковый домен. Для этого сделать цепочку из двух триггеров, на вход первого повесить единицу, а асинхронный сброс подавать на вход асинхронного сброса этих двух триггеров. А вот всю остальную схему сбрасывать подавая выход «синхронизатора» на асинхронный вход остальных триггеров. Так получается что и волки сыты и овцы целы триггеры выставятся в начальное состояние одновременно, по фронту клока. То есть сохранятся все плюсы синхронного сброса, но при этом без лишней логики о которой вы говорите.
Окей shvlad, а чем вам не понравилось мое описание той же концепции?
(правда после кнопки конечно нужно будет поставить триггер, подзащелкивающий этот ресет, чтобы он случайно не попал на фронт клока).

Боитесь что на выходе синхронизатора может возникнуть метастабильность?
Не могу сказать, что мне не понравилось, просто разница есть. Как я понял вы подаете асинхронный сброс на D вход триггера, а я описал примерно тоже но с входом асинхронного сброса. Такой способ есть в рекомендациях производителей FPGA=)
Скорее всего такая концепция предложена чтобы избежать метастабильности на выходе синхронизирующего триггера в момент установки ресета. Ну типа вот в моем случае, с подачей ресета на D вход, может сложиться такая ситуация, что ты зажал кнопку слишком близко к фронту частоты, и на выходе, на ближайший такт, получил ни рыбу ни мясо. В итоге часть триггеров у тебя асинхронно сбросится на этом такте, а часть только на следующем, когда метастабильность пропадет. Навскидку не могу придумать ситуации когда это окажется критичным.
Хм… Я был уверен что это
общесхемный асинхронный ресет триггеров заводят на неё (правда после кнопки конечно нужно будет поставить триггер, подзащелкивающий этот ресет, чтобы он случайно не попал на фронт клока).
подразумевает, как минимум два триггера. Если один, то это не самая хорошая идея, в сети и в частотности на этом ресурсе по метастабильности много информации и даже есть выкладки с вероятностью попасть в такое состояние и для одного триггера она не такая уж и маленькая.
Ну типа вот в моем случае, с подачей ресета на D вход, может сложиться такая ситуация, что ты зажал кнопку слишком близко к фронту частоты, и на выходе, на ближайший такт, получил ни рыбу ни мясо. В итоге часть триггеров у тебя асинхронно сбросится на этом такте, а часть только на следующем, когда метастабильность пропадет. Навскидку не могу придумать ситуации когда это окажется критичным.

Это для когда мы зажали кнопку, а что будет когда мы ее отпустили? ;-) Часть схемы стартовала, а часть еще в reset и привет…
Так что думаю производители рекомендуют такой способ из других соображений.
Да, все правильно, мой косяк)
Оформлю сказанное в виде кода (для отрицательного сброса):

reg [1:0] reset_reg = 0;

// Формирователь сброса
always @( posedge clk, negedge reset_n_i )
begin
  if( !reset_n_i )
    reset_reg <= 0;
  else
    reset_reg <= { reset_reg[0], 1'b 1 };
end

// Остальные always
always @( posedge clk, negedge reset_reg[1] )
begin
  if( !reset_reg[1] )
    //
  else
    //
end
Раз уж пошла такая пьянка, то пусть тема будет совсем завершена =) Прикрепляю картинки из мануалов Альтеры и Ксайлинкса

Тиристоры же, никто не любит шумных гирлянд.
В школе когда-то собрал секвенсор на жёсткой логике подключенный к клавишам «электропианино» релюшками. В чём то даже было прикольное совмещение с ударными:)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории