简体   繁体   中英

How do I toggle a sample clock every n clock cycles?

I am new to Verilog, so I am not sure how to go about doing this. I have a clock, 'samp_clk', that toggles every 10 clock cycles of the system clock, 'clock' (or that's what I tried to do). This is what I have so far:

     //'counter' counts the number of rising edges for system clock
     //'samp_clk' is the sample clock, 'clock' is system clock
     always @ (posedge clock)begin
           if(~reset)begin
                 if(counter == 10)begin
                        samp_clk <= 1;
                        counter <= 0;
                 end
                 else begin
                        samp_clk <= 0;
                        counter <= counter + 1;
                 end
           end
      end

The way I wrote it, I feel like my samp_clk will only stay asserted for one clock cycle. How can I make it so that it toggles between 1 and 0 every ten clock cycles?

You want to toggle it, so toggle it.

Also note that to toggle every 10 clocks, you will have to set your counter to 0 when its value is 10-1.

Try this (not tested):

//'counter' counts the number of rising edge s for system clock
//'samp_clk' is the sample clock, 'clock' is sy stem clock
always @ (posedge clock)begin
    if(~reset)begin
        if(counter == 9)begin
            samp_clk <= ~samp_clk;
            counter <= 0;
        end
        else begin
            counter <= counter + 1;
        end
    end
    else begin
        samp_clk <= 0;
    end
end

From your code:

             if(counter == 10)begin
                    samp_clk <= 1;
                    counter <= 0;
             end

This will result to 11 clock cycles since we start counting from 0 to 10.

First step, define a counter wherein it resets to a certain number (clock cycles). For example, you want to detect 10 clock cycles (n = 10), when counter is more than or equal to 9, it sets back to 0.

 always @ (posedge clk)begin
       if(~reset)begin
         counter <= 0;
       end
       else begin
         if(counter >= 9)begin
                    counter <= 0;
             end
             else begin
                    counter <= counter + 1;
             end
       end
 end

Then simply, toggle samp_clk based from the counter when it's equal to n-1 (10 - 1 = 9).

always @(posedge clk) begin
  if (~reset) begin
    samp_clk <= 0;
  end
  else begin
    if (counter == 9) begin
        samp_clk <= ~samp_clk;
    end
  end
end

Notice that I've separated two flip-flops to make debugging easy and clear enough to understand its logic.

Here is the code with a test bench included.

module ten_clock(input clk, reset, output reg samp_clk);
  reg [7:0] counter;
     //'counter' counts the number of rising edges for system clock

     always @ (posedge clk)begin
           if(~reset)begin
             counter <= 0;
           end
           else begin
             if(counter == 10)begin
                        //samp_clk <= 1;
                        counter <= 0;
                 end
                 else begin
                        //samp_clk <= 0;
                        counter <= counter + 1;
                 end
           end
     end

  //'samp_clk' is the sample clock, 'clock' is system clock
  always @(posedge clk) begin
    if (~reset) begin
      samp_clk <= 0;
    end
    else begin
      if (counter == 9) begin
        samp_clk <= ~samp_clk;
      end
    end
  end

endmodule

module test;
  reg clk, reset;
  wire samp_clk;
  ten_clock ten_clock(.*);

  initial begin
    clk = 0;
    forever #1 clk = !clk;
  end

  initial begin
    reset <= 1;
    repeat (2) @(posedge clk);
    reset <= 0;
    repeat (2) @(posedge clk);
    reset <= 1;

    repeat (100) @(posedge clk);
    $finish;
  end

  initial begin
    $dumpfile("dump.vcd"); $dumpvars;
  end
endmodule

You can try to run this code and see the wave form if this behavior is what you expect.

在此处输入图片说明

You are correct, this code sets samp_clk to be 1 when the counter is 10 and otherwise sets it to 0 . This means you will have a signal which is asserted for 1 clock cycle and low for 10 clock cycles. The basic logic is correct (count for 10 clock cycles) but the value given to samp_clk is incorrect.

What you want to have is that samp_clk is the same value as it was in the previous cycle if counter ins't 10 and to flip samp_clk when it is. To flip a signal you want to assign the signal to the inverse of a signal: samp_clk <= ~samp_clk .

After you have that working you might need to refactor your code because I think it is going to produce latches in its current state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM