Estoy tratando de hacer una sencilla BCD --> binario operación de conversión de trabajo en una ALU estoy de codificación. Todas las otras operaciones de trabajo perfectamente bien, sólo esta última operación no funciona por alguna razón.
He intentado numerosos enfoques y nada parece tener sentido.
Mis entradas son A
y B
que son de 8 bits en vectores. Las salidas son X
y Y
.
Así que la fórmula va Y:X = BCD2BIN(B:A)
.
En mi caso, en mi testbench he B = 0x40
y A = 0x46
, por lo que el resultado que estoy esperando es 0xFCE
, que es 4046.
Sólo para aquellos que son conscientes de la forma más sencilla de realizar esto es dividir cada byte en 2 nibbles, y se multiplica por una constante y la suma de los términos.
Así:
B:A = 0x4046 = (4 * 1000) + (0 * 100) + (4 * 10) * (6 * 1)
Señales de que estoy Usando
B = 0x40 --These are the inputs of the ALU, so it isn't actually coded this way.
A = 0x46 --However these are the values.
signal sig1000 : STD_LOGIC_VECTOR(15 downto 0) := x"03E8"; --1000
signal sig100 : STD_LOGIC_VECTOR(15 downto 0) := x"0064"; --100
signal sig10 : STD_LOGIC_VECTOR(15 downto 0) := x"000A"; --10
signal dig1 : STD_LOGIC_VECTOR(3 downto 0);
signal dig2 : STD_LOGIC_VECTOR(3 downto 0);
signal dig3 : STD_LOGIC_VECTOR(3 downto 0);
signal dig4 : STD_LOGIC_VECTOR(3 downto 0);
Después de COMENZAR el
dig1 <= B(7 downto 4);
dig2 <= B(3 downto 0);
dig3 <= A(7 downto 4);
dig4 <= A(3 downto 0);
De La Operación Real
opF <= STD_LOGIC_VECTOR((unsigned(dig1) * unsigned(sig1000)) + (unsigned(dig2) * unsigned(sig100)) + (unsigned(dig3) * unsigned(sig10)) + (unsigned(dig4)));
Y más tarde, el opF quede dividida en y y X.
Así que incluso la verificación de las señales en la simulación, son correctas, sin embargo, la salida no es.
El sig10001
, sig100
y sig10
son los valores correctos y dig1 = 4
, dig2 = 0
, dig3 = 4
y dig4 = 6
con base decimal sin signo.
Sin embargo, el resultado es de 252
Incluso he intentado esta utilizando constantes, en lugar de vectores, con menos éxito.
Por ejemplo
opF <= STD_LOGIC_VECTOR((unsigned(dig1) * 10#1000#) + (unsigned(dig2) * 10#100#) + (unsigned(dig3) * 10#10#) + (unsigned(dig4)));
Archivo completo, como algunos lo han solicitado.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU is
Port ( A : in STD_LOGIC_VECTOR (7 downto 0);
B : in STD_LOGIC_VECTOR (7 downto 0);
Cin : in STD_LOGIC;
OPCODE : in STD_LOGIC_VECTOR (3 downto 0);
Y : out STD_LOGIC_VECTOR (7 downto 0);
X : out STD_LOGIC_VECTOR (7 downto 0);
Z : out STD_LOGIC;
Cout : out STD_LOGIC;
V : out STD_LOGIC;
F_active : out STD_LOGIC;
X_bin_pal : out STD_LOGIC;
X_prime : out STD_LOGIC;
N : out STD_LOGIC);
end ALU;
architecture Behavioral of ALU is
signal resultSignal : STD_LOGIC_VECTOR(15 downto 0);
signal cin_vector : STD_LOGIC_VECTOR(0 downto 0);
signal op0 : STD_LOGIC_VECTOR(15 downto 0);
signal op1 : STD_LOGIC_VECTOR(15 downto 0);
signal op2 : STD_LOGIC_VECTOR(15 downto 0);
signal op3 : STD_LOGIC_VECTOR(15 downto 0);
signal op4 : STD_LOGIC_VECTOR(15 downto 0);
signal op5 : STD_LOGIC_VECTOR(15 downto 0);
signal op6 : STD_LOGIC_VECTOR(15 downto 0);
signal op7 : STD_LOGIC_VECTOR(15 downto 0);
signal op8 : STD_LOGIC_VECTOR(15 downto 0);
signal op9 : STD_LOGIC_VECTOR(15 downto 0);
signal opA : STD_LOGIC_VECTOR(15 downto 0);
signal opB : STD_LOGIC_VECTOR(15 downto 0);
signal opC : STD_LOGIC_VECTOR(15 downto 0);
signal opD : STD_LOGIC_VECTOR(15 downto 0);
signal opE : STD_LOGIC_VECTOR(15 downto 0);
signal opF : STD_LOGIC_VECTOR(15 downto 0);
signal dig1 : STD_LOGIC_VECTOR(3 downto 0);
signal dig2 : STD_LOGIC_VECTOR(3 downto 0);
signal dig3 : STD_LOGIC_VECTOR(3 downto 0);
signal dig4 : STD_LOGIC_VECTOR(3 downto 0);
signal Xsig : STD_LOGIC_VECTOR(7 downto 0) := x"00";
signal Xsig_reverse : STD_LOGIC_VECTOR(7 downto 0) := x"00";
signal Ysig : STD_LOGIC_VECTOR(7 downto 0) := x"00";
signal Zsig : STD_LOGIC := '0';
signal Coutsig : STD_LOGIC := '0';
signal Vsig : STD_LOGIC := '0';
signal Nsig : STD_LOGIC := '0';
signal sig1000 : STD_LOGIC_VECTOR(15 downto 0) := x"03E8";
signal sig100 : STD_LOGIC_VECTOR(15 downto 0) := x"0064";
signal sig10 : STD_LOGIC_VECTOR(15 downto 0) := x"000A";
begin
cin_vector(0) <= Cin;
dig1 <= B(7 downto 4);
dig2 <= B(3 downto 0);
dig3 <= A(7 downto 4);
dig4 <= A(3 downto 0);
op0 <= x"00" & (A AND B);
op1 <= x"00" & (A OR B);
op2 <= x"00" & (A XOR B);
op3 <= x"00" & (A XNOR B);
op4 <= STD_LOGIC_VECTOR(unsigned(x"00" & A) + unsigned(x"00" & B));
op5 <= x"00" & STD_LOGIC_VECTOR(signed(A) + signed(B));
op6 <= STD_LOGIC_VECTOR(unsigned(x"00" & A) + unsigned(x"00" & B) + unsigned(x"000" & "000" & cin_vector));
op7 <= STD_LOGIC_VECTOR(signed(A) * signed(B));
op8 <= STD_LOGIC_VECTOR(unsigned(A) * unsigned(B));
op9 <= STD_LOGIC_VECTOR(unsigned(x"00" & A) - unsigned(x"00" & B));
opA <= STD_LOGIC_VECTOR(ROTATE_LEFT(unsigned(A & x"00"), 1));
opB <= STD_LOGIC_VECTOR(ROTATE_LEFT(unsigned(Cin & A & "0000000"), 1));
opC <= STD_LOGIC_VECTOR(SHIFT_RIGHT(unsigned(A & x"00"), 1));
opD <= STD_LOGIC_VECTOR(SHIFT_RIGHT(signed(A & x"00"), 1));
opE <= STD_LOGIC_VECTOR(SHIFT_LEFT(unsigned(A & x"00"), 1));
opF <= STD_LOGIC_VECTOR((unsigned(dig1) * unsigned(sig1000)) + (unsigned(dig2) * unsigned(sig100)) + (unsigned(dig3) * unsigned(sig10)) + (unsigned(dig4)));
with OPCODE select resultSignal <=
op0 when x"0",
op1 when x"1",
op2 when x"2",
op3 when x"3",
op4 when x"4",
op5 when x"5",
op6 when x"6",
op7 when x"7",
op8 when x"8",
op9 when x"9",
opA when x"A",
opB when x"B",
opC when x"C",
opD when x"D",
opE when x"E",
opF when x"F";
Ysig <= resultSignal(15 downto 8) when OPCODE = "0111" or OPCODE = "1000" or OPCODE = "1111" else
x"00";
Y <= Ysig;
Xsig <= resultSignal(15 downto 8) when OPCODE = "1100" or OPCODE = "1101" or OPCODE = "1110" else
resultSignal(15 downto 9) & resultSignal(0) when OPCODE = "1010" else
resultSignal(14 downto 8) & resultSignal(0) when OPCODE = "1011" else
resultSignal(7 downto 0);
Xsig_reverse <= Xsig(0) & Xsig(1) & Xsig(2) & Xsig(3) & Xsig(4) & Xsig(5) & Xsig(6) & Xsig(7);
X <= Xsig;
Zsig <= '1' when resultSignal = x"0000" else
'0';
Z <= Zsig;
Coutsig <= resultSignal(8) when OPCODE = "0100" or OPCODE = "0110" or OPCODE = "1001" or OPCODE = "1110" else
resultSignal(15) when OPCODE = "1011" else
resultSignal(7) when OPCODE = "1100" or OPCODE = "1101" else
'1' when OPCODE = "1111" and Ysig /= x"00" else
'0';
Cout <= Coutsig;
Vsig <= '1' when OPCODE = "0101" and resultSignal(7) = '0' and A(7) = '1' and B(7) = '1' else
'1' when OPCODE = "0101" and resultSignal(7) = '1' and A(7) = '0' and B(7) = '0' else
'1' when OPCODE = "1110" and resultSignal(15) /= A(7) else
'0';
V <= Vsig;
F_active <= Zsig OR Coutsig OR Vsig;
X_bin_pal <= '1' when Xsig = Xsig_reverse else
'0';
X_prime <= '1' when Xsig = x"02" or Xsig = x"03" or Xsig = x"05" or Xsig = x"07" or Xsig = x"0B" or Xsig = x"0D" or Xsig = x"11" or Xsig = x"13" else
'1' when Xsig = x"17" or Xsig = x"1D" or Xsig = x"1F" or Xsig = x"25" or Xsig = x"29" or Xsig = x"2B" or Xsig = x"2F" or Xsig = x"35" else
'1' when Xsig = x"3B" or Xsig = x"3D" or Xsig = x"43" or Xsig = x"47" or Xsig = x"49" or Xsig = x"4F" or Xsig = x"53" or Xsig = x"59" else
'1' when Xsig = x"61" or Xsig = x"65" or Xsig = x"67" or Xsig = x"6B" or Xsig = x"6D" or Xsig = x"71" or Xsig = x"7F" or (Xsig = x"83" and Nsig = '0') else
'1' when (Xsig = x"89" or Xsig = x"8B" or Xsig = x"95" or Xsig = x"97" or Xsig = x"9D" or Xsig = x"A3" or Xsig = x"A7" or Xsig = x"AD") and Nsig = '0' else
'1' when (Xsig = x"B3" or Xsig = x"B5" or Xsig = x"BF" or Xsig = x"C1" or Xsig = x"C5" or Xsig = x"C7" or Xsig = x"D3" or Xsig = x"DF") and Nsig = '0' else
'1' when (Xsig = x"E3" or Xsig = x"E5" or Xsig = x"E9" or Xsig = x"EF" or Xsig = x"F1" or Xsig = x"FB") and Nsig = '0' else
'0';
Nsig <= '1' when OPCODE = "0101" and Xsig(7) = '1' else
'1' when OPCODE = "0111" and Ysig(7) = '1' else
'1' when OPCODE = "1101" and Xsig(7) = '1' else
'1' when OPCODE = "1110" and Xsig(7) = '1' else
'0';
N <= Nsig;
end Behavioral;