Reputation: 37
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
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
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
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
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