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

Борьба с Latches на verilog

Ну парни, всем спасибо, я устал возится с этим простейшим куском....

Чувствую себя неудавшимся кодером, потому как в графике нарисовал все за 5 минут и все работает..

Выложу, может пригодится или хоть настроение поднимет кому :)

module shift_reg
(
    input enable,
    input clr,
    input cpu_data_in, cpu_clk_in,
    output reg [263:0] sr = 0,
    output wire [8:0] bytenums
);

    reg [8:0] cntr;


assign bytenums = cntr;
     always @ (posedge cpu_clk_in or posedge clr) begin
            if (clr == 1'b1) begin
            cntr <= 9'd0;
            end
            else begin
            if (enable==1'b1) begin
              sr[263:1] <= sr[262:0];
              sr[0] <= cpu_data_in;
              cntr <= cntr + 1'b1;
              end
            end
      end


endmodule

 

module cntr264
(
    input enable,
    input clr, cpu_clk_in,
    output reg rec_ready
);

    reg [8:0] cntr;


     always @ (posedge cpu_clk_in or posedge clr) begin
            if (clr==1'b1) cntr <= 9'd0;
            else begin
              if (enable == 1'b1) begin
              cntr <= cntr + 1'b1;
              if (cntr == 9'd263) begin
                cntr <= 9'd0;
                rec_ready    <= 1'b1;
                end
            else rec_ready    <= 1'b0;
                
              end
              end
            
      end


endmodule

post-25041-1324363162_thumb.jpg

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


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

Попробуйте вот так:

module cpu_in
  (
      input enable,
      input cpu_data_in, cpu_clk_in,
      output reg [263:0] cpu_mess,
      output wire [8:0] bytenums
  );
  
      reg [263:0] sr = 0;
      reg [8:0] cntr;
  
  assign bytenums = cntr;
     always @(enable) begin  
       always @ (posedge cpu_clk_in) begin
                sr[263:1] <= sr[262:0];
                sr[0] <= cpu_data_in;
                cntr <= cntr +1;
       end
     end
     always @(negedge enable) begin
        if (cntr==9'd264) cpu_mess <= sr;
        cntr <= 0;
     end
    endmodule

Не знаю, скомпилируется ли. Нет под рукой компилятора.

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


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

Попробуйте вот так:

module cpu_in
   (
       input enable,
       input cpu_data_in, cpu_clk_in,
       output reg [263:0] cpu_mess,
       output wire [8:0] bytenums
   );
   
       reg [263:0] sr = 0;
       reg [8:0] cntr;
   
   assign bytenums = cntr;
      always @(enable) begin  
        always @ (posedge cpu_clk_in) begin
                 sr[263:1] <= sr[262:0];
                 sr[0] <= cpu_data_in;
                 cntr <= cntr +1;
        end
      end
      always @(negedge enable) begin
         if (cntr==9'd264) cpu_mess <= sr;
         cntr <= 0;
      end
     endmodule

Не знаю, скомпилируется ли. Нет под рукой компилятора.

 

Нее, не удается :(

Во-первых похоже не понравилось что always внутри другого always,

затем Error (10028): Can't resolve multiple constant drivers for net "cntr[8]" at cpu_in.v(20)

и еще кажется нельзя в одном модуле событие обрабатывать по enable и negedge enable

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


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

Во-первых похоже не понравилось что always внутри другого always,

затем Error (10028): Can't resolve multiple constant drivers for net "cntr[8]" at cpu_in.v(20)

и еще кажется нельзя в одном модуле событие обрабатывать по enable и negedge enable

Похоже на правду. Главное, что у вас все заработало уже :cheers:

Так наверно тоже ругаться будет на latch?

always @(negedge enable) begin  
   if (cntr==9'd264) cpu_mess <= sr;
   cntr <= 0;
end
always @ (posedge cpu_clk_in) begin
   if (enable) begin
      sr[263:1] <= sr[262:0];
      sr[0] <= cpu_data_in;
      cntr <= cntr +1;
   end
end

Изменено пользователем M@kar

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


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

Похоже на правду. Главное, что у вас все заработало уже :cheers:

Так наверно тоже ругаться будет на latch?

always @(negedge enable) begin  
    if (cntr==9'd264) cpu_mess <= sr;
    cntr <= 0;
end
always @ (posedge cpu_clk_in) begin
    if (enable) begin
       sr[263:1] <= sr[262:0];
       sr[0] <= cpu_data_in;
       cntr <= cntr +1;
    end
end

 

Ругается, но не на латч... А на несколько драйdеров cntr

Error (10028): Can't resolve multiple constant drivers for net "cntr[3]" at cpu_in.v(17)

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


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

Тогда так:

always @(negedge enable) begin  
    if (cntr==9'd264) cpu_mess <= sr;
end
always @ (posedge cpu_clk_in) begin
    if (enable) begin
       sr[263:1] <= sr[262:0];
       sr[0] <= cpu_data_in;
       cntr <= cntr +1;
    end
    else  cntr <= 0;
end

 

Хотя не, так он else cntr <= 0; не обнулит никогда. Тогда у меня только вариант с латчем уживаться:

always @ (posedge cpu_clk_in or negedge enable) begin
  if (enable) begin
    sr[263:1] <= sr[262:0];
    sr[0] <= cpu_data_in;
    cntr <= cntr +1;
  end
  else begin // if (!enable) begin
    if (cntr==9'd264) cpu_mess <= sr;
    cntr <= 0;
  end 
end

Его можно попробовать так убрать:

module cpu_in
  (
      input enable,
      input cpu_data_in, cpu_clk_in,
      output reg [263:0] cpu_mess,
      output wire [8:0] bytenums
  );
  
      reg [263:0] sr = 0;
      reg [263:0] temp = 0;
      reg [8:0] cntr;
  
  assign bytenums = cntr;

  always @ (posedge cpu_clk_in or negedge enable) begin
  if (enable) begin
    sr[263:1] <= sr[262:0];
    sr[0] <= cpu_data_in;
    cntr <= cntr +1;
  end
  else begin // if (!enable) begin
    if (cntr==9'd264) begin 
      cpu_mess <= sr;
      temp <= sr;
      cntr <= 0;
    end
        else begin 
          cntr <= 0;
          cpu_mess <= temp;
       end
  end
endmodule

Хотя так жаловаться на temp будет :rolleyes:

Изменено пользователем M@kar

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


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

Предполагаю, что вначале поднимается enable, потом 264 раза бьёт клок, потом enable опускается. Именно так типично управляется spi с микроконтроллера.

module cpu_in
(
     input enable,
     input cpu_data_in, cpu_clk_in,
     output reg [263:0] cpu_mess,
     output wire [8:0] bytenums
);

    reg [263:0] sr;
    reg [8:0] cntr;
    reg reset_count;
assign bytenums = cntr;
    always @ (posedge cpu_clk_in)
    begin
        if (enable)
        begin
            sr[263:1] <= sr[262:0];
            sr[0] <= cpu_data_in;
            if(reset_count)
                cntr <= 9'b0;
            else
                cntr <= cntr+1;
        end
    end
    always @(negedge enable)
    begin
        if(cntr = 9'd264)cpu_mess < sr;
    end
    always @(posedge cpu_clk_in or negedge enable)
        if enable = 1'b0 reset_count <= 1'b1;
        else reset_count <= 1'b0;

endmodule

Отдельно определяем регистр для cpu_mess, который защёлкивается по фронту enable,

и ещё специальный триггер для управления сбросом счётчика бит, который асинхронно устанавливается по уровню enable и сбрасывается после первого клока(который одновременно сбрасывает счётчик).

И не забывайте о синхронизации всего этого с системным клок доменом.

Ещё надо проверить конечное значение счётчика, которое может получится на 1 меньше, чем ожидалось.

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


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

Я могу быть не права, но обратите внимание вот на что:

1) У всех авторов в их кодах считается не 264 бита, а 265, поскольку счетчик cntr начинает считать с 0, а значение снимается по счету 264, т.е. всего 265 тактов. Это же явно видно по схеме в аттачах автора KWIer.

2) У автора KWIer был запрос был такой, перефразирую - когда enable будет держаться 264 тактов подряд - только тогда считать информацию на шине правильной, т.е. защититься от внезапных всплесков enable, так? Если так, то никто из авторов не позаботился о том, чтобы "неправильные данные" во время случайного всплеска не попали в регистр sr, а ведь он потом перейдет в cpu_mess. Может стоит обнулять sr, когда enable не находится в единичном состоянии 264 такта подряд?

3) Автор KWIer скажите мне, КАК вы умудрились на схематике подключить ШИНУ на однобитный вход триггера (DFF кажется) и не получить ошибок?

4) Автор Timmy кажется приблизил этот код к работоспособности, но (без компилятора, на глаз) вижу такое несоответствие задумке: поясню

ЕСЛИ (enable = 0) ТО (reset_count = 1) - указано явно

ЕСЛИ (enable = 1) ТО (reset_count = 0) - указано неявно через else

в другом же процессе происходит проверка ЕСЛИ ((enable = 1) И (reset_count = 1)) ТО (cntr = 0) - сгруппировано мной для наглядности.

Так вот, cntr похоже никогда так 0 не станет.

 

 

 

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


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

Я могу быть не права, но обратите внимание вот на что:

1) У всех авторов в их кодах считается не 264 бита, а 265, поскольку счетчик cntr начинает считать с 0, а значение снимается по счету 264, т.е. всего 265 тактов. Это же явно видно по схеме в аттачах автора KWIer.

2) У автора KWIer был запрос был такой, перефразирую - когда enable будет держаться 264 тактов подряд - только тогда считать информацию на шине правильной, т.е. защититься от внезапных всплесков enable, так? Если так, то никто из авторов не позаботился о том, чтобы "неправильные данные" во время случайного всплеска не попали в регистр sr, а ведь он потом перейдет в cpu_mess. Может стоит обнулять sr, когда enable не находится в единичном состоянии 264 такта подряд?

4) Автор Timmy кажется приблизил этот код к работоспособности, но (без компилятора, на глаз) вижу такое несоответствие задумке: поясню

ЕСЛИ (enable = 0) ТО (reset_count = 1) - указано явно

ЕСЛИ (enable = 1) ТО (reset_count = 0) - указано неявно через else

в другом же процессе происходит проверка ЕСЛИ ((enable = 1) И (reset_count = 1)) ТО (cntr = 0) - сгруппировано мной для наглядности.

Так вот, cntr похоже никогда так 0 не станет.

по 1)Я тоже обратил внимание в предыдущем посте, что 264 надо проверить и исправить:).

по 2)Случайные данные могут сколько угодно задвигаться в sr, в cpu_mess они не попадут, если enable держался не 264 клока. А потом полностью перезапишутся правильным пакетом в 264 клока.

по 4)Обращайте также внимание на условия выполнения процессов. В соответствии с ними reset_count безусловно и асинхронно устанавливается по низкому уровню enable, а сбрасывается по фронту clk при высоком уровне enable. Одновременно по тому же фронту clk сбросится и cntr, это не зря называется flip-flop.

Надеюсь, код типа

reset_count <= 1'b0;
if(reset_count==1'b1)cntr <= 9'b0;

не вызывает у Вас когнитивного диссонанса?:)

 

Ещё заметил, что я по VHDL-ной привычке иногда пишу "if" без скобок и = вместо ==.

 

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


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

по 1)Я тоже обратил внимание в предыдущем посте, что 264 надо проверить и исправитьsm.
Обращал внимание автора на это, он говорит так и надо. Спасибо вам за пример, а то я так и не сообразил.
Изменено пользователем M@kar

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


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

Надеюсь, код типа
reset_count <= 1'b0;
if(reset_count==1'b1)cntr <= 9'b0;

не вызывает у Вас когнитивного диссонанса?:)

 

Возможно, ввиду того, что редко использую latch в реализации, считаю что код вырван из контекста, хотя часто использую такой способ и неприятных ощущений он у меня не вызывает:

 

if(reset_count==1'b1)
begin
   cntr <= 9'b0;
   reset_count <= 1'b0;
end

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


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

считаю что код вырван из контекста

 

И Ваш тоже. Ибо все что Выше , предлагалось ввиде наброска без использования внутренней системной частоты. Что наложило свой отпечаток на реализацию в виде двух процессов always @(posedge cpu_clk_in) и always @(posedge cpu_clk_in or negedge enable), поэтому и разнесены по процессам reset_count и cntr.

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

 

Что касается Вашего вопроса по графическому редактору, то как известно параметризированные lpm функции занимают много места на листе ватмана, поэтому и используют одиночные примитивы, ибо если к одиночному примитиву подвести шину, квартус размножает этот примитив до разрядности этой шины.

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


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

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

На всякий случай выкладываю финальную редакцию твоего кода.

 

Я могу быть не права, но обратите внимание вот на что:

1) У всех авторов в их кодах считается не 264 бита, а 265, поскольку счетчик cntr начинает считать с 0, а значение снимается по счету 264, т.е. всего 265 тактов. Это же явно видно по схеме в аттачах автора KWIer.

...

3) Автор KWIer скажите мне, КАК вы умудрились на схематике подключить ШИНУ на однобитный вход триггера (DFF кажется) и не получить ошибок?

...

1) в реализации у Timmy, условие действительно должно быть if(cntr == 9'd263), чтобы считать ровно 264 клока (симуляция во вложении), так как счетчик увеличивается лишь по второму импульсу клока.

А вот в моей первой реализации по первому переднему фронту клока сдвигался 1 бит и счетчик становился равным 1, соответственно счетчик = 264 когда сдвинуто 264 бита, а не 265.

Можете провести сравнение двух симуляций в посках различий в поведении счетчиков :)

 

3) Quartus такие действия разрешает, если на входе и выходе DFF шина одинаковой ширины, он создает массив триггеров.

 

Еще раз всем спасибо! :santa2:

Вопрос можно считать решенным, а тему - завершенной

cpu_in.v

post-25041-1324618837_thumb.jpg

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

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


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

Что касается Вашего вопроса по графическому редактору, то как известно параметризированные lpm функции занимают много места на листе ватмана, поэтому и используют одиночные примитивы, ибо если к одиночному примитиву подвести шину, квартус размножает этот примитив до разрядности этой шины.

3) Quartus такие действия разрешает, если на входе и выходе DFF шина одинаковой ширины, он создает массив триггеров.

 

Ух ты! Забавно, что Квартус так умеет, не знала, спасибо)

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


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

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

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

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

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

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

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

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

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

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