Hi Chris:
The problem is in the sensitivity list applied. You really want it evaluated on both rising and falling edges, and tell it to hold in the non-case.
However, that being said. it is much better to do a synchronous design as follows:
module updown (
input clk_i,
input reset_i,
input up_i,
input down_i,
output [11:0] counter_o
);
reg [2:0] up_s;
reg [2:0] down_s;
reg [11:0] counter_r;
wire up_rise_edge_p <= up_s[1] & ~up_s[2];
wire down_rise_edge_p <= down_s[1] & ~down_s[2];
always @(posedge clk_i)
begin
if (reset_i)
begin
counter_r <= 12'd250;
up_s <= 3'b111;
down_s <= 3'b111;
end
else
begin
up_s <= {up_s[1:0],up_i};
down_s <= {down_s[1:0],down_i};
if (up_rise_edge_p)
begin
if (down_rise_edge_p)
counter_r <= counter_r;
else
counter_r <= counter_r + 12'd3;
end
else
begin
if (down_rise_edge_p)
counter_r <= counter_r - 12'd3;
else
counter_r <= counter_r;
end
end
end
endmodule
This takes care of async up and down signals, but glitch eaters could also be added if necessary. This also takes care of a non-count case of both up and down being pressed at the same time.
Pete