web-dev-qa-db-fra.com

Ordre des bits inversé sur VHDL

J'ai du mal à faire quelque chose comme

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

quand je le compile avec ghdl, j'ai une erreur de commande. Le seul moyen que j'ai trouvé pour faire fonctionner mon circuit est le suivant:

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? Merci d'avance

16
titockmente

Ce n'est pas autorisé - VHDL est tellement typé que si vous voulez inverser les ordres de bits, vous devez le faire explicitement.

La solution standard consiste à utiliser une fonction (je n'ai pas écrit ceci - Jonathan Bromley l'a fait ):

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
22
Martin Thompson

Il existe plusieurs solutions à ce problème. Une possibilité est la suivante:

gen: for i in 0 to 7 generate
  y(i) <= a(i) when rev='0' else a(7-i);
end generate;
4
VAP

La question demande comment traiter spécifiquement avec b(0 to 7) <= a(7 down 0). Je ne connais pas les raisons, mais parfois cette affectation fonctionne pour moi (assigne les choses de gauche à droite, quel que soit le découpage) et parfois, elle génère des erreurs de compilation (découpage incorrect ou autre).

Heureusement, vous n'avez pas besoin d'utiliser une fonction pour gérer le découpage incorrect. Si vous obtenez des erreurs de compilation pour ce problème spécifique, vous pouvez utiliser une boucle generate pour affecter a à 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;

En gros, il fait la même tâche déroulée que dans votre exemple, à la fois étroite et évolutive. 

J'ai également utilisé ce modèle lorsque j'ai mal découpé du côté droit de la tâche. Par exemple:

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;

Ce qui équivaut à:

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);
3
Matt Dallmeyer

Vraiment inverser:

for i in 0 to intermediate_data'left loop

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

end loop;
2
menniwick

Suggestions?

Parce que votre exemple spécifie une longueur fixe:

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;

La théorie étant que cela devrait être moins lourd qu'un appel de fonction ou une déclaration de boucle.

0
user1155120