Multiplication in VHDL by a fraction

I am trying to multiply a 8-bit number with 5/7 in VHDL language. I wrote 5/7 as a 20-bit binary and stored the multiplication in a 10-bit variable by only taking first 10-bit numbers of the result. The problem is my simulation keeps on freezing and I cannot see the simulation waveforms. Why does Vivado keep crashing during this code? Can anyone shed a light on this matter?

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_arith.all;

entity lab47 is
Port ( x : in STD_LOGIC_VECTOR (7 downto 0);
y : out STD_LOGIC_VECTOR (9 downto 0));
end lab47;

architecture rtl of lab47 is

constant cnst1 : std_logic_vector(19 downto 0) := "10110110110110110111"; -- 20-bit
--representation of 5/7

signal cnst2 : std_logic_vector(27 downto 0);

begin
process(x)
begin

cnst2 <= unsigned(x) * unsigned(cnst1);

if (x >= X"0" or x <= X"1") then y <= "000000000" & cnst2(18);
elsif(x > X"1" or x <= X"3") then y <= "00000000" & cnst2(19 downto 18);
elsif(x > X"3" or x <= X"7") then y <= "0000000" & cnst2(20 downto 18);
elsif(x > X"7" or x <= X"F") then y <= "000000" & cnst2(21 downto 18);
elsif(x > X"F" or x <= X"1F") then y <= "00000" & cnst2(22 downto 18);
elsif(x > X"1F" or x <= X"3F") then y <= "0000" & cnst2(23 downto 18);
elsif(x > X"3F" or x <= X"7F") then y <= "000" & cnst2(24 downto 18);
elsif(x > X"7F" or x <= X"FF") then y <= "00" & cnst2(25 downto 18);
elsif(x > X"FF" or x <= X"1FF") then y <= "0" & cnst2(26 downto 18);
elsif(x > X"1FF" or x <= X"3FF") then y <= cnst2(27 downto 18);

end if;

end process;

end rtl;


And here's my testbench.

library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity test_bench is
-- Port();
end test_bench;

architecture simulate of test_bench is

signal  x : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
signal  y : STD_LOGIC_VECTOR (9 downto 0) := (others => '0');

component lab47 is
Port ( x : in STD_LOGIC_VECTOR (7 downto 0);
y : out STD_LOGIC_VECTOR (9 downto 0));
end component lab47;

begin

dut : lab47 port map (x => x,
y => y);

input_gen : process
begin

x <= "00000000",
"00000001" after 10 ns,
"00000010" after 10 ns,
"00000011" after 10 ns,
"00000100" after 10 ns,
"00000101" after 10 ns,
"00000110" after 10 ns,
"00000111" after 10 ns,

"00001000" after 10 ns,
"00001001" after 10 ns,
"00001010" after 10 ns,
"00001011" after 10 ns;
wait;
end process;

end simulate;

• You have a lot of 'stuff' there. It's better to ask a question with a 'Minimum Reproducible Example'. Remove all the cruft, does it work? If no, debug. If yes, put some back in until it fails. Post both the working, and the first non-working one. Commented Apr 23, 2023 at 12:44
• (The longer I look, the more quirks I see - seeing lab47, I should leave it at answering what might freeze simulation.) Commented Apr 23, 2023 at 14:33
• @Neil_UK you are right, getting the simulation to run was the first part, I'm new to VHDL, the thing that confuses me about VHDL is, if we have 5-bit signal in binary, how would we represent it it hexadecimal? For ex. Is b"00001" equal to X"01"? Hexadecimal notation has 8-bits, how can we write the hexadecimal properly?
– Zzz
Commented Apr 23, 2023 at 15:16
• In -2008 bit string literals can have their bit length specified, e.g. 5X"01" would yield string "00001" with a length of five. Without the length specifier it would have a length of eight. IEEE Std1076-2008 15.8 Bit string literals "The length of a bit string literal is the length of its string literal value. If a bit string literal includes the integer immediately preceding the base specifier, the length of the bit string literal is the value of the integer. Otherwise, the length is the number of characters in the expanded bit value." Commented Apr 23, 2023 at 21:33

In the testbench, there are numerous values listed for same simulated time.
From the language reference:

The delay values supported with the after clause do not cumulate, but all relate to the same simulation time

    x <= "00000000",
"00000001" after 10 ns,
"00000010" after 20 ns,
"00000011" after 30 ns,

• oh, @greybeard, the simulation time of 10ns for every instant was causing problems, now I can see the simulation graphs, now, time to debug the multiplier code, thank you!
– Zzz
Commented Apr 23, 2023 at 13:56

After some tweaking, I solved this problem some time ago. Here's the code

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity lab47 is
Port( x : IN std_logic_vector (7 downto 0);
y : OUT std_logic_vector (9 downto 0));
end lab47;

architecture rtl of lab47 is

constant number : std_logic_vector (19 downto 0) :=
"10110110110110110111";

signal temp : std_logic_vector (27 downto 0);

signal result : std_logic_vector(27 downto 0);

begin

mult : process(x, temp, result)
begin

temp <= unsigned(x) * unsigned(number);

result <=  to_stdlogicvector(to_bitvector(temp) srl 2);

y <= result(27 downto 18);

end process mult;

end rtl;


And here's the testbench.

library IEEE;
use IEEE.std_logic_1164.all;

entity lab47_tb is
--Port();
end lab47_tb;

architecture sim of lab47_tb is

signal x : std_logic_vector (7 downto 0) := (others => '0');
signal y : std_logic_vector (9 downto 0) := (others => '0');

--constant period : time := 1 ns;

component lab47 is
Port( x : IN std_logic_vector (7 downto 0);
y : OUT std_logic_vector (9 downto 0));
end component lab47;

begin

input_gen : process
begin
x <= "00000000",
"00000001" after 10 ns,
"00000010" after 20 ns,
"00000011" after 30 ns,
"00000100" after 40 ns,
"00000101" after 50 ns,
"00000110" after 60 ns,
"00000111" after 70 ns,
"00001000" after 80 ns,
"00001001" after 90 ns,
"00001010" after 100 ns,
"00001011" after 110 ns,
"00001100" after 120 ns,
"00001101" after 130 ns,
"00001110" after 140 ns,
"00001111" after 150 ns,
"11111110" after 160 ns,
"11111111" after 170 ns;
wait;

end process input_gen;

dut : lab47 port map (x => x,
y => y);
end sim;


@greybeard, regarding simulation, when my input stimulus is "11111111" at 160 & 170 ns, Modelsim sees it as a signed number, how to make it show as unsigned number? Also on the internet, people dont recomment using slr, sll, etc. because they say that it causes too many bugs. Slicing and concatenation dont work all the time, do we have a better method other than sll and srl?

• Trying to produce a minimal reproducible example is the way to go. Posting a follow-on question as an answer isn't: Post as another question, cross-references welcome. Commented Apr 24, 2023 at 11:06
• (y never turning "1111111111" should tell you x >= "00000000" or x < X"2" is true. (To spoil a learning experience and see more, edit my above answer.) Commented Apr 24, 2023 at 11:09