Hallo - ich habe hier einen C-Code eines LowPass Filters, und wüßte gerne wie man so einen Code in VHDL umsetzt.. Clock Frequency = 32kHz Wäre um jeden Hinweis dankbar. Grüße unsigned long LPF2(unsigned char voltf, char smpl) //====================================================================== === { static unsigned long ACC0=0, ACC1=0, ACC2=0, OUT=0; ACC0+=voltf; if (smpl) { ACC1+=(ACC0*16-OUT); ACC2+=(ACC1/32); OUT = ACC2/16; ACC2-=OUT; OUT = ACC2/16; ACC0=0; } return(OUT); }
Sieht irgendwie nach einem HP zweiter Ordnung aus. Im Prinzip kannst du das in VHDL genau so hinschreiben, da keine divider benötigt werden.
Hallo Wolfgang - hier habe ich mal angefangen, weiss aber nicht wie ich die C-Funktion umsetzen soll. Jeglicher input willkommen. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity lp2 is port( clk : in std_logic; smpl : in std_logic; voltf : in integer; output : out integer :=0) end lp2; architecture t1 of lp2 is begin process(clk) is variable ACC0 : integer_vector(0 to 5) := (others => 0); variable ACC1 : integer_vector(0 to 5) := (others => 0); variable ACC2 : integer_vector(0 to 5) := (others => 0); begin -- process if rising_edge(clk) then -- rising clock edge if smpl = '1' then ?? ?? ?? else output <= output; end if; end if; end process; end t1;
Thomas Stoll schrieb: > use IEEE.STD_LOGIC_ARITH.ALL; > use IEEE.STD_LOGIC_UNSIGNED.ALL; NEIN, nicht für neue Designs. Besser:
1 | use ieee.numeric_std.all; |
Für nähere Informationen bitte die Forumssuche benutzen.
1 | signal ACC0 : integer := 0; |
2 | signal ACC2 : integer := 0; |
3 | signal temp : integer := 0; |
4 | |
5 | process(clk) is |
6 | begin -- process |
7 | if rising_edge(clk) then -- rising clock edge |
8 | |
9 | ACC0 = ACC0 + voltf; |
10 | |
11 | if smpl = '1' then |
12 | ACC1 <= ACC1 + (ACC0 * 16 - temp); |
13 | ACC2 <= ACC2 + (ACC1 / 32); |
14 | ACC2 <= ACC2 - (ACC2 / 16); |
15 | temp <= ACC2 / 16; |
16 | ACC0 <= 0; |
17 | end if; |
18 | |
19 | OUT <= temp; |
20 | |
21 | end if; |
22 | end process; |
Ob das tut mußt Du mal schauen (simulieren), Dein Quellcode läßt sich so, wie er ist nicht direkt in Hardware umsetzen. BTW: Welchen Simulator verwendest Du? Duke
Danke, werde ich mal ausprobieren. Ich verwende ISE. Grüße, Tom
Duke Scarring schrieb: > BTW: Welchen Simulator verwendest Du? Thomas Stoll schrieb: > Ich verwende ISE. Pech, der ISIM kann noch keine Analogdarstellung... :-( Duke Scarring schrieb: > signal ACC0 : integer := 0; > signal ACC2 : integer := 0; > signal temp : integer := 0; > > process(clk) is > begin -- process > if rising_edge(clk) then -- rising clock edge > ACC0 = ACC0 + voltf; > if smpl = '1' then > ACC1 <= ACC1 + (ACC0 * 16 - temp); > ACC2 <= ACC2 + (ACC1 / 32); > ACC2 <= ACC2 - (ACC2 / 16); --- ACC2 ist ein Signal > --> der vorige Wert wird einfach überschrieben... > : > : > Ob das tut mußt Du mal schauen... Kann leider nicht tun, weil ACCx Signale sind und daher ACC2 einfach überschreiben wird. In diesem speziellen Fall hier würde ich die "globalen" Akkumulatorsignale im Prozess auf temporäre Variablen abbilden, mit denen rechnen und das Ergebnis am Ende des Prozesses wieder an die Signale zuweisen...
Hallo Lothar - Schade das mit ISE.. könnte allerdings auch auf modelsim umsteigen.. Und - könntest Du mir das <<In diesem speziellen Fall hier würde ich die "globalen" Akkumulatorsignale im Prozess auf temporäre Variablen abbilden, mit denen rechnen und das Ergebnis am Ende des Prozesses wieder an die Signale zuweisen...>> mal als Beispiel anschreiben? Grüße, Tom
Thomas Stoll schrieb: > Und - könntest Du mir das mal als Beispiel anschreiben? Naja, sooooo kompliziert ist das nicht:
1 | signal ACC0 : integer := 0; |
2 | signal ACC1 : integer := 0; |
3 | signal ACC2 : integer := 0; |
4 | signal RESULT : integer := 0; -- ein Signal darf nicht OUT heißen, das ist ein Keyword |
5 | |
6 | process(clk) is |
7 | variable A0 : integer; -- alles nur temporäre Variable |
8 | variable A1 : integer; --> hier wird kein Flipflop instatiiert |
9 | variable A2 : integer; |
10 | variable RES : integer; |
11 | begin -- process |
12 | if rising_edge(clk) then -- rising clock edge |
13 | A0 := ACC0; -- "globale" Signale auf Variable abbilden |
14 | A1 := ACC1; |
15 | A2 := ACC2; |
16 | RES := RESULT; |
17 | |
18 | if (clock_enable_32khz='1') then -- der FPGA-Takt wird ja wohl höher sein als 32kHz, deshalb wird mit Clock-Enable gearbeitet |
19 | A0 = A0 + voltf; |
20 | |
21 | if (smpl='1') then |
22 | A1 := A1 + (A0*16 - RES); |
23 | |
24 | A2 := A2 + (A1/32); |
25 | RES := A2/16; |
26 | |
27 | A2 := ACC2 - (RES/16); |
28 | RES := A2/16; |
29 | A0 := 0; |
30 | end if; |
31 | |
32 | end if; |
33 | |
34 | RESULT <= RES; -- Signale updaten |
35 | ACC0 <= A0; |
36 | ACC1 <= A1; |
37 | ACC2 <= A2; |
38 | end if; |
39 | end process; |
Herzlichen Dank! Es wird mit 32kHz gearbeitet.. somit gehe ich davon aus, dass ich das clk_enable_32kHz weg lassen kann? Grüße, Tom
Thomas Stoll schrieb: > Es wird mit 32kHz gearbeitet.. somit gehe ich davon aus, dass ich das > clk_enable_32kHz weg lassen kann? In dem Fall schon, ja. Aber ... :-/ ... die Frequenz scheint mir doch extrem niedrig. Worauf wird das Filter implementiert (CPLD/FPGA)? Läuft das ganze Design drumrum auch mit 32kHz? Wieviele Takte hast du in dem Design?
Design soll auf FPGA ausprobiert werden. Anschliessend in CMOS 0.35u Technologie synthetisiert werden. Kann man die inputs (integer) irgendwie auf 6 bit begrenzen? So vielleicht? integer_vector(5 downto 6) Tom
also, habe gerade nochmals nachgelesen der systemtakt ist 32KHz der sample takt ist 1kHz für das LPF. damit bekomme ich zusammen mit den koeffizienten einen butterworth LPF mit 7Hz Grenzfrequenz
Thomas Stoll schrieb: > Kann man die inputs (integer) irgendwie auf 6 bit begrenzen? signal vorzeichenlos : integer range 0 to 63; oder signal vorzeichenbehaftet : integer range -32 to 31;
Den 2 stufigen Filter müsse man auch verkettet schreiben können: Kombinatorisch: (Neubelegung) Wert1Neu <= Wert1Alt*(1-k1) + Input*k1; Wert2Neu <= Wert2Alt*(1-k2) + Wert1Neu*k2; Getaktet: (Fortschreiben der Zeit) Wert1Alt <= Wert1Neu; Wert2Alt <= Wert2Neu; Output <= Wert2Neu; Wenn man sowas dreistufig baut, kann man aus einem Rechteck locker einen Sinus machen. Die k1 müssen dazu in der Höhe absteigen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.