1

I have written a program in modelsim that add to numbers and put the result in Ra/Sum. I have used a tristate buffer, but I get this: Fatal: (vsim-3420) Array lengths do not match. Left is 16 (15 downto 0). Right is 8 (7 downto 0). I understand that this is because they have different lengths. But they cant have the same length either, because then I get an error when adding add1 and add2 and putting them in Sum. So what can I do to make this work?

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;

entity MAC is
generic (width: integer := 8);
port(
    clk, reset      :    in STD_LOGIC; 
    MLS_select      :    in STD_LOGIC;
    Rn, Rm, Ra :    in STD_LOGIC_VECTOR(width-1 downto 0);
    Rd         :    out STD_LOGIC_VECTOR(width-1 downto 0)
);
end;

architecture behavioral of MAC is
signal mul1, mul2, add1 : UNSIGNED(width-1 downto 0);
signal add2, sum        : UNSIGNED(width*2-1 downto 0);
begin
    process(clk, reset)

    begin
        if reset = '1' then Rd <= (others => '0');

        elsif rising_edge(clk) then
            Rd <= STD_LOGIC_VECTOR(sum(width-1 downto 0)); 
      end if;

    end process;

     mul1 <= UNSIGNED(Rn);
     mul2 <= UNSIGNED(Rm);
     add1 <= UNSIGNED(Ra);
     add2 <= mul1*mul2;
     sum <= add2 when clk = '1' else add2; 
     sum <= add1+add2;
  end architecture;
Paebbels
  • 15,573
  • 13
  • 70
  • 139
H.Pett
  • 43
  • 5
  • Your problem can't be duplicated with the code shown. There is no tristate buffering present, there are no matching element requirement errors during signal updates - your code simulates. The length of the multiply result is the length of add2, the length of the addition between add1 and add2 is the length of the longer operand (add2). There are however [two drivers for sum](https://i.stack.imgur.com/ZNlvk.jpg) (the concurrent signal assignments). Rd is only the least product of the multiply and accumulate, as is the Ra path. –  Oct 22 '18 at 01:57

1 Answers1

0

At first, ... when clk = '1' else ... will create a latch, but no flip-flop.
You need to use ... when rising_edge(clk);.

library IEEE;
use     IEEE.std_logic_1164.all;
use     IEEE.numeric_std.all;

entity MAC is
  generic (width: integer := 8);
  port(
    clk, reset  : in  STD_LOGIC; 
    MLS_select  : in  std_logic;
    Rn, Rm, Ra  : in  std_logic_vector(width - 1 downto 0);
    Rd          : out std_logic_vector(width - 1 downto 0) := (others => '0')
  );
end entity;

architecture rtl of MAC is
  signal mul1, mul2, add1 : unsigned(width - 1 downto 0);
  signal add2, sum        : unsigned(width * 2 - 1 downto 0);

begin
  process(clk, reset)
  begin
    if (reset = '1') then
      Rd <= (others => '0');
    elsif rising_edge(clk) then
      Rd <= std_logic_vector(sum(Rd'range)); 
    end if;
  end process;

  mul1 <= unsigned(Rn);
  mul2 <= unsigned(Rm);
  add1 <= unsigned(Ra);
  add2 <= (mul1 * mul2) when rising_edge(clk);

  sum <= resize(add1, add'length) + add2;
end architecture;

Signal MLS_select is unused. There is no need to calculate the sum with so many bits. I suggest to truncate add2 before the addition, to reduce the number of unused bits (and warnings generated by them).

Paebbels
  • 15,573
  • 13
  • 70
  • 139