1

I'm new to VHDL and I have a problem I don't know how to resolve. The problem appears when I'm doing the simulation, but the code compiles correctly. Here is the problem :

entity fir is
port (  clock : in STD_LOGIC;
        reset : in STD_LOGIC;
        X : in STD_LOGIC_VECTOR (7 downto 0); -- X = X(n)
        Y : out STD_LOGIC_VECTOR (16 downto 0)); -- Y = Y(n)
end fir;

architecture Behavioral of fir is

    signal X_s, XZ1, XZ2, XZ3, XZ4, XZ5, XZ6, XZ7 : signed (7 downto 0); -- XZi = X(n-i)
    signal Y_s  : signed (16 downto 0);
    constant A  : signed(7 downto 0) := "00001011"; -- A=11
    (constant B,C,D,E,F,G,H similary to A)

begin
    process (clock, reset) 
    begin

    X_s <= signed(X);

        if (rising_edge(clock)) then
            if (reset = '1') then
                X_s <= (others => '0');
                Y_s <= (others => '0');
                XZ1, XZ2,XZ3...XZ7 <= (others => '0'); <= (others => '0');

            else
                XZ1 <= X_s;
                XZ2 <= XZ1;
                XZ3 <= XZ2;
                XZ4 <= XZ3;
                XZ5 <= XZ4;
                XZ6 <= XZ5;
                XZ7 <= XZ6;
            end if;
        end if;
    end process;

    Y_s <= (X_s*A) + (XZ1*B) + (XZ2*C) + (XZ3*D) + (XZ4*E) + (XZ5*F) + (XZ6*G) + (XZ7*H);
    Y <= std_logic_vector(Y_s);
end Behavioral;

This line :

Y_s <= (X_s*A) + (XZ1*B) + (XZ2*C) + (XZ3*D) + (XZ4*E) + (XZ5*F) + (XZ6*G) + (XZ7*H);

returns this error : "array shape mismatch - no matching element"

I firstly think it was because of its size, but the problem is still there even if I replace this line :

Y_s <= (X_s*A) + (XZ1*B) + (XZ2*C) + (XZ3*D) + (XZ4*E) + (XZ5*F) + (XZ6*G) + (XZ7*H);

by this one :

Y_s <= (X_s*A);

However, it works with this line : (just to see if the rest of the code is correct) :

Y_s <= (others => '0');

What could I do ?

Thanks a lot.

B. Clement
  • 298
  • 2
  • 13
  • Y_s - 17 wires (16 downto 0). X_s - 8 wires (7 downto 0). A - 8 wires (7 downto 0). 8 + 8 != 17. – fukanchik Nov 30 '18 at 21:00
  • So should I write : signal Y_s : signed (15 downto 0); ? The problem is that : X_s*A : 8 wires ; XZ1*B : 8 wires So X_s*A + XZ1*B : 8+8+1 wires right ? – B. Clement Nov 30 '18 at 21:04
  • It depends on your needs. You can either resize `Y_s` or add extra wire to product `"0" & (X_s*A)` or `"1" & (X_s & A)` – fukanchik Nov 30 '18 at 21:06
  • Ok but how can I know the size of this operation : (X_s*A) + (XZ1*B) + (XZ2*C) + (XZ3*D) + (XZ4*E) + (XZ5*F) + (XZ6*G) + (XZ7*H) I thought it was 17 wires, isn't it ? – B. Clement Nov 30 '18 at 21:15
  • size of `Y <= A + B` is `Maximum (A'Length, B'Length)` not A'Length+B'Length+1 therefore your whole sum has size 16. – fukanchik Nov 30 '18 at 21:36
  • See https://www.allaboutcircuits.com/technical-articles/review-of-vhdl-signed-unsigned-data-types/ section "“Signed”/“Unsigned” Addition without Overflow" – fukanchik Nov 30 '18 at 21:39
  • Ok, thank you very much ! – B. Clement Nov 30 '18 at 21:53
  • Signal `X` is not in the sensitivity list. You cannot reset signal `X_s`, because it violates the synchronous description rules. – Paebbels Dec 01 '18 at 20:20

2 Answers2

2

Your simple case:

Y_s <= (X_s*A);

Y_s - 17 wires (16 downto 0). X_s - 8 wires (7 downto 0). A - 8 wires (7 downto 0). 8 + 8 != 17.

Complex sum:

Y_s <= (X_s*A) + (XZ1*B) + (XZ2*C) + (XZ3*D) + (XZ4*E) + (XZ5*F) + (XZ6*G) + (XZ7*H);

Result sizes for addition and multiplication:

|  Operation |         Size of result       |
+------------+------------------------------+
| Y <= A + B | Maximum (A'Length, B'Length) |
| V <= A * B | A'Length + B'Length          |

Therefore your whole sum has size 16: Maximum(8+8,8+8,8+8,8+8,8+8,8+8,8+8,8+8).

Section "“Signed”/“Unsigned” Addition without Overflow" on this page explains how to solve this.

fukanchik
  • 2,811
  • 24
  • 29
1

Properly sizing Y_s should solve your problem. You also should move the assignment X_s <= signed(x) outside the process statement and remove X_s<= (others => '0') assignment inside the reset condition.

amiller856
  • 36
  • 4