Electronic – Verilog bit direction

verilog

I am buffering in data from an ADC. The data comes in MSB-first. Naturally, I have a 16-bit register to buffer in the data:

reg [0:15] sample_in;

The MSB index is 0, since it comes in first. This makes the most sense when your indexer is a simple counter. I am using a floating-point conversion module that looks like this:

module int16_to_float(input [15:0] a, output [31:0] b);

As you can see, the input has a different bit direction from my original register.

My question is this: If I set the input a to my register sample_in, is the synthesizer smart enough to wire them together MSB-to-MSB, or does it simply stick them together? In my case, sample_in LSB would be wired to a MSB, and vice-versa.

Also, I realize it's easy to change the sample_in bit direction, making everything match. This is more of a theoretical question that a practical one.

Best Answer

My suggestion would be to always keep the bit directions the same in your design. To my knowledge some Verilog compilers don't support automatically connecting buses with opposite directions. I know that I have had issues with Quartus for example connecting buses where the bits are opposite ways around.

If your compiler isn't smart enough to do it automatically, there are two options given your ADC has bits in the opposite directions (*).

Option 1

You can write both registers in the same order (recommended), and then use the following function to reverse the bits. The loop in this function infers only the bits in the wire being swapped, there is no logic added whatsoever.

//Function for reversing the number of bits in a parallel bus.
function [16-1:0] bitOrder (
    input [16-1:0] data
);
integer i;
begin
    for (i=0; i < 16; i=i+1) begin : reverse
        bitOrder[16-1-i] = data[i]; //Note how the vectors get swapped around here by the index. For i=0, i_out=15, and vice versa.
    end
end
endfunction

//Example usage
reg [15:0] sample_in; //your sample in
wire [15:0] sample_rev; //bit order reversed, but note the direction of the declared vector is the same.
assign sample_rev = bitOrder(sample_in); //swap the bits.

Option 2

If you do want your bits to be in the opposite order, it should be possible to do the same as above as below. But I would recommend option 1 if possible, best to keep all your vectors the same bit order for better compatibility..

//Function for connecting bits in two parallel buses with opposite directions.
function [16-1:0] bitOrder (
    input [0:16-1] data
);
integer i;
begin
    for (i=0; i < bitOrder_WIDTH; i=i+1) begin : reverse
        bitOrder[i] = data[i]; //Index is the same as this is just to help synthesiser correctly assign bits.
    end
end
endfunction

//Example usage
reg [0:15] sample_in; //your sample in
wire [15:0] sample_rev; //direction reversed
assign sample_rev = bitOrder(sample_in); //swap the bits.

Note (*): But who is to say which 'direction' means what in your firmware, you are free to choose. Depending on how you handle the data [15:0] could mean LSB 'first' or MSB 'first'.