-1

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.

K2082
  • 37
  • 1
  • 1
  • 3
  • Do you have flip-flops that can be triggered by two clocks? if not what hardware are you trying to describe? – Morgan Nov 26 '14 at 10:20
  • @Morgan a clock. clk indicates every second and clk1 can adjust time. – K2082 Nov 26 '14 at 10:59
  • @Morgan maybe I misunderstood what u said. Just a filp-flop triggered by two clocks is also ok. – K2082 Nov 26 '14 at 11:10
  • I have never seen a flip-flop that can accept 2 clocks like that, which would explain the error you are getting. The verilog is describing Hardware I doubt that you have a cell in your synthesis library that can accept that. SO vivado has to try hook up a single clk flip-flop and it does not know which clock to use (ambiguous clock). May be post more of an example. – Morgan Nov 26 '14 at 11:15
  • @Morgan I tried @(posedge clk, posedge clk1) but it doesn't work. The same problem ocurred. – K2082 Nov 26 '14 at 18:17
  • @Morgan sorry for misunderstood again. what i'd like to do is a accumulator which can increase when clk1 or clk. I'll show my entire code later. – K2082 Nov 26 '14 at 19:01
  • Could you add some information on the rates of `clk` and `clk1`. You really need to move to a single clock design. If you could explain why you have two clocks, we might be able to have the two domains setting an single enable. – Morgan Nov 26 '14 at 19:45
  • @Morgan clk and clk1 are two separate buttons. they control the same accumulator. – K2082 Nov 27 '14 at 03:32

4 Answers4

1

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.

George G
  • 7,443
  • 12
  • 45
  • 59
  • it seems that a reg variable cannot be used in two different always blocks? another error "Rule violation (MDRV-1) Multiple Driver Nets" came out. – K2082 Nov 26 '14 at 18:37
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
Morgan
  • 19,934
  • 8
  • 58
  • 84
-1
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.

A Q
  • 166
  • 2
  • 13
-1

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.

toolic
  • 57,801
  • 17
  • 75
  • 117
  • This will not. If synthesized, it would have an asynchronous feedback loop. Most synthesizers require a constant expression for the assignment in the asynchronous component of a flip-flop. The cleanest solution is to synchronize the inputs to a true clock and detect input transition (like Morgan's answer). An alternate solution would have a counter per clock domain then combining them (`assign acc = acc_clk + acc_clk1`), but this has timing risk for down stream logic. – Greg May 24 '23 at 17:35