Verilog /DIP Switch Question....

Is it possible to implement a "pause" function for a counter using a DIP switch? i.e. where it counts, you press the DIP switch it stops counting holding the current value until you press the DIP switch again in which it counts again starting from its stopped value?

Right now, the DIP switch is used as a "reset" zeroing out the counter...you press it, the counter immediately goes to 00 and once you release it starts counting...01,02, etc.

I have tried all the obvious things, but I am wondering if this is even possible at all with a DIP switch and I am wasting my time...with a DIP switch, you only have a "known" state when it is pressed...when not pressed it is an open circuit, right? It seems like I would need a switch that is tied to ground when open, right? Or am I missing something?

FYI, this a board with an FPGA, LCD and DIP Switch. Thanks for any help you can offer.

Reply to
G
Loading thread data ...

Yes, it is possible. However, since this sounds suspiciously like a homework problem, I'll be a little vague about how to solve it.

When you push the dip switch, it toggles between two states, counter running/counter paused. How do you implement that?

Next, you need to take the paused/running signal and use it to control whether the counter is running or not. How do you do that?

When you have solved those two problems, you will have your circuit.

Hope this helps,

-Chris

***************************************************************************** Chris Clark Internet : snipped-for-privacy@world.std.com Compiler Resources, Inc. Web Site :
formatting link
23 Bailey Rd voice : (508) 435-5016 Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)

------------------------------------------------------------------------------

Reply to
Chris F Clark

First of all, this isn't a HW problem...I have been out of school a few years... I am trying to bridge the gap between the simulated world that academia covers well and the actual real world HW that academia does a poor job at covering, imo.

Anyway....Like I mentioned in my first post, I have done all the obvious things to no avail...it simulates as expected, but once in hardware, it doesn't, which makes me think it is something with the DIP switch.

I can cut and paste the necessary code if you are willing to help....

Reply to
G

Have you tried using the DIP switch as an enable signal instead of a reset signal? I'm interesetd in reading the code if you would like to post it.

Reply to
dexter

I apologize for suggesting it might be a homework problem. It's actually not school time and so the suggestion was unwarranted. (I might have missed your first post also (or atleast not connected it).)

If it is a mismatch between simulation and physical implementation, perhaps there is something in the physical implementation your model doesn't account for. For example, perhaps the dip switch "Bounces". What you are trying to build, where the switch acts as a toggle would be susceptible to that. Using the dip as a reset wouldn't have the same tempermentalness, as if one sees two (or more) rests in a row, one isn't going to "notice", since in the end the signal still gets reset. Tow toggles in a row are a different story.

If you could tie an indicator (e.g. an led) to the "state" part of the design, so that the led would indicate which state the toggle is in, you might see that it doesn't actually toggle (or toggles more than once per push). Of course, if the problem is too quick, it might go by to quick for you to see it.

Assuming that bounce is the problem, you could then ask how to de-bounce your circuit (i.e. make it less sensitive to bounce). I don't know what solutions are available there, but one possibility is to make the circuit insensitive to a 2nd button push until a specific amount of time (say a specific number of clock cycles) after the first. Iamgine how you would change your circuit model so that the dip button could only cause one change of the toggle per cycle. Implement that and see if it effects your problem. If bounce is the problem, whether that change will help depends on how fast your cycle is relatively to how fast bounces settle.

If bounce isn't the problem, you need to keep looking until you can find out what is. You're right about the differences between unrealistic "academic" models and the real-world implementation. Verilog models are a simplification of the real world and do not model it completely faithfully. There are things which can happen in the real world that your model is likely to miss and vice-versa: sometimes the model can have artifacts that can never heppen in the real world.

Hope this helps,

-Chris

***************************************************************************** Chris Clark Internet : snipped-for-privacy@world.std.com Compiler Resources, Inc. Web Site :
formatting link
23 Bailey Rd voice : (508) 435-5016 Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)

------------------------------------------------------------------------------

Reply to
Chris F Clark

Yes, post your code if you want help.

Maybe the switch is not debounced. See:

formatting link

-- Mike Treseler

Reply to
Mike Treseler

again

You want to use the DIP switch to toggle a Count Enable flip-flop. This would be trivial if there were no contact bounce. In reality, the toggling flip-flop is about a million times faster than the contact bounce activity, so you must somehow make sure that the whole bounce sequence ( lasting 100 ms?) is seen as only one clock input to the control flip-flop. With a two-pole switch this is trivial, but with only one pole, you have to introduce a delay that masks the bounce. A clean digital solution uses an extra multibit resettable "dead-ended" counter that stops counting when its MSB is a 1. Needs a reasonably slow clock to make it longer than 100 ms. Depressing the DIP switch resets the whole counter, and keeps it reset as long as you hold the DIP switch down. Use the MSB going 1-to-0 as the clock for your toggling count enable signal.

There are many variations on this theme, but none is trivial. There are neat tricks you can play with R and C, but that gets you an outcry of contempt from the digital design community... Peter Alfke

Reply to
Peter Alfke

I'm possibly missing something here, but seems to me that it really doesn't matter whether the switch bounces or not.

If the switch is changing from "count" to "don't count" at the time the counter is trying to figure out whether to count or not, the worst that can happen is that it will make an extra count or maybe a few.

Assume the switch debounces in 100 ms, and during the 100 ms it's in the wrong state for 50% of the time. If the counter is counting at 1 Hz, then there's a 5% chance that it will make one extra count.

If you're counting faster than 10 Hz, then you'll probably never know if there are one or two extra counts that happen while the switch is debouncing.

If you're interested in switch bounce time, Jack Ganssle did a column about it a few months ago, in Embedded Systems Magazine. He went out and bought about 20 switches and measured debounce time using an oscilloscope. I don't remember the results, but it's still an interesting read. Here's a link to the article:

formatting link

Reply to
Al Gosselin

The original posting asked for a design where the first depression of the DIP stops the counter, the second depression starts it again, like an old-fashioned lamp next to your bed.

"where it counts, you press the DIP switch it stops counting holding the current value until you press the DIP switch again in which it counts again starting from its stopped value"

That toggle action is the problem, and it needs switch debouncing. Peter Alfke, on a rainy California Sunday afternoon...

Reply to
Peter Alfke

The original posting asked for a design where the first depression of the DIP stops the counter, the second depression starts it again, like an old-fashioned lamp next to your bed.

"where it counts, you press the DIP switch it stops counting holding the current value until you press the DIP switch again in which it counts again starting from its stopped value"

That toggle action is the problem, and it needs switch debouncing. Peter Alfke, on a rainy California Sunday afternoon...

Reply to
Peter Alfke

OOPS...

Well, Jack Ganssle has some good ideas about debouncing as well.

Al, on a cold, freezing rain, New England Sunday evening...

Reply to
Al Gosselin

"div_16M.v" generates a count that enables both "cnt_10.v" and subsequently "cnt_10_tens.v" when its(div_16M.v) count reaches all 1s.

To do the pause/start/stop function, I moved the "clr" function out of the two counter modules and into a module "cnt_pause.v" to enable/disable the master counter enabler "div_16M.v"...this makes the most sense(I thought)

Initially, "clr" was used to reset the counter to zero...this was tied to the DIP switch on the PCB.(this code is commented out)

This is my last shot at what I thought was "trivial"...I have changed it around a lot, but settled on this approach...I feel it is close, but I have begun to think otherwise...Please excuse the messiness and somewhat disarray.

// module: counter.v

// This is the top level module that ties all sub-modules together

module counter(clk,reset,lcd_com,one_dp,ten_dp,one_out,ten_out); input clk; input reset; output lcd_com; output one_dp; output ten_dp; output [6:0] one_out; output [6:0] ten_out;

wire nreset; wire pause; wire lcd_clk; wire tc; wire ce_tens; wire [23:0] ce_1s; wire [3:0] cnt_1s; wire [3:0] cnt_10s; wire [6:0] lcd1_out; wire [6:0] lcd10_out;

cnt_pause PAUSE( .clk(clk), .clr(nreset), .start_stop(pause) );

div_500K DIV_500K( .clk(clk), .clk_60(lcd_clk) );

div_16M DIV_16M( .clk(clk), .start_stop(pause), .enable(ce_1s) );

cnt_10 ONES( .clk(clk), //.clr(nreset), .enable(ce_1s), .tc(tc), .qout(cnt_1s) );

cnt_10_tens TENS( .clk(clk), //.clr(nreset), .ce_tens(ce_tens), .qout_tens(cnt_10s) );

hex2lcd ONES_LCD( .hex(cnt_1s), .lcd(lcd1_out) );

hex2lcd TENS_LCD( .hex(cnt_10s), .lcd(lcd10_out) );

lcd_mux ONES_MUX( .clk(clk), .cnt(lcd_clk), .data_in(lcd1_out), .lcd_seg(one_out), .lcd_com(lcd_com), .lcd_dp(one_dp) );

lcd_mux TENS_MUX( .clk(clk), .cnt(lcd_clk), .data_in(lcd10_out), .lcd_seg(ten_out), .lcd_com(), .lcd_dp(ten_dp) );

assign nreset = ~reset; assign ce_tens = tc & (ce_1s == 24'hFFFFFF);

endmodule

// module: cnt_pause.v

// This module ties the DIP switch function to counter enable.Pauses the //counter. // Continues counting toggled by user DIP and at last count value.

module cnt_pause(clk,clr,start_stop); input clk; input clr; output start_stop;

reg pause = 0;

always @ (posedge clk) begin if (clr) pause

Reply to
G

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.