2016-06-10 3 views
-1

J'essaye de faire une conversion de Kilogramme en Lib, pour cela j'utilise des shifters pour faire la conversion (j'aurai une petite erreur due à la représentation de la sortie ne sera pas fractionnaire), j'ai trouvé la bonne fonction et les valeurs pour faire la conversion, quand je dis cela, je veux dire que mes valeurs de décalage sont correctes, si quelqu'un veut la fonction de conversion, faites le moi savoir dans les commentaires ci-dessous.Erreur de débordement dans le décalage? VHDL

Mon problème est: quand je mets une valeur supérieure à 130 KG, la conversion se passe mal, de petites valeurs puis 130 KG fonctionne correctement. J'utilise une entrée avec 16 bits (Kilogram Input) et une sortie 16 bits (LB Output). Lorsque cette erreur apparaît, je pense que la première fois était une erreur de débordement dans les additionneurs, mais tous les additionneurs ne montrent pas l'exécution, donc il ne peut pas être débordement sur les additionneurs. J'ai essayé d'utiliser une plus grande représentation dans les valeurs (32 bits), mais l'erreur apparaît toujours. J'ai supprimé les sorties d'exécution en raison de cela.

Ci-dessous les codes:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity shift_register is 
port (
    i_DIN : in unsigned (15 downto 0); 
    o_DOUT0 : out unsigned (15 downto 0); 
    o_DOUT1 : out unsigned (15 downto 0); 
    o_DOUT2 : out unsigned (15 downto 0); 
    o_DOUT3 : out unsigned (15 downto 0)); 
end shift_register; 

architecture arch_1 of shift_register is 
begin 
    o_DOUT0 <= i_DIN SLL 9; 
    o_DOUT1 <= i_DIN SLL 5; 
    o_DOUT2 <= i_DIN SLL 2; 
    o_DOUT3 <= i_DIN SLL 1; 
end arch_1; 

Sur cette partie, je ferai des 4 changements nécessaires pour le travail de conversion, après cela je reçois 4 valeurs de sortie et somme en 2 demi-additionneurs.

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity half_adder is 
port (
    i_DIN0 : in unsigned(15 downto 0); -- data input 
    i_DIN1 : in unsigned(15 downto 0); -- data input 
    o_DOUT : out unsigned(16 downto 0)); -- data output 
end half_adder; 


architecture arch_1 of half_adder is 
begin 
process(i_DIN0,i_DIN1) 
    variable soma:unsigned(15 downto 0); 
    variable c:std_logic; 
    begin 
      c :='0'; 
      for i in 0 to 15 loop 
       soma(i) := i_DIN0(i) xor i_DIN1(i) xor c; 
       c := (i_DIN0(i) and i_DIN1(i)) or ((i_DIN0(i) xor i_DIN1(i)) and c); 
      end loop; 
      o_DOUT(15 downto 0)<= soma(15 downto 0); 
      o_DOUT(16) <= c; 
     end process; 
end arch_1; 

je vais avoir 2 sorties, 1 pour chaque demi-additionneur, ce 2 sorties i somme dans un additionneur complet pour obtenir la valeur de décalage finale, le report à partir des 2 demi-additionneurs sont concaténés dans le dernier bit de chaque sortie.

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity full_adder is 
port (
    i_DIN0 : in unsigned(16 downto 0); 
    i_DIN1 : in unsigned(16 downto 0); 
    o_DOUT : out unsigned(16 downto 0)); 
end full_adder; 

architecture arch_1 of full_adder is 
begin 
    process(i_DIN0,i_DIN1) 
    variable soma:unsigned(16 downto 0); 
    variable c:std_logic; 
    begin 
      c := '0'; 
      for i in 0 to 16 loop 
       soma(i) := i_DIN0(i) xor i_DIN1(i) xor c; 
       c := (i_DIN0(i) and i_DIN1(i)) or ((i_DIN0(i) xor i_DIN1(i)) and c); 
      end loop; 
      o_DOUT <= soma; 
     end process; 
end arch_1; 

Ici, je ne concaténer pas effectuer de l'additionneur complet du dernier bit de la sortie parce que je veux montrer le report si le dépassement de la somme. En fin de compte, je divise la somme des 4 décalages initiaux pour obtenir la valeur convertie.

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
entity kg_to_lb is 
port (
    i_INPUTKG : in unsigned(15 downto 0); -- data input 
    o_OUTLB : out unsigned(16 downto 0)); -- data output 
end kg_to_lb; 


architecture arch_1 of kg_to_lb is 

component full_adder is 
    port (
    i_DIN0 : in unsigned(16 downto 0); 
    i_DIN1 : in unsigned(16 downto 0); 
    o_DOUT : out unsigned(16 downto 0)); -- data output 
end component; 

component half_adder is 
port (
    i_DIN0 : in unsigned(15 downto 0); -- data input 
    i_DIN1 : in unsigned(15 downto 0); -- data input 
    o_DOUT : out unsigned(16 downto 0)); -- data output 
end component; 

component shift_register is 
port (
    i_DIN : in unsigned (15 downto 0); 
    o_DOUT0 : out unsigned (15 downto 0); 
    o_DOUT1 : out unsigned (15 downto 0); 
    o_DOUT2 : out unsigned (15 downto 0); 
    o_DOUT3 : out unsigned (15 downto 0)); -- data output 
end component; 

component div_register is 
port (
    i_DIN : in unsigned (16 downto 0); 
    o_DOUT : out unsigned (16 downto 0)); -- data output 
end component; 



signal w_OUT0 : unsigned(15 downto 0); 
signal w_OUT1 : unsigned(15 downto 0); 
signal w_OUT2 : unsigned(15 downto 0); 
signal w_OUT3 : unsigned(15 downto 0); 
signal w_OUT4 : unsigned(16 downto 0); 
signal w_OUT5 : unsigned(16 downto 0); 
signal w_OUT6 : unsigned(16 downto 0); 
signal w_OUT7 : unsigned(16 downto 0); 

begin 

u_0: shift_register port map (
       i_DIN => i_INPUTKG, 
       o_DOUT0 => w_OUT0, 
       o_DOUT1 => w_OUT1, 
       o_DOUT2 => w_OUT2, 
       o_DOUT3 => w_OUT3 
       ); 

u_1: half_adder port map (
       i_DIN0 => w_OUT0, 
       i_DIN1 => w_OUT1, 
       o_DOUT => w_OUT4 
       ); 

u_2: half_adder port map (
       i_DIN0 => w_OUT2, 
       i_DIN1 => w_OUT3, 
       o_DOUT => w_OUT5 
       ); 

u_3: full_adder port map (
       i_DIN0 => w_OUT4, 
       i_DIN1 => w_OUT5, 
       o_DOUT => w_OUT6 
       ); 

u_4: div_register port map (
       i_DIN => w_OUT6, 
       o_DOUT => w_OUT7 
       ); 

o_OUTLB <= w_OUT7; 

end arch_1; 

Voici mon dossier principal, où je l'ai fait tout cela, au fond, je suis en utilisant la même architecture de l'image ci-dessous, la seule différence est les changements, parce que je l'utilise encore des valeurs dans ma fonction de conversion, mais avec les changements de l'imagem l'erreur se produit encore.

Main Architecture

Ci-dessous la conversion correcte:

110KG conversion

Comme je l'ai dit avant, il existera une erreur en raison du diregarding de la partie fractionay. Quand je entrée une valeur plus grande que la conversion 130kg va mal:

conversion error

NOTE: Dans ma simulation je ne l'ai pas mis la porte à partir de l'additionneur complet parce que je l'ai déjà simulé cela, et Does'nt apparaît effectuer (erreur de débordement) dans la simulation, en raison de cela, je pense que l'erreur est dans les quarts de travail.

Quelqu'un sait ce que c'est?

+2

Veuillez créer un [exemple minimal, complet et vérifiable] (http://stackoverflow.com/help/mcve), car cela révélera peut-être le problème et facilitera l'assistance aux autres utilisateurs. –

+0

Qu'est-ce qui manque? Je pense que tout cela est nécessaire pour trouver le problème ... – Mutante

+1

En fait, l'erreur dépasse 127 kg, et c'est un problème de précision avec le shift_register ('o_DOUT0 <= i_DIN SLL 9;'). les valeurs kg supérieures à 127 (8 bits ou plus) décalées à gauche 9 bits déposent des bits sur le sol pour une valeur de 16 bits. – user1155120

Répondre

0

L'erreur était dans la largeur des registres internes, quand je décale la logique 9, pour des valeurs supérieures à 8 bits, la sortie reste à 0 car le décalage était grand, la solution était d'utiliser un registre plus grand. Cas).