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.

8

4 Answers

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.

1

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 
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.

This is a very old post, but I stumbled on it while trying to solve a somewhat similar problem and there may be an alternate answer, depending on the exact situation. 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.

1

ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoaXBpZGqCdYSOmqSboZeqvLa%2FjJyjqJubYravecSvnKesXZi8r8DRqKM%3D