K2082
K2082

Reputation: 37

ambiguous clock in event control

I wrote such verilog code in xilinx vivado:

module a(input clk, input clk1, output reg [4:0] acc)
initial
begin
acc = 5'd0;
end
always @ (posedge clk or posedge clk1)
begin
acc <= acc+1;
end
endmodule  

And the error (ambiguous clock in event control) came out when runnning synthesis, and vivado points out that error is in the line "always @ (posedge clk or posedge clk1)". Only one error occurred. I wonder why this error come out and how to solve it without changing function of my code. As you can see, I'd like to do something when clk or clk1 turns from 0 to 1.

Upvotes: -1

Views: 17218

Answers (4)

Wilton Helm
Wilton Helm

Reputation: 1

There is a case where two "clocks" can be used with the same FF. It is called asynchronous reset (or preset). The "ambiguity" is resolved by creating a priority.

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

For a more nuanced case consider the case of an alarm clock where there is a button to accelerate the counting for setting it. I'll not address the metastability issues and bounce issues, but the following example should illustrate the concept.

always @ (posedge clk or posedge btn) begin
    if (button)
        count <= count + 1;
    else
        count <= count + 1;
    end
end

While it looks redundant, it should generate an asynchronous load from an adder in the first case and normal FF operation in the second. The key point to both code snippets is that when there are two edge triggered "clocks" in a sensitivity list, the code inside must include one of them in an if .. else clause that clearly specifies the priority. The one given the priority becomes an asynchronous preset or reset that blocks the other from having any impact as long as it is asserted.

Upvotes: -1

A Q
A Q

Reputation: 166

module a (
      input clk, 
      input clk1, 
       output reg [4:0] acc = 5
         );
always @ (posedge clk or posedge clk1)
begin
     if(clk | clk1)
        acc <= acc+1;
     else
        acc <= acc;
end
endmodule 

This should work. It gives an ambiguous clock error if we put our signal in as clock for the always block. We again need to specify it using if else in the block.

Upvotes: -1

Morgan
Morgan

Reputation: 20514

On the understanding that your clk and clk1 are input from buttons, you need to give your clk and clk1 better names. for the rest of this answer I will refer to them as btn1 and btn2. You also need to configure a clock fast enough to capture these button presses.

Button inputs normally need to be debounced or at a minimum edge detection put in place so you only increment once for a given button press.

//Button 1 meta stability
logic [2:0] meta_edge_det_btn1;
always @(posedge clk) begin
   meta_edge_det_btn1 <= {meta_edge_det_btn1[1:0], btn1} ;
end

//button 1 Positive edge detection
logic btn1_rise;
always @* begin
   btn1_rise = meta_edge_det_btn1[1] & ~meta_edge_det_btn1[2];
end

logic [2:0] meta_edge_det_btn2;
always @(posedge clk) begin
   meta_edge_det_btn2 <= {meta_edge_det_btn2[1:0], btn2} ;
end

logic btn2_rise;
always @* begin
   btn2_rise = meta_edge_det_btn2[1] & ~meta_edge_det_btn2[2];
end

//Increment if either of the buttons has been pressed
always @ (posedge clk) begin
  if (btn1_rise  | btn2_rise ) begin
    acc <= acc+1;
  end
end

Upvotes: 2

Coral9 Consulting
Coral9 Consulting

Reputation: 34

you are describing hardware using verilog. as pointed above, one flip-flop cannot be driven by two separate clocks. you will have to use 2 separate always blocks, one sensitive to clk and other to clk1.

e.g

always @ (posedge clk)
begin 
// your verilog statements here, driven by clk
end

always @ (posedge clk1)
begin 
// your verilog statements here, driven by clk1
end

Hope this helps.

Upvotes: 1

Related Questions