FPGARelated.com
Forums

Downsizing Verilog synthesization.

Started by eromlignod August 6, 2008
John_H wrote:
> If you can't increase the processing frequency, you could still count > the LSbits and cycle through the counters, adding and clearing the > LSbits to a BlockRAM worth of counter values. To cycle through 255 > 32-bit counters, you'd need 8-bit counters for each signal and a > read-add-write cycle (using the dual-port mode) for each entry in your > list. You end up only using half the BlockRAM for this extreme number > of counters. > > It's more housekeeping but you use a fraction of the count resources.
I once did something very much like this, but in reverse. I needed to generate 63 PWM outputs with a repetition rate of 1 kHz and 16-bit resolution (which implies a master clock frequency of 65.536 MHz) on a fairly modest FPGA. Obviously, the brute-force way to do this is to have a 16-bit master counter, 63 16-bit registers to hold the duty cycle values, and 63 16-bit comparators to drive the outputs. This would not have fit into the chip. So, rather than having 63 16-bit comparators, I used 6-bit comparators. The duty-cycle values were stored in a 64x16 block RAM (actually 128x16 so that updates to the values could be double-buffered), and I scanned through that RAM at the master clock rate (1024000 scans/second) and did the MSB comparison with one common 10-bit comparator. Each of the 6-bit comparators was "enabled" for fine timing when the MSBs matched for that channel. IIRC, used about 40% of the chip. -- Dave Tweed
eromlignod wrote:
> The incoming signals are square waves at the fundamental frequency of > each of the 219 strings in the piano that are being magnetically > sustained (vibrate forever). I only read 44 strings at a time, tune > them, then go on to the next 44, etc. So there are 44 counting > modules and an output address signal to instruct the sustainer > circuits when to vibrate the next string. > > I first convert the wave to a "period" wave that has an "on" time > equal to one period of the string's vibration. I then use this wave > to enable counting of the 50-MHz system clock. So I get a count of > how many clock ticks of the system clock occur for one period of > string vibration. This takes up to 21 bits for the low strings. I > average 32 of these numbers and calculate an error based on a stored > setpoint. Currently I'm using a theoretical setpoint, but eventually > I will want to add the feature whereby a piano tech can hand-tune the > piano and then "store" his tuning numbers for subsequent use.
Ah, this makes what you are doing much clearer. One immediate suggestion would be this: Rather than using 44 separate 50-MHz counters, use just one counter and 44 registers that capture the value of that counter when the rising edge of the input occurs. Then, you have a module that scans those 44 latches, and each time one is updated, you subtract the previous value from the current value (mod 2**21) to get the period for that string. This should save a lot of chip resources, converting lots of slice flip-flops into block RAM. The "previous values" can be stored in block RAM, the calibration periods can be stored in block RAM, the PWM values can be stored in block RAM, etc. Everything except for the 44 latches can be processed sequentially rather than in parallel. -- Dave Tweed
On Aug 7, 1:44=A0pm, David Tweed <dtw...@acm.org> wrote:
> eromlignod wrote: > > The incoming signals are square waves at the fundamental frequency of > > each of the 219 strings in the piano that are being magnetically > > sustained (vibrate forever). =A0I only read 44 strings at a time, tune > > them, then go on to the next 44, etc. =A0So there are 44 counting > > modules and an output address signal to instruct the sustainer > > circuits when to vibrate the next string. > > > I first convert the wave to a "period" wave that has an "on" time > > equal to one period of the string's vibration. =A0I then use this wave > > to enable counting of the 50-MHz system clock. =A0So I get a count of > > how many clock ticks of the system clock occur for one period of > > string vibration. =A0This takes up to 21 bits for the low strings. =A0I > > average 32 of these numbers and calculate an error based on a stored > > setpoint. =A0Currently I'm using a theoretical setpoint, but eventually > > I will want to add the feature whereby a piano tech can hand-tune the > > piano and then "store" his tuning numbers for subsequent use. > > Ah, this makes what you are doing much clearer. > > One immediate suggestion would be this: Rather than using 44 separate > 50-MHz counters, use just one counter and 44 registers that capture > the value of that counter when the rising edge of the input occurs. > > Then, you have a module that scans those 44 latches, and each time > one is updated, you subtract the previous value from the current value > (mod 2**21) to get the period for that string. This should save a lot > of chip resources, converting lots of slice flip-flops into block RAM. > > The "previous values" can be stored in block RAM, the calibration > periods can be stored in block RAM, the PWM values can be stored in > block RAM, etc. Everything except for the 44 latches can be processed > sequentially rather than in parallel. > > -- Dave Tweed > > - Show quoted text -
I like this idea. But how do I handle the case when the counter rolls back to zero inside a period measurement? Excuse my thickheadedness, but I'm actually an ME by trade and just taught myself HDL a few months ago. Don
David Tweed wrote:

> eromlignod wrote: > >> The incoming signals are square waves at the fundamental frequency of >> each of the 219 strings in the piano that are being magnetically >> sustained (vibrate forever). I only read 44 strings at a time, tune >> them, then go on to the next 44, etc. So there are 44 counting >> modules and an output address signal to instruct the sustainer >> circuits when to vibrate the next string. >> >> I first convert the wave to a "period" wave that has an "on" time >> equal to one period of the string's vibration. I then use this wave >> to enable counting of the 50-MHz system clock. So I get a count of >> how many clock ticks of the system clock occur for one period of >> string vibration. This takes up to 21 bits for the low strings. I >> average 32 of these numbers and calculate an error based on a stored >> setpoint. Currently I'm using a theoretical setpoint, but eventually >> I will want to add the feature whereby a piano tech can hand-tune the >> piano and then "store" his tuning numbers for subsequent use. >
There is flaw in this approach, which is the Signal to Noise of a SINGLE cycle. With 44 going off at once, you will have crosstalk. That 21 bits will be mostly an illusion.
> Ah, this makes what you are doing much clearer. > > One immediate suggestion would be this: Rather than using 44 separate > 50-MHz counters, use just one counter and 44 registers that capture > the value of that counter when the rising edge of the input occurs. > > Then, you have a module that scans those 44 latches, and each time > one is updated, you subtract the previous value from the current value > (mod 2**21) to get the period for that string. This should save a lot > of chip resources, converting lots of slice flip-flops into block RAM. > > The "previous values" can be stored in block RAM, the calibration > periods can be stored in block RAM, the PWM values can be stored in > block RAM, etc. Everything except for the 44 latches can be processed > sequentially rather than in parallel.
Even simpler, since you KNOW what frequency you want, set up a pair of Loadable counter, close together as MIN as MIX and generate a TuneUP and TuneDOWN signal from when outside this error band. - drive those into LEDS and your Tune motors. Then your datapaths are just the error signals. Read up on reciprocal Frequecy counters, these give higher precisions by counting a time for a certain WHOLE number of cycles. To do that, you would preload 3 numbers, the Min/Max counts, and the cycles to total over. Much better signal to noise. You might even get the whole thing working in a Block Ram, as you can lower the 50MHz... You don't want the pianist saying your system is crap do you ;) -jg
eromlignod wrote:
> I like this idea. But how do I handle the case when the counter > rolls back to zero inside a period measurement?
Modular arithmetic -- what I was alluding to with the "mod 2**21" comment -- takes care of that automatically. As long as you treat the difference as a positive number, it will always be correct, even if the counter rolls over. Actually, I can think of many refinements to this basic idea. Since you have a system clock of 50 MHz, you can easily scan your 44 input channels in well under 1 us, which means you really only need a 6-bit latch for each channel, along with an "edge happened" flag. Everything else can be handled with resources that are shared among all of the channels. To be honest, this is a system that really begs for a microcontroller. The only hardware that should be in the FPGA are the latches for your 44 period measurement channels and your 219 PWM output channels. Everything else -- the difference logic for the period calculation, the calibration algorithm, the preset tuning numbers, user interface features -- should be microcontroller firmware. > Excuse my thickheadedness, but I'm actually an ME by trade and just > taught myself HDL a few months ago. Really? The press announcments about this system that you linked to date from 2002-03 or so. Has it really taken that long to begin an implementation? -- Dave Tweed
On Aug 7, 2:57=A0pm, Jim Granville <no.s...@designtools.maps.co.nz>
wrote:
> David Tweed wrote: > > eromlignod wrote: > > >> The incoming signals are square waves at the fundamental frequency of > >> each of the 219 strings in the piano that are being magnetically > >> sustained (vibrate forever). =A0I only read 44 strings at a time, tune > >> them, then go on to the next 44, etc. =A0So there are 44 counting > >> modules and an output address signal to instruct the sustainer > >> circuits when to vibrate the next string. > > >> I first convert the wave to a "period" wave that has an "on" time > >> equal to one period of the string's vibration. =A0I then use this wave > >> to enable counting of the 50-MHz system clock. =A0So I get a count of > >> how many clock ticks of the system clock occur for one period of > >> string vibration. =A0This takes up to 21 bits for the low strings. =A0=
I
> >> average 32 of these numbers and calculate an error based on a stored > >> setpoint. =A0Currently I'm using a theoretical setpoint, but eventuall=
y
> >> I will want to add the feature whereby a piano tech can hand-tune the > >> piano and then "store" his tuning numbers for subsequent use. > > There is flaw in this approach, which is the Signal to Noise > of a SINGLE cycle. With 44 going off at once, you will have crosstalk. > That 21 bits will be mostly an illusion. > > > Ah, this makes what you are doing much clearer. > > > One immediate suggestion would be this: Rather than using 44 separate > > 50-MHz counters, use just one counter and 44 registers that capture > > the value of that counter when the rising edge of the input occurs. > > > Then, you have a module that scans those 44 latches, and each time > > one is updated, you subtract the previous value from the current value > > (mod 2**21) to get the period for that string. This should save a lot > > of chip resources, converting lots of slice flip-flops into block RAM. > > > The "previous values" can be stored in block RAM, the calibration > > periods can be stored in block RAM, the PWM values can be stored in > > block RAM, etc. Everything except for the 44 latches can be processed > > sequentially rather than in parallel. > > Even simpler, since you KNOW what frequency you want, set up > a pair of Loadable counter, close together as MIN as MIX and generate a > TuneUP and TuneDOWN signal from when outside this error band. > > - drive those into LEDS and your Tune motors. > > Then your datapaths are just the error signals. > > Read up on reciprocal Frequecy counters, these give higher > precisions by counting a time for a certain WHOLE number > of cycles. > To do that, you would preload 3 numbers, the Min/Max counts, and > the cycles to total over. Much better signal to noise. > You might even get the whole thing working in a Block Ram, > as you can lower the 50MHz... > > You don't want the pianist saying your system is crap do you ;) > > -jg- Hide quoted text - > > - Show quoted text -
An ordinary frequency counter is not an option in this application. The lowest note A0 in a piano is 27.5 Hz and I need an accuracy of less than one "cent" (1/100th of a musical semitone). One cent sharp at 27.5 Hz is 27.5 * (2**(1/1200)) =3D 27.5159 Hz That's a difference in frequency of .0159 Hz. To be able to count with this accuracy would require that I count for at least a minute to get each reading. This is unacceptable. Also, please read the publicity I posted the links to, or the patent (6,559,369). I do not use any moving parts to control the string's pitch. Don Kansas City
On Aug 7, 3:38=A0pm, David Tweed <dtw...@acm.org> wrote:
> eromlignod wrote: > =A0> Excuse my thickheadedness, but I'm actually an ME by trade and just > =A0> taught myself HDL a few months ago. > > Really? The press announcments about this system that you linked to > date from 2002-03 or so. Has it really taken that long to begin an > implementation? > > -- Dave Tweed
All of this was originally supposed to be prototyped by an electronics firm in Florida, starting in the summer of 2002. I had a five-year royalty contract with Story & Clark Pianos (QRS) to build it. After the five years was up, they still hadn't got around to starting the project. They kept putting it on the back burner as other projects and financial concerns took priority. I refused to renew their contract in 2007 and am using the minimum royalty money that they had paid me, to build the prototype myself. I thought about a microcontroller for the main processing, but decided that I could probably do it all with the FPGA...and did so, except for this size problem. But I think by implementing some of your ideas, I can considerably reduce the number of slices. Thanks. Don Kansas City
eromlignod wrote:
> I like this idea. But how do I handle the case when the counter rolls > back to zero inside a period measurement? Excuse my thickheadedness, > but I'm actually an ME by trade and just taught myself HDL a few > months ago.
Normally you capture the value, and simply subtract Newest-Previous. IF newest < previous then overflow occured, and you replace as Newest+(MAX-Previous). -jg

eromlignod wrote:

> On Aug 7, 2:57 pm, Jim Granville <no.s...@designtools.maps.co.nz> >> >>Even simpler, since you KNOW what frequency you want, set up >>a pair of Loadable counter, close together as MIN as MIX and generate a >>TuneUP and TuneDOWN signal from when outside this error band. >> >>- drive those into LEDS and your Tune motors. >> >>Then your datapaths are just the error signals. >> >>Read up on reciprocal Frequecy counters, these give higher >>precisions by counting a time for a certain WHOLE number >>of cycles. >>To do that, you would preload 3 numbers, the Min/Max counts, and >>the cycles to total over. Much better signal to noise. >>You might even get the whole thing working in a Block Ram, >>as you can lower the 50MHz... >> >>You don't want the pianist saying your system is crap do you ;) >> >>-jg- Hide quoted text - >> >>- Show quoted text - > > > > An ordinary frequency counter is not an option in this application. > The lowest note A0 in a piano is 27.5 Hz and I need an accuracy of > less than one "cent" (1/100th of a musical semitone). One cent sharp > at 27.5 Hz is > > 27.5 * (2**(1/1200)) = 27.5159 Hz
Read what I wrote carefully. "Read up on reciprocal Frequecy counters" A Reciprocal Frequecy counter is not an ordinary frequency counter :) It counts in two domains: Whole cycles and time. Your values above are a dT of 17.05us. Suppose you measure 3 whole cycles, giving ~9 readings a second then a (relatively low) 1MHz reciprocal Counter will give a 63 count difference on your 15.9mHz dF example. - so is about 6 bits more precise than you need. You can change the sample time, to improve noise filtering, or the Mhz to give you more FPGA time. 500KHz is 100 cycles at 50MHz, (which sounds useful) and still gives 5 bits precision headroom at 9 samples/second. (more at lower samples/sec) eg at a 1-2us timebase, you can edge count 25-50 channels in block ram, with a simple state engine. Interleave the INC and Decision cycles for simplicity.
> > That's a difference in frequency of .0159 Hz. To be able to count > with this accuracy would require that I count for at least a minute to > get each reading. This is unacceptable. > > Also, please read the publicity I posted the links to, or the patent > (6,559,369). I do not use any moving parts to control the string's > pitch.
Wow - what is your power budget ? <paste>
> I thought about a microcontroller for the main processing, but decided > that I could probably do it all with the FPGA...and did so, except for > this size problem. But I think by implementing some of your ideas, I > can considerably reduce the number of slices. Thanks.
A fpga is a good development vehicle. Good luck. -jg
eromlignod wrote:
> On Aug 6, 8:05 pm, John McCaskill <jhmccask...@gmail.com> wrote: >> On Aug 6, 12:31 pm, eromlignod <eromlig...@aol.com> wrote: >> >> >> >> >> >>> On Aug 6, 11:50 am, John McCaskill <jhmccask...@gmail.com> wrote: >>>> If you can map this onto a block ram, you will save quite a bit of >>>> registers. Whether or not you can do this depends on if you can write >>>> the vectors in one (or a few) at a time, and process them sequentially >>>> in the time you have available. How much time do you have to process >>>> the vectors? Ns, us, ms ? >>> Ah, I think I'm following along now. Are you talking about sending >>> the numbers over a single 8-bit vector wire one-at-a-time? Hmmm. >>> The vectors are actually independent from each other and refresh at >>> various random rates, so a few usec here or there shouldn't make a >>> difference. I'll give it a try! >>> Don >> You are asking good questions, so there are multiple people here that >> will be happy to help you out. However, you are asking for some low >> level suggestions without giving enough high level detail. The best >> optimizations are the ones that you apply at the high level where you >> have the most leverage. >> >> If you can tell us more about what you are trying to do you will get >> better responses. You said that you have almost 100 high speed >> channels. >> >> How many channels are there? >> How fast are the pulses arriving on average? >> Over what time is the average? >> What is the air speed of an unladen swallow? >> What is the minimum spacing between pulses? >> How fast does your central processing module need to compare the >> channels? >> >> As Jim Granville pointed our, the various time bases of your problem >> have a major impact on the potential solutions. >> >> Regards, >> >> John McCaskillwww.FasterTechnology.com- Hide quoted text - >> >> - Show quoted text - > > > Well, I'm being a little cryptic because there are new patent > applications involved and I don't want to give too much away. I can > tell you those things that are already covered in the first patent > though. > > The device is a self-tuning piano. You can read/listen about it > here... > > New York Times: > http://query.nytimes.com/gst/fullpage.html?res=9800E1D8133FF931A35752C0A9659C8B63 > > NPR: > http://www.npr.org/templates/story/story.php?storyId=878091 > > New Scientist Magazine: > http://www.newscientist.com/article/dn3143-hotwired-piano-tunes-itself.html > > The incoming signals are square waves at the fundamental frequency of > each of the 219 strings in the piano that are being magnetically > sustained (vibrate forever). I only read 44 strings at a time, tune > them, then go on to the next 44, etc. So there are 44 counting > modules and an output address signal to instruct the sustainer > circuits when to vibrate the next string. > > I first convert the wave to a "period" wave that has an "on" time > equal to one period of the string's vibration. I then use this wave > to enable counting of the 50-MHz system clock. So I get a count of > how many clock ticks of the system clock occur for one period of > string vibration. This takes up to 21 bits for the low strings. I > average 32 of these numbers and calculate an error based on a stored > setpoint. Currently I'm using a theoretical setpoint, but eventually > I will want to add the feature whereby a piano tech can hand-tune the > piano and then "store" his tuning numbers for subsequent use. > > The output of each of these modules is a 16-bit, signed "error" > vector. All 44 errors go to an "evaluation" module where it is > decided how much warmth needs to be applied to each string to tune it, > in the form of 219 PWM duty cycles (0 to 256 each). These numbers > are sent to another two modules and translated to a synchronous serial > output where a separate power circuit decodes and uses them to produce > the individual PWM control lines. Once the "in tune" value of PWM is > found for each string, it is simply maintained until the system is > switched off. Actual adjustments only occur when the system is first > turned on. Currently I can tune each set of 44 strings in about 20 to > 30 seconds. > > The whole system does indeed work just fine so far. I'm just running > out of FPGA space, ostensibly because of my poorly-written code. I > would like to add code to refine the tuning accuracy and time and > possibly add the "store" option, so I need all the space I can get. > > Thanks for all of the excellent help so far! > > Don A. Gilmore > Kansas City >
Don, That's quite fascinating. Are you concerned about the 600W of heat drying out the piano wood? I know some pianos have humidifiers inside them so it seems like a potential issue. -Jeff