I have a problem with an "always" block in Verilog. First let me present the code:
module syncRX(clk, signal, detect, output clk_1khz);
input clk, signal;
output reg [7:0] detect = 0;
//wire clk_1khz;
freq_div div(.clk(clk), .clk_1khz(clk_1khz));
always @(posedge signal, posedge clk_1khz)
begin
detect <= detect + 1;
end
endmodule // top
module freq_div(input clk, output reg clk_1khz);
reg [12:0] count = 0;
always @(posedge clk)
begin
if(count == 6000)
begin
clk_1khz <= ~clk_1khz;
count <= 0;
end
else
count <= count + 1;
end
endmodule
I got this error message (using Icestorm):
2.3.7. Executing PROC_DFF pass (convert process syncs to FFs). Creating register for signal
\freq_div.\clk_1khz' using process
\freq_div.$proc$syncRX.v:22$4'. created $dff cell$procdff$15' with positive edge clock. Creating register for signal
\freq_div.\count' using process\freq_div.$proc$syncRX.v:22$4'. created $dff cell
$procdff$16' with positive edge clock. Creating register for signal\syncRX.\detect' using process
\syncRX.$proc$syncRX.v:8$1'. ERROR: Multiple edge sensitive events found for this signal! make: *** [Makefile:44: syncRX.bin] Error 1
I could detect that the "always" block involved is:
always @(posedge signal, posedge clk_1khz)
begin
detect <= detect + 1;
end
becaise if change "always @(posedge signal, posedge clk_1khz)" for "always @(posedge signal)" works.
Also fails in that same way:
always @(posedge signal)
begin
detect <= detect + 1;
end
always @(posedge clk_1khz)
begin
detect <= detect + 1;
end
And the error disappears when comment the line "detect <= detect + 1;" in bought of cases. Then the error is related to the access to the "detect" counter register. I have not idea why I can not trigger this counter from two different signals, but in fact, I have to increase the counter in bought post edge signals (and I can figure out in my mind a very simple digital circuit doing this), and I found many examples in Verilog using a "always" block with two posedges triggers... But mine dont works.
Please, if anyone can explain me why dont work and how I can do it. It will be extremely useful for me.
I guess you can use separate counters for each clk_1khz and signal. Then just add them:
always @(posedge signal)
begin
detect_sig <= detect_sig + 1;
end
always @(posedge clk_1khz)
begin
detect_clk <= detect_clk + 1;
end
assign detect = detect_sig + detect_clk;
Though, @(posedge signal)
looks strange to me. You should not use anything but clocks here. So, check your algorithm.
And, you should also simulate and verify your model before synthesizing.
Since you asked this in another question, your second variant with 2 different always blocks is not synthesizable either. It results in the detect
signal driven by multiple always blocks and causing a multiply-driven condition in synthesis. In simulation it will cause non-deterministic results. synthesis should break. Check messages.