# Verilog: Check for two negedges in always block

i try to do something like this:

always @ (negedge speed_dec or negedge speed_inc)
begin
do something
end


This doesn't work as checking for 2 negative edges is to demanding and results in only checking for the clock.

I tried do do the check manually:

    reg old_key0;
always @ (KEY[0])
begin
if(KEY[0] == 1  & old_key0 == 0)
do something
old_key0 = KEY[0];
end


But now it completely stops working. Can anyone spot the error?

The always@ is a sensitivity list and generally not a checking list i.e. it doesn't work as an if-else block.

Instead, it indicates when the register/latch specified in the block needs to change states, typically on a clock edge (register) or level change (latch).

If you're trying to detect an edge on an input, such as for an interrupt detection, the recommended way is to synchronise the edge to an internal shift register.

It could be as simple as this:

reg [1:0] det_edge;
wire sig_edge;
assign sig_edge = (det_edge == 2'b10);
always @(posedge clk)
begin
det_edge <= {det_edge[0], input};
end


Then, you can do whatever you want with the edge signal, possibly as an enable signal to a state machine or other block that does something with your device (such as flagging the interrupt).

So, for your application, you may want to do the above twice and then use the two edge detect signals to control some other device/block.

The key point to remember with all HDL work is that HDL stands for Hardware Description Language. It is a replacement for schematics, not software.

For starters, I would recommend starting with the hardware and then translate that into code i.e. draw the schematic and then write the HDL that describes that circuit schematic.

• ok i hope i understood you correctly. instead of input i put KEY[0] in there. i also did another always block with the edge to alter some values. the problem is that i have two buttons, one to increase and one to decrease a value. i have to check this in one step because else, the compiler complains that i could press both buttons at the same time and would alter the same register with two functions simultaneously. – Nicolas Feb 12 '12 at 16:39
• your problem has nothing to do with edges, it has everything to do with what to do in a situation where both buttons are pressed. you need to sort this out in a separate state machine. with two buttons, there are only four possible state changes - up, down, both, none. you need to figure out what to do with each. – sybreon Feb 12 '12 at 16:55

What you wrote is perfectly valid Verilog. For example, one case where an always block depends on two edges is in describing a flip-flop with asyncronous reset:

wire d;
reg q;
always @ (posedge CLOCK or posedge RESET) begin
if (RESET)
q <= 0;
else
q <= d;
end


Another case where an always block has sensitivity to multiple inputs (but not to their edges) is in describing a multiplexer:

wire s, a, b;
reg out;
always @ ( s or a or b ) begin
case ( s )
0 : out <= a;
1 : out <= b;
endcase
end


Note that in this case, even though out is a reg variable in the Verilog, it will actually be implemented as the output of combinatorial logic, and no flip-flop or latch will be generated from this code.

However, just because something is valid Verilog, doesn't mean it is synthesizable into your device (I'll guess you're trying to synthesize for an FPGA or CPLD). If your device doesn't have actual gates available that can perform the logic you describe in your Verilog, you will get a synthesis error.

As Sybreon said, it's often a good idea to mentally design your logic in terms of the hardware resources available in your device, then figure out how to translate that to Verilog, rather than just write Verilog and then try to figure out how to adjust it to make it synthesizable.