Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Treating pushbutton events to implement up/down counter in verilog

Status
Not open for further replies.

lg3

Newbie level 3
Newbie level 3
Joined
Feb 1, 2013
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,308
Hi everybody,

I'm trying to implement in an Altera's DE2-70 board (which has an embedded Cyclone II) an up/down counter,
which counts up when a press one pushbutton, and count down when a press another pushbutton. First I tried implementing just
the up counter, which looked like this :

Code:
module top(input inc, rst,
                output[6:0] segment_display);

reg[3:0] counter;

always @(negedge inc or negedge rst) begin
    if(~rst) begin
        counter <= 4'd0;
    end else begin
        if(~inc) begin
            counter <= counter + 1;         
        end
    end

end

endmodule

It worked correctly. However, when trying to implement both increment and decrement I was tempted to write the following
code, which did not work:
Code:
always @(negedge inc or negedge dec or negedge rst) begin
    if(~rst) begin
        counter <= 4'b0;
    end else begin
        if (~inc) begin
            counter <= counter + 1;
        end else begin
            counter <= counter - 1;
        end
    end

end

Googlin, I found out it has something to do with the negedge inc or negedge dec, which seems to cause a combinational loop
when synthesized. I have tried many different ways to implement it, but I do not know how to treat this kind of event,
because I want to count just once, when the user triggers the pushbutton (which in the DE2-70 board already have debouncing).
Using a "clk" doesn't seem intuitive to me. Can someone propose another approach which will work on both pushbutton edges?

Thanks in advance,
lgb.
 

Currently you are using dec and inc as clocks, and you are only allowed to use a single clock in an FPGA. The best thing to do is use a system clock from an oscilator and then register dec and inc to allow you to do rising/falling edge detections in the clock domain.
 
  • Like
Reactions: lg3

    lg3

    Points: 2
    Helpful Answer Positive Rating
Thank you very much TrickyDicky! I was stuck into thinking about using the "inc" and "dec" signals as clock, I didn't know there could be only one signal acting as a clock. So that's how my code look right now :

Code:
 reg inc_reg, dec_reg;
 integer number;
 
 always @(posedge clk or negedge rst) begin
	if(~rst) begin
		number <= 0;
		inc_reg <= 0;
	end else begin
		if (!inc) begin
			if(inc_reg == 1'b0) begin
				inc_reg <= 1'b1;
				if(number == 9) begin
					number <= 0;
				end else begin
					number <= number + 1;
				end
			end
		end else begin
			inc_reg <= 1'b0;
		end
		
		if (!dec) begin
			if(dec_reg == 1'b0) begin
				dec_reg <= 1'b1;
				if(number == 0) begin
					number <= 0;
				end else begin
					number <= number - 1;
				end
			end
		end else begin
			dec_reg <= 1'b0;
		end
		
	end
 end

That is, I keep a "reg" to store the dec event, and another one to treat the "inc" event. The counter is incremented/decremented only when
the pushbutton is pressed, and the register was not already '1'. When the pushbutton is not pressed, the reg is always reset to '0'.

Anyways, thank you for the advice, I was already 2 days struggling with it.

Best regards.
lgb.
 

I think TrickyDicky meant for you to synchronize the inc & dec (which I would name inc_n and dec_n since they are active going low) and then after the metastability resolution registers you add an edge detector. Now you'll have two outputs called say inc_strobe & dec_strobe. Personally I like to use a case statement when I code a up/down counter, where I use
case ({inc_strobe, dec_strobe})
and the default clause is don't count up or down.
 

Hi ads_ee, I am not sure If I understood what you meant by "synchronize inc & dec", could you please explain a little more?
 


Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top