0

I have been working on a vhdl program that accepts 2 inputs, a 3-bit input and a 4-bit input. The 3-bit input represents "2 to the power of n", ie an input of 010(which is 2) would equal 2^2=4. An input of 110(which is 6) would yield 2^6 which is 64. This is to be multiplied by a 4-bit input from 0000 to 1111, and the answer stored as 8-bits. However, when I try to solve for this in VHDL, I keep getting the error "Expression error at midterm_q_one.vhd(34): expression has 12 elements, but must have 8 elements". I am new to VHDL, and searching online has yielded little result. I want a way for my output, in this case hex, to store the product of my 2 inputs as an 8 bit value but don't know how. Any help would be greatly appreciated and below is my code. Thanks!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity midterm_q_one is
port(en: in std_logic;
     reset: in std_logic;
      three_bit: in std_logic_vector(2 downto 0);
      four_bit: in std_logic_vector(3 downto 0);
      hex: out std_logic_vector(7 downto 0)
);
end midterm_q_one;

architecture arch of midterm_q_one is
signal temp : std_logic_vector(7 downto 0);
begin
    process(en, reset, three_bit, four_bit)
    begin
if(reset = '1') then
    temp <= "00000000";--reset to decimal 0
elsif(en = '1') then
        case three_bit is
            when "000" => temp <= "00000001";--1
            when "001" => temp <= "00000010";--2
            when "010" => temp <= "00000100";--4
            when "011" => temp <= "00001000";--8
            when "100" => temp <= "00010000";--16
            when "101" => temp <= "00100000";--32
            when "110" => temp <= "01000000";--64
            when "111" => temp <= "10000000";--128
       end case;
end if;
hex <= temp * four_bit;
    end process;
    end arch;
Alex
  • 3
  • 1
  • 2
  • You could assign the result to another temp signal of 12 bits (as Morten described is the correct bit count) and then slice the signal to 8 bits for the output. Or you could use the resize function. – Paebbels Nov 30 '15 at 07:48
  • Suggestion: Get ridge of the non-standard (Synopsys) `STD_LOGIC_ARITH` and `STD_LOGIC_UNSIGNED`, and start using the standard `numeric_std` package. – Morten Zilmer Nov 30 '15 at 07:50
  • 1
    Are you aware that you are describing a shifter? Multiplication is sometimes not the fastest shifter... – Paebbels Nov 30 '15 at 07:50
  • Actually a multiply by a power of 2 should give you the same answer as shifting, depending on the quality of your synthesis software. The shifting is probably faster to execute in simulation. –  Nov 30 '15 at 09:05

2 Answers2

1

Multiplication of the 8-bit temp with the 8-bit four_bit gives a 12-bit result, which is assigned to the 8-bit hex, thus the error message "expression has 12 elements, but must have 8 elements".

Suggestion: Get ridge of the non-standard (Synopsys) STD_LOGIC_ARITH and STD_LOGIC_UNSIGNED, and start using the standard numeric_std package.

With the numeric_std you can resize the result using:

library ieee;
use ieee.numeric_std.all;
...
hex <= std_logic_vector(resize(unsigned(temp) * unsigned(four_bit), hex'length));
Morten Zilmer
  • 15,586
  • 3
  • 30
  • 49
1

I could see two ways to get rid of the error.

The simplest is:

architecture simple of midterm_q_one is
begin
    process (en, reset, four_bit, three_bit)
    begin
        if reset = '1' then
            hex <= (others => '0');
        elsif en = '1' then 
            hex <= SHL("0000" & four_bit, three_bit);
        end if;
    end process;
end architecture;

This still requires some knowledge of what 8 bit's you want, or whether you want the value to clamp to x"FF" or whether you want the 8 bit best product:

architecture best_product of midterm_q_one is
begin
    process (en, reset, four_bit, three_bit)
        variable intermed: std_logic_vector (11 downto 0);
    begin
        if reset = '1' then
            intermed := (others => '0');
        elsif en = '1' then 
            intermed := SHL("0000" & four_bit, three_bit);
        end if;
        hex <= intermed(11 downto 4);
    end process;
end architecture;

Clamping:

architecture saturate_clamp of midterm_q_one is
begin
    process (en, reset, four_bit, three_bit)
        variable intermed: std_logic_vector (11 downto 0);
    begin
        if reset = '1' then
            intermed := (others => '0');
        elsif en = '1' then 
            intermed := SHL("0000" & four_bit, three_bit);
        end if;
        if intermed(11) = '1' or intermed(10) = '1' or 
           intermed(9)  = '1' or intermed(8)  = '1' then
            hex <= x"FF";
        else 
            hex <= intermed(7 downto 0);
        end if;
    end process;
end architecture;

What are the 8 bits supposed to represent mathematically?