Hallo Zusammen,
ich will mit VHDL eine Momentanwertleistung anhand von drei ADC Werten 
berechnen. Diese soll folgendermaßen (am besten in einem Takt [40MHz]) 
berechnet werden:
P = ((I1 + I2)/2) * U
Zuerst soll ein Mittelwert von zwei gemessenen Strömen gebildet werden 
((I1 + I2)/2) und danach mit der Spannung multipliziert werden. Hierbei 
handelt es ich um 12bit-Werte von drei Flash-ADCs (I1, I2, U) im 
ZWEIERKOMPLEMENT Format (SIGNED). Die Teilung durch 2 kann mit dem SHIFT 
Operator (SRL) erledigt werden.
1  | library IEEE;
  | 
2  | use IEEE.STD_LOGIC_1164.ALL;
  | 
3  | use IEEE.NUMERIC_STD.ALL;
  | 
4  | 
  | 
5  | entity leistungsberechnung is
  | 
6  |     Port ( 
  | 
7  |         clk_adc     : in  STD_LOGIC;
  | 
8  |         strom_I1    : in  STD_LOGIC_VECTOR (11 downto 0);
  | 
9  |         strom_I2    : in  STD_LOGIC_VECTOR (11 downto 0);
  | 
10  |         spannung_U  : in  STD_LOGIC_VECTOR (11 downto 0);
  | 
11  |         leistung    : out  STD_LOGIC_VECTOR (23 downto 0)
  | 
12  |       );
  | 
13  | end leistungsberechnung;
  | 
14  | 
  | 
15  | architecture Behavioral of leistungsberechnung is
  | 
16  | 
  | 
17  | signal s_strom_I1      : SIGNED (11 downto 0) := (others=>'0');
  | 
18  | signal s_strom_I2      : SIGNED (11 downto 0) := (others=>'0');
  | 
19  | signal s_strom_summe   : SIGNED (12 downto 0) := (others=>'0');
  | 
20  | signal s_spannung_U    : SIGNED (11 downto 0) := (others=>'0');
  | 
21  | signal s_leistung      : SIGNED (23 downto 0) := (others=>'0');
  | 
22  | 
  | 
23  | begin
  | 
24  | 
  | 
25  | s_spannung_U <= SIGNED(spannung_U);
  | 
26  | s_strom_I1 <= SIGNED(strom_I1);
  | 
27  | s_strom_I2 <= SIGNED(strom_I2);
  | 
28  | 
  | 
29  | process (clk_adc)
  | 
30  |   begin
  | 
31  |     if rising_edge(clk_adc) then
  | 
32  |       -- s_strom_summe <= s_strom_I1 + s_strom_I2;
  | 
33  |       s_leistung <= ((s_strom_I1 + s_strom_I2) srl 1) * s_spannung_U;
  | 
34  |   end if;
  | 
35  | end process;
  | 
36  | 
  | 
37  | leistung <= STD_LOGIC_VECTOR(s_leistung);
  | 
38  | 
  | 
39  | end Behavioral;
  | 
Folgendes Problem: Bei der Addition von zwei SIGNED 12Bit Zahlen kann 
ein Überlauf statt finden. Eine Addition von zwei SIGNED 12Bit Zahlen 
ergibt eine 13Bit Zahl.
Wenn ich folgendes berechnen will: SUMME(13Bit) = I1(12Bit) + I2(12Bit) 
bekomme ich einen Fehler bei dem ich nicht weiß wie ich diesen am 
geschicktesten beseitigen kann.
Durch die Division durch 2 ergibt sich wieder eine 12Bit Zahl. Hier 
passiert allerdings auch ein Fehler, da bei negativen Zahlen eine 0 
anstatt einer 1 auf der linken Seite reingeschoben wird.
Bei der Multiplikation funktioniert die automatische Verdopplung der 
Zahl auf 24Bit!
Natürlich sollte dieser CODE später auch synthetisierbar sein und auf 
einem SPARTAN 6 FPGA laufen. Wo ist der Denkfehler? Kann mir hier jemand 
weiterhelfen? Gruß Peter