Vhdl como adicionar um std_logic_vector com um sinal std_logic juntos?
-
22-09-2019 - |
Pergunta
eu tenho
douta : in std_logic_vector (3 downto 0);
doutb : in std_logic_vector (3 downto 0);
c0 : in std_logic;
f1 : in std_logic;
f0 : in std_logic;
res : out std_logic_vector (3 downto 0);
Estou tentando construir um ALU simples, e uma das funções que este ALU oferece é quando
f1 and f0 both = 1
res = douta plus b plus c0
Então eu escrevi
f1 = '1' and f0 = '1' then res <= douta + doutb + c0;
Mas obviamente não vai funcionar porque o tipo de dados de douta
e doutb
é std_logic_vector
enquanto co
é apenas std_logic
e eu recebi esse erro quando compilar
' Error 603 line 34 : Incompatible types for arithmetic operator: LHS=std_logic_vector!18, RHS=std_logic
Alguma ideia de como posso resolver esse problema?
editar:Também tentei
f1 = '1' and f0 = '1' then res <= douta + doutb + ("000" & c0);
Mas ainda não há sorte, desta vez o compilador diz
LHS=std_logic_vector!7, RHS=array_1_of_std_logic_3_d_0
Solução 3
Oh, acho que encontrei uma correção, preciso adicionar a seguinte biblioteca
use ieee.std_logic_arith.all;
E o que tentamos funcionará :) Obrigado a @jdehaan
Outras dicas
Por favor, não use std_logic_vector
Se você vai fazer aritmética neles. Usar ieee.numeric_std
, e usar o signed
ou unsigned
tipos. Então você pode simplesmente adicionar o seu '0' ou '1'.
A solução alternativa de usar std_logic_arith.all
é um caldo usando uma biblioteca não padrão, que pode levar você a problemas de portabilidade quando você troca de cadeias de ferramentas.
Eu escrevi uma página mais detalhada sobre isso: http://parallelpoints.com/node/3
Houve alguma discussão sobre isso em comp.lang.vhdl aqui: http://groups.google.com/group/comp.lang.vhdl/browse_thread/thread/549e1bbffd35914d/83cc0f19350fc392?hl=en&q=group:comp.lang.vhdl+numeric_std#83cc0f19350fc392 e também no comp.lang.vhdl FAQ.
Você pode transformar C0 em um std_logic_vector. Já faz muito tempo desde que fiz Vhdl ...
if f1 = '1' and f0 = '1' then
if c0 = '1' then
res <= douta + doutb + "0001";
else
res <= douta + doutb;
end if;
end if;
Provavelmente isso não é tão performante, talvez o compilador de silicium o sintetize, então algo bom, talvez seja uma idéia melhor escrevê -lo para que C0 seja modificado em um vetor e adicione os três Douta, Doutb e o conversor C0. Outra opção seria fazer o bit de cálculos para o bit, mas então para que você tem o compilador?
Pode parecer ridículo, mas às vezes o compilador produz um resultado melhor se você der algumas dicas como essa (basta experimentar e verifique a saída, por um exemplo tão pequeno, não um grande negócio):
if f1 = '1' and f0 = '1' then
if c0 = '1' then
res <= douta + doutb + "0001";
else
res <= douta + doutb + "0000";
end if;
end if;
Outro conselho, se você escrever se e os resultados são um pouco estranhos, apresente um else para consertar os estados indecisos (alguns compiladores se comportam mal se tiverem muita liberdade!). Mas isso é da minha experiência que já está voltando ao ano de 2004 !!!
Você não precisa converter o std_logic em um std_logic_vector para fazer a adição. Basta fazer a adição como está e verifique se "res" tem bits suficientes para manter a resposta máxima. Nesse caso, o RES precisa ter 5 bits de largura para que agora exagere.
E como um estilo NIT, não nomeie suas portas de entrada "Dout". Essa é uma forma ruim. Chame -os de Din aqui, porque é isso que eles são. E na arquitetura do que instancia isso, você conecta a porta de saída de outro componente denominada "Dout" ao "DIN" deste componente.