Papilio One as High Speed DAQ


Recommended Posts



I just bought a papilio one and logic start shield, and I'd like to use these as a high-speed data acquisition device.


I'd like it to count pulses sent to it via an external pulse generator, then when it receives some sort of command from a computer, transmit to the computer how many pulses it had received since the last transmission request.


I was hoping an experienced user could tell me how they would approach this problem.


Best wishs,



Link to comment
Share on other sites



if I had to implement it in the smallest amount of time, I'd use an existing UART to interface to the PC.

  • One command from the uart, e.g. the character 'a', resets a counter.
  • Pulses increase the counter.
  • A second command, e.g. the character 'b' from the UART, kicks off a state machine that saves the counter state, then transmits in chunks of four bits as hex characters.

It's not a difficult design and you can expect to reach a sampling rate of maybe 200 MHz with moderate effort.

But, be aware that digital design has a fairly steep learning curve.


An alternative is to control the counter from a CPU bus, i.e. as a Wishbone device. If I have a working development environment for e.g. a ZPU with C compiler, the digital design effort for that approach is very small. But as said, I'd use hand-coded state machines.

Link to comment
Share on other sites

Here's a UART:


You send a byte by putting it on "tx_byte" and raising "transmit" for one clock cycle.

Try it in the simulator, e.g. iverilog.

At this level, there is only one "type" of data, that's a byte. My state machine needs to wait, until the UART is idle again (as flagged by is_transmitting falling back to low).

Link to comment
Share on other sites

You might find a pulse counter design already on the internet.  Of course, you'd still have to see if its capabilities meet your needs, and perhaps modify it to work on the Papilio too.


As for developing one, the difficult part may be the counter, not the UART.  It depends on how fast you need the counter to be, and how fancy you need the protocol to be.


If the counter logic is sampling input at 200MHz, then the shortest pulse must be more than 5 ns, and the shortest gap between pulses must be more than 5 ns, and the actual rate of pulses must be less than 100MHz.


It's easiest if all logic on the FPGA is running at the same speed.  (It's by no means required, but it's easiest.)  Your counter might be fast, and your UART might be fast, but if you have a CPU, it'll be rather slower (the fastest I'm aware of is 128MHz and that's on Papilio Pro).


I'd consider two, quite different approaches, with different advantages and disadvantages.


Approach 1: A CPU, with counter and UART attached to it.  The only custom parts are the pulse counter, and the software running on the CPU.  The CPU would allow you to make the protocol as complicated as you'd like.  But it also limits the speed of your counter.  This approach has less "custom" stuff, and may be easier for that reason.


Approach 2: A counter and a UART.  This lends itself to a fast counter, but a very limited protocol.  Perhaps just sending the numeric counter value, over and over again, as fast as possible.  This approach has more "custom" stuff, but less stuff overall, and may be easier for that reason.


(There's also an approach 3, with all the counting done in software.  Easy, quite slow, could be done on a micro controller instead of an FPGA.)


Approach 1 allows a fancier protocol, while approach 2 allows greater speed.  Each may be easier depending on your skill set.


Regarding sending different types of data through a UART:  What's transmitted through a UART is bytes, usually 8 bits each.  There are a lot of different ways to represent a type in bytes.  I'd recommend using what's easiest to encode, even if it isn't very "pretty," effectively moving the complicated parts from the FPGA to your host computer.


The prettiest representation for a number would be in decimal ASCII.  The number 1234 might be represented then as five byte values: 48, 49, 50, 51, and 32 (the 32 is just a space).  But while it's easiest to read, it can be a pain to encode.


The easiest to encode would be a single byte numeric value.  But you're limited to the range 0-255, and some software on your computer may try to interpret parts of that range as control codes.


There are a lot of other encoding options in between those two extremes.  Hexadecimal (base 16) is easier to encode; it's especially easy when you have a CPU; and it's still fairly easy to read.  "Base-64" is similarly easy to encode, and more compact; harder to decode, but not really hard.


Do you really need to accept commands from the computer?  That's a tricky part in itself.  I'd try to do without it if possible.  If you need to know how many pulses between two points in time, just subtract the two counts on the computer side.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.