Можно ли синтезировать события фронта часов внутри всегда блоков в verilog? - PullRequest
0 голосов
/ 01 июня 2018

У меня есть два часа, clk0 и clk1.Я хочу, чтобы счетчик рассчитывал на позицию clk0, но сбрасывал на позицию clk1.Важно отметить, что сброс должен происходить только в позиции, а не при высоком значении clk1.Поэтому приведенный ниже код невозможен.

always @(posedge clk0 or posedge clk1)
begin
     if (clk1)
              count <= 0;
     else
              count <= count + 1;
end

Мы также не можем управлять счетчиком из двух блоков.Поэтому нижеприведенное невозможно:

always @ (posedge clk0)
begin
     count <= count + 1;
end

always @ (posedge clk1)
begin
     count <= 0;
end

Итак, мой вопрос: что предлагает аналогичную функциональность, такую ​​как

always @(posedge clk0 or posedge clk1)
begin
     if (posedge clk1)
              count <= 0;
     else
              count <= count + 1;
end

И является ли она синтезируемой?

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

1 Ответ

0 голосов
/ 01 июня 2018

Вам нужно перенести 'событие' из clk1 в clk0.Это проблема пересечения области часов и поэтому требует синхронизации.

reg clk1_meta,clk1_sync,clk1_prev;
always @(posedge clk0 or negedge reset_n) // async low reset as example
begin
   if (!reset_n)
   begin
      clk1_meta <= 1'b0; 
      clk1_sync <= 1'b0; 
      clk1_prev <= 1'b0;
      counter   <= 'b0;       
   end
   else
   begin
      // transfer clk1 to clk0
      clk1_meta <= clk1;
      clk1_sync <= clk1_meta;

      // Now we have a safe signal: clk1_sync          
      clk1_prev <= clk1_sync;
      // A rising edge is when clk1_sync1 is high but previously it was low
      if (clk1_sync==1'b1 && clk1_prev==1'b0)
         counter <= 'b0;
      else
         counter <= counter + 1;
   end
end

Неизбежная задержка составляет ~ 2 тактовых цикла clk0, прежде чем clk1 поступит в домен clk0 из-за синхронизации.

...