FPGA as a counter/divider? - Page 1
Forum section: electronics / general

author: rcbuck
author_rank: Frequent Contributor
timestamp: November 07, 2018, 04:13:29 am
content: Can a fairly small FPGA be used as a counter? I want to feed a 10.000000 MHz signal into the FPGA and be able to select an output of .1 Hz, 1 Hz, or 10 Hz. I am building a frequency counter and want the outputs to gate the signal going into the PIC32 on and off. I could do the same thing using the MCU but the external 1 second gate would be more accurate.I have a breadboard version of the counter working. In order for it to be accurate, I have to set the value in the PR registers to 39,999,057 due to the PIC interrupt latency. The PIC32 is running at 40 MHz and I am driving the PIC oscillator circuit with a rubidium oscillator that is dead accurate. I am feeding the 10.000000 MHz signal from my GPSDO into the input of the frequency counter. That is how I arrived at the values for the PR registers. I will also be able to use the GPSDO for the 1 second gate which would be extremely accurate. I will use a 10.0 MHz TCXO (adjustable) on the final board for the PIC oscillator. I will also have a BNC connector to feed the GPSDO into the counter as an option.I have no FPGA experience. In fact, I have never actually seen one. I have been using PICs and AVRs for over 20 years. I have also used a couple of STM32 ARM parts over the last couple of years. So I guess I could probably learn to program FPGAs for simple tasks. It never hurts to learn something new.I could do the dividing with 3 CD74HC4059 chips and a couple of other divider chips. If a small FPGA package could be used instead, it would take less board space.

author: Mr. Scram
author_rank: Super Contributor
timestamp: November 07, 2018, 04:21:32 am
content: Sure, it's one of the easier things to do with a CPLD or FPGA. Though you may want to consider using something like a PSoC device. Those are essentially MCUs with a tiny bit bit FPGA fabric added to it, so you can add things like these in hardware. You can write Verilog components or use a graphical logic editor. This way your board space should be reduced even further.

author: PCB.Wiz
author_rank: Super Contributor
timestamp: November 07, 2018, 08:40:08 am
content: Quote from: rcbuck on November 07, 2018, 04:13:29 amOf course.Quote from: rcbuck on November 07, 2018, 04:13:29 amDoes your MCU include configurable Logic Blocks ?Quote from: rcbuck on November 07, 2018, 04:13:29 amWhy not continue to use a small MCU ? A small MCU will be cheaper than a FPGA and with care, and a MCU with reasonable timers, you can /NIf you are making a counter, why not look at a reciprocal counter, those do not lose precision at low frequencies.eg measure 100Hz with a 1 second gate and simple total-counter, and you have coarse results.

author: BrianHG
author_rank: Super Contributor
timestamp: November 07, 2018, 09:11:52 am
content: Just use a bottom end PIC as your clock divider. No interrupts, No timers, No WDT, No PLL, No nothing, absolutely nothing at all just feed the 10MHz to the pic clk in, have 1 output and 2 input config pins. Make a small assembly loop program with timer 3 24 bit loop sizes as your delays. The output will be a dead instruction cycle to dead perfect cycle with a simple pin toggle output and 3 select-able preset loop counter sizes.40 cents, and you have a working 8 pin device with single supply 1.8v through 5v support, 1 million/ 10 million, 100 million to 1 divider with absolutely 0 error as if you wired a TTL programmable counter divider. Never a glitch, never a jitter, never a mess-up.This should even work on microchip's first PIC16C54 of 20 years ago with the identical code...Don't bother doing this one in C code if you want time repeat-ability if you want to edit your code.

author: rs20
author_rank: Super Contributor
timestamp: November 07, 2018, 09:17:57 am
content: I don't understand why you need to "account for latency". If you have 10 MHz coming in, and want 0.1Hz going out, that's a divide by 10^8 operation, which can be done by any half decent 32 bit timer/counter peripheral on an MCU (some MCUs don't even have a native 32 bit counter, but have several 16 bit counters that can be ganged together.) In particular, if you're using software interrupts, you're doing it wrong. The counter peripheral should be configured to reset and output to a pin all by itself (waveform or PWM generation are your keywords).But yeah, you could use a CPLD or FPGA too, that'd only really make sense if you were going out of your way to avoid the MCU though.

author: BrianHG
author_rank: Super Contributor
timestamp: November 07, 2018, 09:21:56 am
content: Quote from: rs20 on November 07, 2018, 09:17:57 amYes. But not everyone is skilled at using such internal hardware peripherals, or they are already being all used, or the firmware is an add-on to someone elses design, which is why I posted the 'Dumb' but guaranteed cheap easy beginners method. (As long as you know how to count cpu cycles for PIC code to set the right loop size)Note that doing it internally in the PIC32 using the internal counters and timer + an external reference 10Mhz clock, with the PIC32's trigger on programed count position would be a proper eloquent solution, but, the developer needs to do a lot of reading and needs to accommodate the setup and counter/timer capture capabilities in a quality elegant manner.Any of the PIC32 are fully capable of doing everything the OP requires all internally. The 1 external component would need to be a pre-scaler if he wants to measure high frequency RF signals.For an intermediate mid level developer, I might suggest feeding the 10Mhz reference source to the PIC's main or secondary clock source if you want the predictable interrupt count clock cycles for doing manual capture or the frequency measuring input source.Quote from: rs20 on November 07, 2018, 09:17:57 amYes again...

author: technix
author_rank: Super Contributor
timestamp: November 07, 2018, 09:32:08 am
content: I do see small CPLD being used for this, one example would be XC2C32A-6CSG32C being cheaper than most MCU I used here in China. Also CPLD does have a deterministic latency and little to no synchronization worry.If you have some logic units to spare, consider add a SPI slave port in there, that will make your chip on-the-fly configurable.

author: BrianHG
author_rank: Super Contributor
timestamp: November 07, 2018, 09:39:15 am
content: If you are making a frequency counter, and you want to both count and time inside the FPGA, and divide down and latch with the 10MHz reference source, the advantage is the CLK input for the counter may be able to go very high in frequency, like 500Mhz even with a cheap FPGA/PLD. You can also initialize the beginning of the 1hz reference clock to the next rising edge of the the source frequency being measured getting rid of that last digit uncertainty jitter.Now needing 2 x 32 bit counters, if you want all this with a second buffer to feed the PIC32, and 3.78$ for 36 pin BGA, or 6.12$ for 153pin BGA, or 9.84$ for 144pin QFP is acceptable for an FPGA, I would look at a MAX10 device. Your entire front end can go inside one of these, and most likely, you can run an entire display and network logging as well and forget about an MCU with such a large FPGA chip. It comes in a QFP, runs on 1.15 to 1.25, or 2.85v to 3.3v, no core voltage regulator needed or no bootprom needed.If you need an MCU, there is enough room for a soft-core MCU to be placed inside, though, small memory compared to a PIC32.Max 10 devicesThese are overkill if all you need is a counter divider. Instead, you should look at FPGA devices like:https://www.digikey.com/product-detail/en/intel/EPM7032AELC44-10N/544-1995-ND/1084699If you need that external cheap 10hz, 1hz, 0.1hz, programming this guy in assembly will be super cheap and easy if you are familiar with microchip:https://www.digikey.com/product-detail/en/microchip-technology/PIC16F54-I-SO/PIC16F54-I-SO-ND/613199If you want a 3 cent solution, look here:https://www.eevblog.com/forum/blog/eevblog-1132-the-3-cent-microcontroller!/

author: iMo
author_rank: Super Contributor
timestamp: November 07, 2018, 11:05:58 am
content: Imagine you want a 32bit reciprocal counter. You needa. 64 FFs for the signal counterb. 64 FFs for the reference counterc. ~4 FFs for the sync logic (time-stamping)d. ~6 FFs and around 100 LEs for reading the counters out (SPI-like 2wire serial).In total about 240 LEs (1 LE = 4 input LUT and 1 FF) with Lattice and Intel.In past I put a reciprocal counter into an XC9572XL CPLD - while the lower fastest parts (10-12bits) of the counters were placed into the CPLD and the upper slowest bits were accumulated in the MCU (via interrupts and internal sw counters). You may get issues with syncing CPLD->MCU crossing, however..With an iCE40LP384 (the smallest FPGA, afaik) it fits fine (384 LEs).QuoteThe first time is always the hardest..You would need to master an infrastructure (FPGA+breakout board, fpga/flash programmer [jtag/spi], dev tools install) and certain know-how (verilog/vhdl language and related mindset, dev tool chain, flashing the fpga, troubleshooting)..

author: NorthGuy
author_rank: Super Contributor
timestamp: November 07, 2018, 02:14:25 pm
content: PIC32 is in a different league compared to FPGA. If you run it at 40MHz, your time resolution is 25 ns (if you use Input Capture (IC) which gives you cycle-accurate data, much worse if you do it with interrupts). If you stay with this, using GSPDO is total waste. FPGA (such as Spartan-7) can theoretically give you time resolution of 50-100 ps, which is at least 200 times better than PIC32. On the other hand, PIC is easy. FPGA is easy if you want 2-3 ns resolution - you simply create a counter, run it at 500MHz, and record readings every second. However if you want better than this, there's much more work. You will need calibration logic, and the further you go the more problems you encounter - temperature, trace lengths, SI, jitter, drift etc.Time resolution is not the only thing you need. The method is important. If you want 1 Hz accuracy, you can simply count pulses for 1 second. You can do it on PIC. If you need sub-Hz frequency, you need to count longer, or you need to change your method and measure time between edges. You still can do it on PIC, but not at higher frequencies.Therefore, the first thing you need to do is to decide on the accuracy you need in your frequency counter.

author: NivagSwerdna
author_rank: Super Contributor
timestamp: November 07, 2018, 02:41:14 pm
content: http://www.leapsecond.com/pic/picdiv.htm

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: November 07, 2018, 02:43:27 pm
content: PIC12 and the NCO peripheral.

author: BrianHG
author_rank: Super Contributor
timestamp: November 07, 2018, 03:17:46 pm
content: Quote from: NivagSwerdna on November 07, 2018, 02:41:14 pmBasically my recommendation ready made, however, the author missed 1 source code you require he has on his FTP site, here is the location of his missing 'delayw.asm' routine required to compile his posted example 'pdXX.asm' source codes:http://www.leapsecond.com/pic/src/I'd say since the op is experienced with PICs, just use this code which has an only 2 picosecond jitter output.

author: rcbuck
author_rank: Frequent Contributor
timestamp: November 07, 2018, 04:56:04 pm
content: QuoteBecause 1 second on the PIC32 running at 40 MHz should be 40,000,000 clock cycles. The pre-load value for the counter has to be set at 39,999,957 to accunt for the hardware interrupt latency. With a 10 second delay the pre-load value has to be 399,999,960. So the 1 second delay is 43 cycles and the 10 second delay is 40 cycles. In reality, I could just use those values and the counter would still be highly accurate. Note: I said 39,999,057 in my first post but meant 957.If I can divide the 10.000000 MHz signal down to 1 Hz with no cycle error, I can use that to gate the input to the counter off with a J-K FF when the 1 Hz positive edge happens. The same 1 Hz signal would be applied to one of the PIC I/O pins to trigger an interrupt for the PIC32. Even if it takes a millisecond to respond to the interrupt it wouldn't matter since the input signal has been shut off. After the count value is displayed on the LCD, I will reset the J-K FF to start a new count.QuoteBrian, I never thought of that. Thanks for the links. That would be the easiest way to accomplish the 1 second delay. I always program the low end 6 and 8 pin PICs in assembly. I even have a few 16C54s laying around but wouldn't consider using them since the 16F54s are 1/3 the cost.NivagSwerdna, same thought as Brian. I will go that way. It means I do not have to learn how to use FPGAs. Although I keep telling myself I really should learn how they work.I should have stated in the initial post that I need to measure RF up to 50 MHz. Even the 8 bit PICs can handle that. I am using an AD4002 as a prescaler to measure from 50-400 MHz. The RF front end in both cases has squaring circuitry for the input signal.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: November 07, 2018, 05:19:26 pm
content: Quote from: rcbuck on November 07, 2018, 04:56:04 pmLook at the newer parts like 16f153xx and 10F322 - streets ahead of the ancient stuff in terms of peripherals and cheaper.And no need for assembler perfectly useable in C - even the 10F322.

author: rstofer
author_rank: Super Contributor
timestamp: November 07, 2018, 06:22:32 pm
content: Interrupt latency may not be constant. Using the uC internal counters makes more sense.If the plan is to use the FPGA as a divider, why not use it as the entire counter and then make the results available via SPI and use a PIC <or whatever> to query and display the results?There are interesting results if you Google for 'fpga frequency counter'

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: November 07, 2018, 07:08:20 pm
content: Quote from: rstofer on November 07, 2018, 06:22:32 pmDMA can help a lot if this is an issue, but that can get rather tricky..

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 07, 2018, 07:41:10 pm
content: Quote from: rcbuck on November 07, 2018, 04:13:29 amYes, any ultra small FPGA would do the trick. You could take a look at Lattice's ice40 series, the smallest one should be more than enough for your needs, and cheaper than even using a couple logic ICs.http://www.latticesemi.com/Products/FPGAandCPLD/iCE40.aspxOf course there are many others.If you're not used to HDL languages, it's an opportunity to learn. Your requirements would only take a few lines of code.

author: rstofer
author_rank: Super Contributor
timestamp: November 07, 2018, 07:45:59 pm
content: Quote from: mikeselectricstuff on November 07, 2018, 07:08:20 pmThis gets to the issue of whether the OP wants to build an accurate frequency counter or something that is 'about' right. Given the GPDSO source, I'm assuming that accuracy will be a factor and this is only going to happen with hardware counters gated appropriately. Everything else is just 'more or less'.

author: Kleinstein
author_rank: Super Contributor
timestamp: November 07, 2018, 09:02:14 pm
content: The two correction values for the gat time are suspicious. The extra delay should be constant, not 3 cycles apart. With the fast µCs there may be caches that may not be always predictable. Also multi cycle instructions can make the interrupt latency not fully predictable.Usually the larger µCs have enough timers to produce the 1 Hz / 10 Hz signals with there internal timer HW.The usually better way to make a counter with an µC is to use the internal timers. Especially the time capture function is well suited to make a reciprocal counter with it. The data capture part is easy to do inside an FPGA, but the math part (e.g. the division) can be messy inside a FPGA.The next step from a reciprocal counter would be a time stamping counter, so that not only the first and last edge is used but also edges in between - that is the way the high end counter go to 10 or 12 digits. It sounds complicated, but a simply version could be done in an µC. I did one in a little as an Atmel Tiny2313 (8 bit AVR) - though I would recommend a more powerful µC. The PIC32 should well suitable for this.The other point for high resolution is better timing resolution. This can be an analog interpolation or a counter with a higher clock (e.g. FPGA).

author: ogden
author_rank: Super Contributor
timestamp: November 07, 2018, 10:00:55 pm
content: Quote from: rcbuck on November 07, 2018, 04:56:04 pmIf you compensate for interrupt latency, you are either doing it wrong or using wrong microcontroller. Don't know about PIC timers, but Stm32 timers with their capture/compare allows to build dependable frequency counter that does not rely on CPU or interrupt speed.

author: iMo
author_rank: Super Contributor
timestamp: November 08, 2018, 12:27:43 am
content: QuoteI built several 50MHz counters with pic16f84 and pic16f628. 20y back? I liked the trick with reading out the not accessible timer prescaler content.. Those 8bitters have clock precise instruction timings, therefore the gating time was simply done in a sw loop. That will not work with pic32.

author: macboy
author_rank: Super Contributor
timestamp: November 08, 2018, 06:58:01 pm
content: Quote from: rcbuck on November 07, 2018, 04:56:04 pmHave you considered adjusting the preload instead of setting it? Then, interrupt latency does not matter. I don't know which device or timer you are using, but the idea is that if the timer counts down, and you want it to fire every 10M cycles, thenaddexactly 10M to the counter pre-load after servicing the interrupt. Don'tsetit to 10M-[ISR latency].Also, if you want low jitter, clock the PIC from the 10 MHz you are dividing, and use the PLL if you want higher MIPS. Using another clock domain makes no sense.

author: iMo
author_rank: Super Contributor
timestamp: November 08, 2018, 08:14:16 pm
content: Sure, the OP has to study a little bit what the pic32 does offer.He can feed his rubidium 10MHz into a hw pic32 counter set to divide by 2*10e6 or whatever gate time he needs [this could be done as generating 1sec with Output Compare], gate the OCXO signal with that 1sec gate pulse, and feed the gated signal into the second pic32 hw counter and that is it..http://ww1.microchip.com/downloads/en/devicedoc/61105f.pdfhttp://ww1.microchip.com/downloads/en/devicedoc/61111e.pdf

author: PCB.Wiz
author_rank: Super Contributor
timestamp: November 09, 2018, 05:50:31 am
content: Quote from: technix on November 07, 2018, 09:32:08 amWow, really - what do you pay for the XC2C32A-6CSG32C ?Chinese MCUs are 20~30c for quite good ones (eg N76E003), and sub 10c for more lobotomized ones, or OTP ones (see other threads)

author: rcbuck
author_rank: Frequent Contributor
timestamp: November 09, 2018, 06:15:15 pm
content: I had to step away from the project for a couple of days to handle other things. As additional information, the PIC32 I am using is a PIC32MX110F016.This morning I modified the code so I am using the Output Comapare function of the PIC32. According to the data sheet, when the count in the Output Compare register matches the value in the Timer2/3 register pair, the OC output pin gets set with no cycle delay. I am using the Timer4/5 pair for the frequency counter input.I put my programmer in debug mode and confirmed that is true. When the OC match occurs, I use the OC output pin to disconnect the 10 MHz signal from the counter input pin using a TS5A3159 analog switch. When I stop the program inside the OC interrupt routine, the TMR4 register contains 40,000,000 which is exactly one second. If I set Timer2/3 and OCR1 to 400,000,000, that is what I see in TMR4 register inside the OC interrupt. So there is in fact no cycle delay when the OCR1 count matches the PR4 value.The counter has been running in the 10 second mode for a couple of hours and constantly displays 100,000,000. About once a minute I see a count of 99,999,999 due the input signal not being edge aligned with the start of the delay period. But that is no big deal.All I need to do now is to find someone with a $10,000 HP or Tektronix 12 digit frequency counter who can tell me the exact frequency of my GPSDO. If I knew that, I could put my counter in a 1000 second count mode and see how it compares to the expensive counter.

author: iMo
author_rank: Super Contributor
timestamp: November 09, 2018, 06:49:36 pm
content: Quote from: rcbuck on November 09, 2018, 06:15:15 pmTS5A3159 is slow. Use a fast logic gate instead..

author: NorthGuy
author_rank: Super Contributor
timestamp: November 09, 2018, 07:00:25 pm
content: Quote from: rcbuck on November 09, 2018, 06:15:15 pmYou can do it much simpler. Let the timer run from the external signal which you want to measure, and use an IC module to capture rising edges of external 1PPS signal from a GPS module. This gives you one count per second, which you simply sum up. This way you don't need any external circuitry, and don't even need GPSDO because GPSDO feeds of GPS pulses itself, and there's no need for anything else. The best part, you don't need $10K HP device for tests

author: rcbuck
author_rank: Frequent Contributor
timestamp: November 09, 2018, 11:14:47 pm
content: QuoteIt can handle input signals to 100 MHz. My highest frequency will be 50 MHz. Its maximum switching time is rated at 50 nsec so it can probably handle the once per second switch toggle with no problem.QuoteThe GPSDO will not be connected to the frequency counter. It will normally run off of the onboard TCXO. A couple of times per year I will connect the GPSDO 10 MHz signal to the counter to re-calibrate the TCXO.

author: NorthGuy
author_rank: Super Contributor
timestamp: November 09, 2018, 11:27:26 pm
content: Quote from: rcbuck on November 09, 2018, 11:14:47 pm50 ns will fully contain 2 pulses at 50 MHz, potentially making your count 2 more or 2 less.

author: rcbuck
author_rank: Frequent Contributor
timestamp: November 10, 2018, 02:02:40 am
content: NorthGuy, you are correct. I hadn't done the math at 50 MHz. I guess I will replace the switch with something like a SN74LVC1G08. It has 1-5 ns switch time in a SOT-23 package.

author: iMo
author_rank: Super Contributor
timestamp: November 10, 2018, 06:36:37 pm
content: You may think about following pic32 setup (a "reciprocal counter"):1. rubidium to hw counter_ref (32bit) - ref_freq2. OCXO to hw counter_sig (32bit) - sig_freqBoth counters shall run continuously.And do make a snapshot of both with a single edge. It could be it is somehow feasible.You get counter_sig_old and counter_ref_old values.Then, after some time (it must not be a precise interval, it could be any reasonable interval you want), do make a snapshot again.You get counter_sig_new and counter_ref_new values.From ((delta_sig*ref_freq) / delta_ref) you may get the measured sig_freq.In case you would be able to measure the phase (in ns or ps) of the sig edge against the ref edge in the moment of sampling (when you do the snapshot) you may enhance the counter's resolution significantly (the "reciprocal counter with the time iterator"). Significantly means 1000x for example..