# Electronic – Unexpected results when multiplying in VHDL

vhdl

I'm trying to make a simple BCD –> binary conversion operation work in an ALU I'm coding. All the other operations work perfectly fine, just this last operation doesn't work for some reason.

I've tried numerous approaches and nothing seems to make sense.

My inputs are `A` and `B` which are both 8-bit vectors. The outputs are `X` and `Y`.

So the formula goes `Y:X = BCD2BIN(B:A)`.

In my case, in my testbench I have `B = 0x40` and `A = 0x46`, so the output I'm expecting is `0xFCE`, which is 4046.

Just for those who are unaware, the simplest way to perform this is to divide each byte into 2 nibbles, and multiply by a constant and sum the terms.

So:

`B:A = 0x4046 = (4 * 1000) + (0 * 100) + (4 * 10) * (6 * 1)`

Signals I'm Using

``````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);
``````

After the BEGIN

``````dig1 <= B(7 downto 4);
dig2 <= B(3 downto 0);
dig3 <= A(7 downto 4);
dig4 <= A(3 downto 0);
``````

Actual Operation

``````opF <= STD_LOGIC_VECTOR((unsigned(dig1) * unsigned(sig1000)) + (unsigned(dig2) * unsigned(sig100)) + (unsigned(dig3) * unsigned(sig10)) + (unsigned(dig4)));
``````

And later the opF gets split into Y and X.

So even verifying the signals in simulation, they are correct, yet the output is not.

The `sig10001`, `sig100` and `sig10` are the correct values, and `dig1 = 4`, `dig2 = 0`, `dig3 = 4` and `dig4 = 6` with unsigned decimal radix.

Yet the result is 252

I've even tried this using constants, instead of vectors, with even less success.

For example

``````opF <= STD_LOGIC_VECTOR((unsigned(dig1) * 10#1000#) + (unsigned(dig2) * 10#100#) + (unsigned(dig3) * 10#10#) + (unsigned(dig4)));
``````

Full file, as some have requested.

``````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;
``````