Reverse bit order on VHDL
Asked Answered
U

6

22

I'm having trouble doing something like

b(0 to 7) <= a(7 downto 0)

when I compile it with ghdl, I have an order error. The only way I have found to make my circuit work is the following:

library ieee;
use ieee.std_logic_1164.all;
entity reverser is
    port(
        a: in std_logic_vector(7 downto 0);
        y: out std_logic_vector(7 downto 0);
        rev: in std_logic
        );
end reverser;

architecture rtl of reverser is
    signal b: std_logic_vector (7 downto 0);

begin

    b(7) <= a(0);
    b(6) <= a(1);
    b(5) <= a(2);
    b(4) <= a(3);
    b(3) <= a(4);
    b(2) <= a(5);
    b(1) <= a(6);
    b(0) <= a(7);

    y <= b when rev = '1' else a;

end rtl;

Suggestions? Thanks in advance

Usage answered 27/11, 2012 at 12:31 Comment(2)
Although it will not help for the bit-reverse operation, the descending range keyword is downto (ie not down to).Zacynthus
sorry for the mistake what I mean was that. b(0 to 7) <= a (7 downto 0)Usage
E
35

That's not allowed - VHDL is so strongly typed that if you want to reverse bit orders, you have to do it explicitly.

The standard solution is to use a function (I didn't write this - Jonathan Bromley did):

function reverse_any_vector (a: in std_logic_vector)
return std_logic_vector is
  variable result: std_logic_vector(a'RANGE);
  alias aa: std_logic_vector(a'REVERSE_RANGE) is a;
begin
  for i in aa'RANGE loop
    result(i) := aa(i);
  end loop;
  return result;
end; -- function reverse_any_vector
Encephalography answered 27/11, 2012 at 13:5 Comment(0)
R
5

There are several solutions for this problem. One possibility is the following:

gen: for i in 0 to 7 generate
  y(i) <= a(i) when rev='0' else a(7-i);
end generate;
Romanfleuve answered 5/1, 2014 at 20:42 Comment(0)
M
4

The question asks how to deal specifically with b(0 to 7) <= a(7 down 0). I don't know of the reasons, but sometimes this assignment works for me (assigns things from left to right regardless of the slicing) and sometimes this assignment throws compiler errors (mismatched slicing or something).

Fortunately you do not need to use a function to handle mismatched slicing. If you are getting compiler errors for this specific problem you can use a generate loop to assign a to b.

for i in a'range generate
   b(i) <= a(i)  
   --when i is 0, you assign a's right-most bit to b's left-most bit
end generate;

It does basically the same unrolled assignment as in your example, just tight and scale-able.

I've also used this pattern when I have mismatched slicing on the right side of the assignment. For example:

signal a : std_logic_vector(0 to 7);
signal b : std_logic_vector(7 downto 0);
signal c : std_logic_vector(0 to 7);

...

for i in a'range generate
   c(i) <= a(i) xor b(i);
end generate;

Which is equivalent to:

c(0) <= a(0) xor b(0);
c(1) <= a(1) xor b(1);
c(2) <= a(2) xor b(2);
c(3) <= a(3) xor b(3);
c(4) <= a(4) xor b(4);
c(5) <= a(5) xor b(5);
c(6) <= a(6) xor b(6);
c(7) <= a(7) xor b(7);
Mise answered 4/10, 2013 at 1:32 Comment(1)
By default, given the a/b vectors you've defined above and the statement "b <= a" (or the equivalent in a PORT MAP), VHDL will assign the vector bits in order left to right, regardless of numbering. This preserves MSB == MSB when using a mixture of big-endian and little-endian bit ordering. (ie. b(7) <= a(0) etc.) You get the error if you attempt to use "a(x downto y)" or b(x to y)" -- ie. if you attempt to reverse the declared order of a specific signal. If you intentionally want to map the bits out of order then you need to use a generate or function as shown in these answers.Gertudegerty
G
1

Really inverting:

for i in 0 to intermediate_data'left loop

  inverted_vector(i) <= intermediate_data(intermediate_data'left - i);

end loop;
Granada answered 18/10, 2016 at 11:7 Comment(0)
R
0

Suggestions?

Because your example specifies fixed length:

architecture rtl of reverser is 
    -- signal b: std_logic_vector (7 downto 0);

begin

    -- b(7) <= a(0);
    -- b(6) <= a(1);
    -- b(5) <= a(2);
    -- b(4) <= a(3);
    -- b(3) <= a(4);
    -- b(2) <= a(5);
    -- b(1) <= a(6);
    -- b(0) <= a(7);

    -- y <= b when rev = '1' else a;

    y <= a(0)&a(1)&a(2)&a(3)&a(4)&a(5)&a(6)&a(7) when rev = '1' else a;

end rtl;

The theory being that this should be less overhead than a function call or loop statement.

Riojas answered 15/6, 2014 at 9:39 Comment(2)
If that comes out of the synthesizer any different to a loop or a function call, I'd be logging a bug!Encephalography
Ahh, OK, I see what you mean!Encephalography
K
-10

OUT_PUT(7 DOWNTO 0) <= IN_PUT(0 DOWNTO 7)

Korney answered 14/6, 2014 at 5:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.