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