1
\$\begingroup\$

Data comes in from a module where the valid bits are going to be between 1 and 32. A word comes along with data that indicates how many bits are valid starting from the least significant bit. This data stream needs to be combined into a register. When the register reaches 128 bits of data, the data is shifted to external memory (FIFO in this case) and the process starts again.

Here is a diagram:

enter image description here

A simple way to do this is to create a mux. The mux has 256 outputs. Each input is the variable size input shifted by one extra bit. So with sel 0 we have data shifted by 0 bits, with sel 1 we have data shifted by 1 bit and so on. We then OR the new data with the data in the register. The register is always created to zero. The solution works but creates a very big multiplexer and fails timing!

This means that this process must be pipelined. But I am not completely sure how it should be pipelined. One way is that there be a large number of pipeline stages (where each stage shifts data away from the least significant bit) like this: first stage can shift data by 128 bits, next stage can shift data by 64 bits, next stage can shift data by 32 bits, next stage can shift data by 16 bits, next stage can shift data by 8 bits, next stage can shift data by 4 bits, next stage can shift data by 2 bits and last stage can shift data by 1 bit. However, a mechanism must still be worked out to decide if the shift is applied or the data is passed to next stage unchanged.

Is this a reasonable approach or there is a better way to design this?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Start by breaking the problem into two parts:

  • Assembling 1-32 bits into 32-bit words
  • Assembling 32-bit words into 128-bit words

For the first part, you need a "barrel shifter" — a piece of logic that can shift N bits of data by M bits in one step.

Here's a secret: A multiplier makes a fine barrel shifter, and most FPGAs are full of hardware multiplier blocks.

Note that the second part could be handled by having a 32-bit write port on your RAM, and a 128-bit read port.

\$\endgroup\$
6
  • \$\begingroup\$ A barrel shifter works by moving data around in a circle such that when a bit is shifted beyond the MSb, it comes back to the MSb rather than be dropped. This is why I believe that barrel shifter is not required here. \$\endgroup\$
    – gyuunyuu
    Commented Jul 23 at 17:42
  • \$\begingroup\$ I think you are implying that I use a multiplier in each stage which is possible, but shifting data (for pipelined design) means using a lot of multipliers. Or perhaps you mean that I use a single multiplier and make the other operance 2^n where n is the number of bits to shift by and then I do not need a mux anymore. \$\endgroup\$
    – gyuunyuu
    Commented Jul 23 at 17:44
  • \$\begingroup\$ Yes, the second one. Multiply by 2^N. The barrel shifter in this case is 64 bits wide, so the data never actually wraps around. \$\endgroup\$
    – Dave Tweed
    Commented Jul 23 at 17:49
  • \$\begingroup\$ From what I know, barrel shifter can take a lot of routing resource in the FPGA and although it can be used, its better to use something else in its place on FPGA design. Is this true? \$\endgroup\$
    – gyuunyuu
    Commented Jul 23 at 21:37
  • \$\begingroup\$ Like I said, use the multiplier as your barrel shifter. The inputs to the multiplier are the 1-32 bit number (masked appropriately) and 2^N, where N is the amount you want to shift by (1-32 bits), The output of the 32x32 multiply is a 64-bit result that you store in a register until you have accumulated a full 32 bits, at which point you transfer that half of the result to your memory. It's getting late, but I can draw you a block diagram in the morning. \$\endgroup\$
    – Dave Tweed
    Commented Jul 24 at 3:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.