Как сделать такой счетчик часов в Verilog HDL? - PullRequest
0 голосов
/ 08 июня 2018

Я хочу создать счетчик, который может начать отсчет с заданного сигнала.И как только он подсчитает 256, прекратите считать, установите счетчик в 0 и что-то выведите.

Я написал следующий код, но, очевидно, это вызовет ошибку «нескольких драйверов».

Но я не могу придумать другого пути.Может кто-нибудь дать идею?

always@(posedge a_specific_signal)
begin
    counter_switch <= 1;
end

always@(posedge clk)
begin
if (counter_switch  == 1)
    counter <= counter + 1;
if (counter == 256)  
    begin   
        counter <= 0;  
        counter_switch <= 0; 
        something <= 1; 
    end
end

Ответы [ 3 ]

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

Вот ваш счетчик, для 0 to 256 count.

module counter (clk, reset, op);
  input logic clk, reset;
  output logic [16:0] op;

  logic [16:0] current_cnt, next_cnt;

  assign next_cnt = (current_cnt[16]) ? 17'd0 : (current_cnt + 17'd1);
  assign op = current_cnt;

  always @ (posedge clk, negedge reset)
  begin
    if (~reset)
      current_cnt <= 17'd0;
    else 
      current_cnt <= next_cnt;
  end
endmodule

Так что, когда вы достигнете 256, ваш 17-й бит current_cnt будет равен 1, что означает, что ваш next_cnt должен быть 0. Вво всех остальных случаях ваш следующий счет должен быть + 1.

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

Ошибка «нескольких драйверов» возникает при попытке изменить сигнал от разных процессов / всегда блоков.Вы не должны этого делать.

Я привык работать с полностью синхронными системами, поэтому я должен спросить вас, что такое "a_specific_signal" и каково отношение к вашим основным часам.

Следовательно, мой подход будет следующим: 1. синхронизировать «a_specific_signal» с моими текущими часами, 2. определять положительные фронты, 3. использовать это как диск для флага для моего счетчика

reg a_spec_signal_reg0 = 1'b0, a_spec_signal_reg1 = 1'b0, a_spec_signal_reg2 = 1'b0;

always @(posedge clk) begin --synchronizer with 3 FFs
  a_spec_signal_reg0 <= a_specific_signal;
  a_spec_signal_reg1 <= a_spec_signal_reg0;
  a_spec_signal_reg2 <= a_spec_signal_reg1;
end

wire a_spec_signal_posedge;
assign a_spec_signal_posedge = a_spec_signal_reg1 & ~(a_spec_signal_reg2);

reg counter_switch = 1'b0;

always @(posedge clk) begin
  something <= 1'b0;
  if (a_spec_signal_posedge)
      counter_switch <= 1'b1;
  if (counter_switch) begin
      counter <= counter + 1;
      if (counter == 255) begin   
          counter <= 0;  
          counter_switch <= 0;
          something <= 1'b1;
      end
  end
end

Несколько замечаний: я предположил, что вы хотите посчитать 256 событий, что означает использование счетчика от 0 до 255 (8 бит).А также что-то сигнал установлен как 0 в его состоянии по умолчанию, поэтому, когда приходит условие «counter == 255», он выводит тик для всего тактового цикла, который обычно используется.

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

Нельзя изменить значение counter_switch в двух разных операторах always.Вы должны сделать это в том же блоке always.

Я бы сделал что-то вроде этого: (не проверял код может содержать ошибки)

input clock, reset;

reg counter_switch, ready;
reg [7:0] counter;

always@(posedge clock) begin
    if (reset) begin
        counter_switch <= 0;
    end else begin 
        if (a_specific_signal) begin 
            counter_switch <= 1;
        end else if (ready) begin
            counter_switch <= 0;
        end 
    end 
end

always@(posedge clock) begin
    if (reset) begin 
        ready <= 0;
        counter <= 0;
    end else begin
        if (counter_switch) begin 
            if (counter == 255) begin   
                counter <= 0;  
                ready <= 1; 
            end else begin 
                counter <= counter + 1;
            end
        end else begin 
            ready <= 0;
        end
    end
end
...