Forum: FPGA, VHDL & Co. Bekomme Matlab-IIR-Lowpass nicht zum laufen. Timingprobleme?


von Gerald G. (gerald_g)


Angehängte Dateien:

Lesenswert?

Hallo, ich habe mit Matlab einen IIR Tiefpassfilter (Maximally Flat, 
input 32Bit, output 32Bit, coeff 18Bit) designed und versuche ihn in 
mein VHDL Design einzubauen.

Ich möchte Die Amplitude und Phase eines Sinussignales messen. Hierfür 
habe ich ein Altera DE4 Board mit Stratix IV und eine 150MSPS ADC-Karte

Um die Daten an den PC zu bekommen benutze ich Xillybus, hier habe ich 
auf dem FPGA nur ein FIFO und am PC kann ich einfach eine Datei lesen 
(Pipe). Xillybus kümmert sich um die ganze PCIe Kommunikation.

Ich gebe einen Sinus mit einem DAC aus und schleife ihn direkt auf den 
ADC. Den gemessenen Wert (obere Reihe im Bild) multipliziere ich mit 
ausgegebenen Sinus (mittlere Reihe im Bild). Das funktioniert alles 
wunderbar. Nur die Werte die ich nach dem Filter heraus bekomme sind 
völliger Quatsch. Da ich einfach mal davon ausgehe, dass Matlab einen 
funktionierenden Code erzeugen kann, bin ich auf der Suche nach dem 
Fehler im Design.
Gerne auch auf grobe Schnitzer hinweisen.
Das Signal ADA_DCO kommt vom ADC und bedeutet es liegen valide Daten 
vor. Dies wird als Clock genutzt.
Wenn wir schon dabei sind, kann mir vielleicht jemand sagen wieso 
Quartus keine dedizierten Multiplizierer nutzt? Muss man das explizit 
angeben oder macht Quartus das einfach richtig indem es abwägt was 
besser ist?

edit: habe noch die Daten angehängt, wie sie aussehen wenn ich sie am PC 
mit dem Filter filtere.
edit2: Wenn das unten zu viel Code ist, kann ich auch das unwichtige 
herausstreichen. Aber ich denke bei den Kommentaren sieht man schnell 
worum es sich handelt. Demodulation.vhd multipliziert bei rising_edge 
nur das ADC Signal mit dem sinus/cosinus und gibt das Signal dann aus.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
use ieee.numeric_std.all;
5
6
entity xillydemo is
7
  port (
8
    clk_50 : IN std_logic;
9
    pcie_perstn : IN std_logic;
10
    pcie_refclk : IN std_logic;
11
    pcie_rx : IN std_logic_vector(3 DOWNTO 0);
12
    pcie_tx : OUT std_logic_vector(3 DOWNTO 0);
13
    user_led : OUT std_logic_vector(3 DOWNTO 0);
14
   
15
   -----------------------------ADC Karte
16
  AD_SCLK : inout std_logic;  --DataFormat Select-- '1' is twos complement
17
  AD_SDIO : inout std_logic; --DutyCycle Stabilizer
18
  ADA_D : in std_logic_vector(13 downto 0) ;
19
  ADA_DCO : in std_logic; --Data Clock out
20
  ADA_OE : out std_logic; --Out enable
21
  ADA_OR : in std_logic; -- Out of Range
22
  ADA_SPI_CS : out std_logic; --high for external mode
23
  ADB_D : in std_logic_vector (13 downto 0);
24
  ADB_DCO : in std_logic;
25
  ADB_OE : out std_logic;
26
  ADB_OR : in std_logic;
27
  ADB_SPI_CS : out std_logic;
28
  AIC_BCLK : inout std_logic;
29
  AIC_DIN : out std_logic;
30
  AIC_DOUT : in std_logic;
31
  AIC_LRCIN : inout std_logic;
32
  AIC_LRCOUT : inout std_logic;
33
  AIC_SPI_CS : out std_logic;
34
  AIC_XCLK : out std_logic;
35
  CLKIN1 : in std_logic; --testpin
36
  CLKOUT0 : out std_logic; --testpin
37
  DA : out std_logic_vector (13 downto 0);
38
  DB : out std_logic_vector (13 downto 0);
39
  FPGA_CLK_A_N : inout std_logic;
40
  FPGA_CLK_A_P : inout std_logic;
41
  FPGA_CLK_B_N: inout std_logic;
42
  FPGA_CLK_B_P: inout std_logic;
43
  J1_152 : inout std_logic; --TP
44
  XT_IN_N : in std_logic;
45
  XT_IN_P : in std_logic
46
  );
47
end xillydemo;
48
  
49
architecture sample_arch of xillydemo is
50
  component xillybus
51
    port (
52
      clk_125 : IN std_logic;
53
      clk_50 : IN std_logic;
54
      pcie_perstn : IN std_logic;
55
      pcie_refclk : IN std_logic;
56
      pcie_rx : IN std_logic_vector(3 DOWNTO 0);
57
      reconfig_clk_locked : IN std_logic;
58
      bus_clk : OUT std_logic;
59
      pcie_tx : OUT std_logic_vector(3 DOWNTO 0);
60
      quiesce : OUT std_logic;
61
      user_led : OUT std_logic_vector(3 DOWNTO 0);
62
      user_r_read_32_rden : OUT std_logic;
63
      user_r_read_32_empty : IN std_logic;
64
      user_r_read_32_data : IN std_logic_vector(31 DOWNTO 0);
65
      user_r_read_32_eof : IN std_logic;
66
      user_r_read_32_open : OUT std_logic;
67
      user_w_write_32_wren : OUT std_logic;
68
      user_w_write_32_full : IN std_logic;
69
      user_w_write_32_data : OUT std_logic_vector(31 DOWNTO 0);
70
      user_w_write_32_open : OUT std_logic)
71
  end component;
72
  
73
74
component fifo
75
  PORT
76
  (
77
    aclr    : IN STD_LOGIC  := '0';
78
    data    : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
79
    rdclk    : IN STD_LOGIC ;
80
    rdreq    : IN STD_LOGIC ;
81
    wrclk    : IN STD_LOGIC ;
82
    wrreq    : IN STD_LOGIC ;
83
    q    : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
84
    rdempty    : OUT STD_LOGIC ;
85
    wrfull    : OUT STD_LOGIC 
86
  );
87
END component;
88
89
90
  component pll2
91
  PORT
92
  (
93
    inclk0    : IN STD_LOGIC  := '0';
94
    c0    : OUT STD_LOGIC ; --250MHZ
95
    c1    : OUT STD_LOGIC ; --250MHz invertiert
96
    c2    : OUT STD_LOGIC ; --150MHz
97
    c3    : OUT STD_LOGIC ; -- 150MHz invertiert
98
    c4    : OUT STD_LOGIC ; --125MHz
99
    locked : OUT STD_LOGIC
100
  );
101
  end component;
102
  
103
  component demodulate 
104
  port(
105
  clock : in std_logic;
106
  sine : in std_logic_vector (13 downto 0);
107
  cosine : in std_logic_vector (13 downto 0);
108
  adc : in std_logic_vector (13 downto 0);
109
  sinemult : out std_logic_vector (27 downto 0);
110
  cosinemult : out std_logic_vector (27 downto 0)
111
  );
112
  end component;
113
114
115
  component lowpass0_05
116
   PORT( clk                             :   IN    std_logic; 
117
         clk_enable                      :   IN    std_logic; 
118
         reset                           :   IN    std_logic; 
119
         filter_in                       :   IN    std_logic_vector(31 DOWNTO 0); -- sfix28_En27
120
         filter_out                      :   OUT   std_logic_vector(31 DOWNTO 0)  -- sfix32_En26
121
  --    ce_out                          :   OUT   std_logic  
122
         );
123
124
  END component;
125
  
126
  
127
128
  signal bus_clk :  std_logic;
129
  signal quiesce : std_logic;
130
  signal user_r_read_32_rden :  std_logic;
131
  signal user_r_read_32_empty :  std_logic;
132
  signal user_r_read_32_data :  std_logic_vector(31 DOWNTO 0);
133
  signal user_r_read_32_eof :  std_logic;
134
  signal user_r_read_32_open :  std_logic;
135
  signal user_w_write_32_wren :  std_logic;
136
  signal user_w_write_32_full :  std_logic;
137
  signal user_w_write_32_data :  std_logic_vector(31 DOWNTO 0);
138
  signal user_w_write_32_open :  std_logic;
139
  signal reconfig_clk_locked :  std_logic;
140
  signal clk_125 : std_logic;
141
  
142
  ------------------------ADC
143
  
144
  signal clock_250MHz : std_logic;
145
  signal clock_250MHz_inv : std_logic;
146
  signal clock_150MHz : std_logic;
147
  signal clock_150MHz_inv : std_logic;
148
  signal sinus : std_logic_vector (13 downto 0);
149
  signal cosinus : std_logic_vector (13 downto 0);
150
  signal DACA_out : std_logic_vector (13 downto 0);
151
  signal DACB_out : std_logic_vector (13 downto 0);
152
  signal incrementvalue_now : std_logic_vector (31 downto 0) :=std_logic_vector(to_unsigned(286331153,32)); --344036
153
  signal counter : integer range 0 to 50000 :=0;
154
  signal increment_value : integer range 0 to 50764 := 829; --Anfang bei 20kHz. Ende bei 75MHz
155
  signal sine_data_valid : std_logic;
156
  signal ADCA_in : std_logic_vector (13 downto 0);
157
  signal ADCB_in : std_logic_vector (13 downto 0);
158
  signal ADCA_value_valid : std_logic;
159
  signal ADCB_value_valid : std_logic;
160
161
  
162
  ------------------------------------FIFo_32
163
  
164
  signal capture_clk          : std_logic;
165
  signal capture_data         : std_logic_vector (31 downto 0);
166
  signal capture_en           : std_logic;
167
  signal capture_full         : std_logic;
168
  signal capture_has_been_full : std_logic;
169
  signal capture_has_been_nonfull : std_logic;
170
  signal capture_open         : std_logic;
171
  signal capture_open_cross   : std_logic;
172
  signal has_been_full        : std_logic;
173
  signal has_been_full_cross  : std_logic;
174
  signal reset_32 : std_logic;
175
  
176
  signal datacounter : integer range 0 to 150000000;
177
  signal enoughdata : std_logic :='0';
178
  
179
  
180
  signal multipliedsine : std_logic_vector (27 downto 0);
181
  signal multipliedcosine : std_logic_vector (27 downto 0);
182
  signal filteredsine1 : std_logic_vector (31 downto 0);
183
  signal filteredcosine1 : std_logic_vector (31 downto 0);
184
 
185
  ---------------------------Sinus
186
  
187
  component NCO
188
  port (
189
    clk       : in  std_logic                     := '0';             -- clk.clk
190
    clken     : in  std_logic                     := '0';             --  in.clken
191
    phi_inc_i : in  std_logic_vector(31 downto 0) := (others => '0'); --    .phi_inc_i
192
    fsin_o    : out std_logic_vector(13 downto 0);                    -- out.fsin_o
193
    fcos_o    : out std_logic_vector(13 downto 0);                    --    .fcos_o
194
    out_valid : out std_logic;                                        --    .out_valid
195
    reset_n   : in  std_logic                     := '0'              -- rst.reset_n
196
  );
197
end component;
198
199
200
201
202
begin
203
    
204
          xillybus_ins : xillybus
205
    port map (
206
      -- Ports related to /dev/xillybus_read_32
207
      -- FPGA to CPU signals:
208
      user_r_read_32_rden => user_r_read_32_rden,
209
      user_r_read_32_empty => user_r_read_32_empty,
210
      user_r_read_32_data => user_r_read_32_data,
211
      user_r_read_32_eof => user_r_read_32_eof,
212
      user_r_read_32_open => user_r_read_32_open,
213
214
      -- Ports related to /dev/xillybus_write_32
215
      -- CPU to FPGA signals:
216
      user_w_write_32_wren => user_w_write_32_wren,
217
      user_w_write_32_full => user_w_write_32_full,
218
      user_w_write_32_data => user_w_write_32_data,
219
      user_w_write_32_open => user_w_write_32_open,
220
221
      -- General signals
222
      clk_125 => clk_125,
223
      clk_50 => clk_50,
224
      pcie_perstn => pcie_perstn,
225
      pcie_refclk => pcie_refclk,
226
      pcie_rx => pcie_rx,
227
      reconfig_clk_locked => reconfig_clk_locked,
228
      bus_clk => bus_clk,
229
      pcie_tx => pcie_tx,
230
      quiesce => quiesce,
231
      user_led => user_led
232
  );
233
234
  ---------- Get clocks
235
  clocks: pll2 port map (clk_50, clock_250MHz, clock_250MHz_inv, clock_150MHz, clock_150MHz_inv, clk_125, reconfig_clk_locked);
236
  
237
  ----------- Make sine/cosine
238
  Data: NCO port map (Clock_150MHz_inv, '1', incrementvalue_now, sinus, cosinus, sine_data_valid, '1');
239
240
241
242
----------------clocks for DCC
243
FPGA_CLK_A_P <= clock_150MHz_inv;
244
FPGA_CLK_A_N <= clock_150MHz;
245
FPGA_CLK_B_N <= clock_150MHz_inv;
246
FPGA_CLK_B_P <= clock_150MHz;
247
248
249
---------------configure ADC
250
AD_SCLK <= '1'; --set twos complement data mode
251
AD_SDIO <= '1'; --enable dutyCycle stabilizer
252
ADA_OE <= '0'; --enable ADCA_in
253
ADB_OE <= '0'; --enable ADCB_in
254
ADA_SPI_CS <= '1'; --set to external mode
255
ADB_SPI_CS <= '1';
256
257
258
-----------------read Data in rising edge of AD_DCO
259
260
process (ADA_DCO)
261
begin
262
if rising_edge(ADA_DCO) then
263
  ADCA_in <= ADA_D;
264
end if;
265
end process;
266
267
-----------------read Data in rising edge of AD_DCO
268
269
process (ADB_DCO)
270
begin
271
if rising_edge(ADB_DCO) then
272
  ADCB_in <= ADB_D;
273
end if;
274
end process;
275
276
277
--  Clock crossing logic: bus_clk -> capture_clk
278
-- delay by one clock
279
280
  process (capture_clk)
281
  begin
282
    if (capture_clk'event and capture_clk = '1') then
283
      capture_open_cross <= user_r_read_32_open ;
284
      capture_open <= capture_open_cross ;
285
    end if;
286
  end process;
287
288
--  Clock crossing logic: capture_clk -> bus_clk
289
-- delay by one clock
290
291
  process (bus_clk)
292
  begin
293
    if (bus_clk'event and bus_clk = '1') then
294
      has_been_full_cross <= capture_has_been_full ;
295
      has_been_full <= has_been_full_cross ;
296
    end if;
297
  end process;
298
299
300
----------------------write the data to line between the clock
301
302
process (clock_150MHz) 
303
begin
304
if rising_edge(clock_150MHz) then
305
DA <= std_logic_vector(signed(sinus)+8192); --DAC is not in twoes complement, so add 8192
306
DB <= std_logic_vector(signed(sinus)+8192);
307
end if;
308
end process;
309
310
--process (ADA_DCO)
311
--begin
312
--  if rising_edge(ADA_DCO) then
313
--     capture_clk <= not capture_clk;
314
--    if capture_clk='1' then
315
--        capture_data(15 downto 0) <=  ADCA_in & "00";
316
--      else capture_data (31 downto 16) <= ADCA_in & "00" ;
317
--    end if;
318
--    --end if;
319
--  end if;
320
--end process;
321
322
capture_clk <= ADA_DCO;
323
capture_data <= filteredsine1;
324
325
process (capture_clk)
326
  begin
327
    if (capture_clk'event and capture_clk = '1') then
328
    if  ( capture_full = '0' ) then
329
        capture_has_been_nonfull <= '1' ;
330
      elsif  ( capture_open = '0' ) then
331
        capture_has_been_nonfull <= '0' ;
332
      end if;
333
334
      if  ( capture_full = '1' and capture_has_been_nonfull = '1' ) then
335
        capture_has_been_full <= '1' ;
336
      elsif  ( capture_open = '0' ) then
337
        capture_has_been_full <= '0' ;
338
      end if;
339
340
    end if;
341
  end process;
342
343
  capture_en <= capture_open and not capture_full
344
                and not capture_has_been_full and not enoughdata;
345
346
347
348
--  The user_r_read_32_eof signal is required to go from '0' to '1' only on
349
--  a clock cycle following an asserted read enable, according to Xillybus'
350
--  core API. This is assured, since it's a logical AND between
351
--  user_r_read_32_empty and has_been_full. has_been_full goes high when the
352
--  FIFO is full, so it's guaranteed that user_r_read_32_empty is low when
353
--  that happens. On the other hand, user_r_read_32_empty is a FIFO's empty
354
--  signal, which naturally meets the requirement.
355
356
  user_r_read_32_eof <= (user_r_read_32_empty and has_been_full) or (enoughdata and user_r_read_32_empty) ;
357
  
358
  --------sample only 15000 Datapoints, then wait until file is closed
359
  process (clock_150MHz)
360
  begin
361
  if rising_edge(clock_150MHz) then
362
    if capture_en= '1' then
363
      if enoughdata = '0' then
364
        if datacounter < 15000 then
365
          datacounter <= datacounter +1;
366
        else 
367
          enoughdata <= '1';
368
        end if;
369
      end if;
370
    elsif capture_open = '0' then 
371
      datacounter <= 0;
372
      enoughdata <= '0';
373
    end if;
374
  end if;
375
end process;
376
377
----------------------FIFo_32
378
379
380
  fifo_32 : fifo
381
    port map(
382
      aclr        => reset_32,
383
      wrclk     => capture_clk,
384
      rdclk     => bus_clk,
385
      data        => capture_data,
386
      wrreq      => capture_en,
387
      rdreq      => user_r_read_32_rden,
388
      q       => user_r_read_32_data,
389
      wrfull       => capture_full,
390
      rdempty      => user_r_read_32_empty
391
      );
392
393
    -- reset if no Pipe is opened in PC
394
  reset_32 <= not user_r_read_32_open;
395
396
------------------------------demodulate signal
397
398
demod : demodulate port map (capture_clk, sinus, cosinus, ADCA_in, multipliedsine, multipliedcosine);
399
400
------------------------------filter everything
401
lowsin1: lowpass0_05 port map (capture_clk, '1', '0', multipliedsine & "0000", filteredsine1);
402
--lowcos1: lowpass0_05 port map (ADA_DCO, '1', '0', multipliedcosine & "0000", filteredcosine1);
403
404
405
end sample_arch;

: Bearbeitet durch User
von bko (Gast)


Lesenswert?

So richtig kann ich die Waveforms nicht deinen Signalen zuordnen..
Also zu data.png; was ist welches Signal in deinem VHDL Code?

Und irgentwie hast du viele Takte im Design, ist das so gewollt?
Siehe auch:
https://www.mikrocontroller.net/articles/Taktung_FPGA/CPLD
z.B:
>  Data: NCO port map (Clock_150MHz_inv, '1', incrementvalue_now, sinus, >cosinus, 
sine_data_valid, '1');
...
>demod : demodulate port map (capture_clk, sinus, cosinus, ADCA_in, 
>multipliedsine, multipliedcosine);
..

Was ist  >lowpass0_05< für ein Filter?
Braucht einen Reset?

von bko (Gast)


Lesenswert?

Es ist zu Heiß!

>Braucht es einen Reset?

von Gerald G. (gerald_g)


Lesenswert?

Hallo, mit einer Antwort hatte ich nicht mehr gerechnet, da das doch 
vielleicht etwas mehr Code war wie sich jemand durchliest.
Das Prinzip ist folgendes:
1
NCO--->DAC ---> ADC ---> multipliziere ---> tiefpass
2
  |                      ^
3
  |                      |
4
  ------>----->----->----
Also Ich erzeuge mit dem NCO einen Sinus, gebe ihn an einen DAC, 
schleife das Signal zurück an den ADC. Das gemessene ADC Signal ist 
ADA_D und wird bei einem rising_edge von ADA_DCO (DataClockOut) in 
ADA_In geschrieben.
ADA_In ist die oberste Zeile von Data.png.
Danach wird das ADA_In Signal mit dem im NCO erzeugten Sinus 
multipliziert (demoduliert) und bei einem rising_edge(ADA_DCO) in 
multipliedsinus geschrieben. Das ist das zweite Signal in Data.png
Das letzte Signal ist das Tiefpass gefilterte Signal nach dem 
Lowpassfilter (filteredsine)

Ich habe hier einmal den Code, ohne das ganze Datenübertragungsgerümpel.
Dann noch das demodulate.vhd
Beim Filter habe ich nun so manche Filter durch. IIR, FIR, decimation 
FIR. Im Code sieht es so aus als ob der decimation FIR einen reset 
brauch um Daten zu bearbeiten, FIR und IIR nicht. Es ändert sich auch 
nichts wenn ich vorher einen Reset ausführe.
Manchmal bekomme ich ein passendes gefiltertes Signal, jedoch ist so 
alle 10 Punkte ein extremer Ausreiser drin. Aber auch nur manchmal. 
Deshalb dachte ich an Timingprobleme.


Top entity:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
use ieee.numeric_std.all;
5
6
7
entity xillydemo is
8
  port (
9
   -----------------------------ADC
10
  AD_SCLK : inout std_logic;  --DataFormat Select-- '1' is twos complement
11
  AD_SDIO : inout std_logic; --DutyCycle Stabilizer
12
  ADA_D : in std_logic_vector(13 downto 0) ; -- Data
13
  ADA_DCO : in std_logic; --Data Clock out
14
  ADA_OE : out std_logic; --Out enable
15
  ADA_OR : in std_logic; -- Out of Range
16
  ADA_SPI_CS : out std_logic; --high for external mode
17
  );
18
end xillydemo;
19
  
20
architecture sample_arch of xillydemo is
21
22
  
23
  component pll2
24
  PORT
25
  (
26
    inclk0    : IN STD_LOGIC  := '0';
27
    c0    : OUT STD_LOGIC ; --250MHZ
28
    c1    : OUT STD_LOGIC ; --250MHz invertiert
29
    c2    : OUT STD_LOGIC ; --150MHz
30
    c3    : OUT STD_LOGIC ; -- 150MHz invertiert
31
    c4    : OUT STD_LOGIC ; --125MHz
32
    locked : OUT STD_LOGIC
33
  );
34
  end component;
35
  
36
  component demodulate 
37
  port(
38
  clock : in std_logic;
39
  sine : in std_logic_vector (13 downto 0);
40
  cosine : in std_logic_vector (13 downto 0);
41
  adc : in std_logic_vector (13 downto 0);
42
  sinemult : out std_logic_vector (27 downto 0);
43
  cosinemult : out std_logic_vector (27 downto 0)
44
  );
45
  end component;
46
47
48
  component lowpass0_05
49
   PORT( clk                             :   IN    std_logic; 
50
         clk_enable                      :   IN    std_logic; 
51
         reset                           :   IN    std_logic; 
52
         filter_in                       :   IN    std_logic_vector(31 DOWNTO 0); -- sfix28_En27
53
         filter_out                      :   OUT   std_logic_vector(31 DOWNTO 0)  -- sfix32_En26
54
  --    ce_out                          :   OUT   std_logic  
55
         );
56
57
  END component;
58
  
59
    ---------------------------Sinus
60
  
61
  component NCO
62
  port (
63
    clk       : in  std_logic                     := '0';             -- clk.clk
64
    clken     : in  std_logic                     := '0';             --  in.clken
65
    phi_inc_i : in  std_logic_vector(31 downto 0) := (others => '0'); --    .phi_inc_i
66
    fsin_o    : out std_logic_vector(13 downto 0);                    -- out.fsin_o
67
    fcos_o    : out std_logic_vector(13 downto 0);                    --    .fcos_o
68
    out_valid : out std_logic;                                        --    .out_valid
69
    reset_n   : in  std_logic                     := '0'              -- rst.reset_n
70
  );
71
  end component;
72
  
73
74
  
75
  ------------------------ADC
76
  
77
  signal clock_250MHz : std_logic;
78
  signal clock_250MHz_inv : std_logic;
79
  signal clock_150MHz : std_logic;
80
  signal clock_150MHz_inv : std_logic;
81
  signal sinus : std_logic_vector (13 downto 0);
82
  signal cosinus : std_logic_vector (13 downto 0);
83
  signal DACA_out : std_logic_vector (13 downto 0);
84
  signal DACB_out : std_logic_vector (13 downto 0);
85
  signal incrementvalue_now : std_logic_vector (31 downto 0) :=std_logic_vector(to_unsigned(286331153,32)); --344036
86
  signal counter : integer range 0 to 50000 :=0;
87
  signal increment_value : integer range 0 to 50764 := 829; --Anfang bei 20kHz. Ende bei 75MHz
88
  signal sine_data_valid : std_logic;
89
  signal ADCA_value_valid : std_logic;
90
  
91
  ----------------------- Daten
92
  signal ADCA_in : std_logic_vector (13 downto 0); --ADC Signal
93
  signal multipliedsine : std_logic_vector (27 downto 0); --ADC Signal mit erzeugtem Sinus multipliziert
94
  signal filteredsine1 : std_logic_vector (31 downto 0); -- Tiefpassgefiltertes Signal
95
  
96
97
98
99
100
101
begin
102
clocks: pll2 port map (clk_50, clock_250MHz, clock_250MHz_inv, clock_150MHz, clock_150MHz_inv, clk_125, reconfig_clk_locked);
103
Data: NCO port map (Clock_150MHz_inv, '1', incrementvalue_now, sinus, cosinus, sine_data_valid, '1');
104
105
106
----------------clocks for DCC
107
FPGA_CLK_A_P <= clock_150MHz_inv;
108
FPGA_CLK_A_N <= clock_150MHz;
109
FPGA_CLK_B_N <= clock_150MHz_inv;
110
FPGA_CLK_B_P <= clock_150MHz;
111
112
113
---------------configure ADC
114
AD_SCLK <= '1'; --set twos complement data mode
115
AD_SDIO <= '1'; --enable dutyCycle stabilizer
116
ADA_OE <= '0'; --enable ADCA_in
117
ADA_SPI_CS <= '1'; --set to external mode
118
119
-----------------read Data in rising edge of AD_DCO
120
121
process (ADA_DCO)
122
begin
123
if rising_edge(ADA_DCO) then
124
  ADCA_in <= ADA_D;
125
end if;
126
end process;
127
128
129
----------------------write the data to line between the clock
130
131
process (clock_150MHz) 
132
begin
133
if rising_edge(clock_150MHz) then
134
DA <= std_logic_vector(signed(sinus)+8192); --DAC is not in twoes complement, so add 8192
135
DB <= std_logic_vector(signed(sinus)+8192);
136
end if;
137
end process;
138
139
140
------------------------------demodulate signal
141
142
demod : demodulate port map (ADA_DCO, sinus, cosinus, ADCA_in, multipliedsine, multipliedcosine);
143
144
------------------------------filter everything
145
lowsin1: lowpass0_05 port map (ADA_DCO, '1', '0', multipliedsine & "0000", filteredsine1);
146
147
  
148
end sample_arch;


Demodulate.vhd
1
library IEEE;
2
use IEEE.std_logic_1164.ALL;
3
use IEEE.numeric_std.ALL;
4
5
entity demodulate is
6
  port(
7
  clock : in std_logic;
8
  sine : in std_logic_vector (13 downto 0);
9
  cosine : in std_logic_vector (13 downto 0);
10
  adc : in std_logic_vector (13 downto 0);
11
  sinemult : out std_logic_vector (27 downto 0);
12
  cosinemult : out std_logic_vector (27 downto 0)
13
  );
14
end entity;
15
16
architecture behave of demodulate is
17
signal sinesig, cosinesig : std_logic_vector (27 downto 0);
18
begin
19
  sinemult <= sinesig;
20
  cosinemult <= cosinesig;
21
process (clock)
22
begin
23
if rising_edge(clock) then
24
  sinesig <= std_logic_vector(signed(sine) * signed(adc));
25
  cosinesig <= std_logic_vector(signed(cosine) * signed(adc));
26
end if;
27
end process;
28
end;


IIR Filter von Matlab:
1
-- -------------------------------------------------------------
2
--
3
-- Module: lowpass0_05
4
-- Generated by MATLAB(R) 8.5 and the Filter Design HDL Coder 2.9.7.
5
-- Generated on: 2015-07-13 13:25:46
6
-- -------------------------------------------------------------
7
8
-- -------------------------------------------------------------
9
-- HDL Code Generation Options:
10
--
11
-- TargetLanguage: VHDL
12
-- Name: lowpass0_05
13
-- TestBenchStimulus: step ramp chirp 
14
15
-- Filter Specifications:
16
--
17
-- Sample Rate   : N/A (normalized frequency)
18
-- Response      : Lowpass
19
-- Specification : Nb,Na,F3dB
20
-- NumOrder      : 8
21
-- DenOrder      : 8
22
-- 3-dB Point    : 0.05
23
-- -------------------------------------------------------------
24
25
-- -------------------------------------------------------------
26
-- HDL Implementation    : Fully parallel
27
-- Multipliers           : 17
28
-- Folding Factor        : 1
29
-- -------------------------------------------------------------
30
-- Filter Settings:
31
--
32
-- Discrete-Time IIR Filter (real)
33
-- -------------------------------
34
-- Filter Structure    : Direct-Form II, Second-Order Sections
35
-- Number of Sections  : 4
36
-- Stable              : Yes
37
-- Linear Phase        : No
38
-- Arithmetic          : fixed
39
-- Numerator           : s18,15 -> [-4 4)
40
-- Denominator         : s18,16 -> [-2 2)
41
-- Scale Values        : s18,46 -> [-1.862645e-09 1.862645e-09)
42
-- Input               : s32,31 -> [-1 1)
43
-- Section Input       : s18,40 -> [-1.192093e-07 1.192093e-07)
44
-- Section Output      : s16,10 -> [-32 32)
45
-- Output              : s32,26 -> [-32 32)
46
-- State               : s16,15 -> [-1 1)
47
-- Numerator Prod      : s32,30 -> [-2 2)
48
-- Denominator Prod    : s32,29 -> [-4 4)
49
-- Numerator Accum     : s40,30 -> [-512 512)
50
-- Denominator Accum   : s40,29 -> [-1024 1024)
51
-- Round Mode          : convergent
52
-- Overflow Mode       : wrap
53
-- Cast Before Sum     : true
54
-- -------------------------------------------------------------
55
LIBRARY IEEE;
56
USE IEEE.std_logic_1164.all;
57
USE IEEE.numeric_std.ALL;
58
59
ENTITY lowpass0_05 IS
60
   PORT( clk                             :   IN    std_logic; 
61
         clk_enable                      :   IN    std_logic; 
62
         reset                           :   IN    std_logic; 
63
         filter_in                       :   IN    std_logic_vector(31 DOWNTO 0); -- sfix32_En31
64
         filter_out                      :   OUT   std_logic_vector(31 DOWNTO 0)  -- sfix32_En26
65
         );
66
67
END lowpass0_05;
68
69
70
----------------------------------------------------------------
71
--Module Architecture: lowpass0_05
72
----------------------------------------------------------------
73
ARCHITECTURE rtl OF lowpass0_05 IS
74
  -- Local Functions
75
  -- Type Definitions
76
  TYPE delay_pipeline_type IS ARRAY (NATURAL range <>) OF signed(15 DOWNTO 0); -- sfix16_En15
77
  -- Constants
78
  CONSTANT scaleconst1                    : signed(17 DOWNTO 0) := to_signed(69212, 18); -- sfix18_En46
79
  CONSTANT coeff_b1_section1              : signed(17 DOWNTO 0) := to_signed(32768, 18); -- sfix18_En15
80
  CONSTANT coeff_b2_section1              : signed(17 DOWNTO 0) := to_signed(65556, 18); -- sfix18_En15
81
  CONSTANT coeff_b3_section1              : signed(17 DOWNTO 0) := to_signed(32778, 18); -- sfix18_En15
82
  CONSTANT coeff_a2_section1              : signed(17 DOWNTO 0) := to_signed(-112238, 18); -- sfix18_En16
83
  CONSTANT coeff_a3_section1              : signed(17 DOWNTO 0) := to_signed(48101, 18); -- sfix18_En16
84
  CONSTANT coeff_b1_section2              : signed(17 DOWNTO 0) := to_signed(32768, 18); -- sfix18_En15
85
  CONSTANT coeff_b2_section2              : signed(17 DOWNTO 0) := to_signed(66356, 18); -- sfix18_En15
86
  CONSTANT coeff_b3_section2              : signed(17 DOWNTO 0) := to_signed(33598, 18); -- sfix18_En15
87
  CONSTANT coeff_a2_section2              : signed(17 DOWNTO 0) := to_signed(-114558, 18); -- sfix18_En16
88
  CONSTANT coeff_a3_section2              : signed(17 DOWNTO 0) := to_signed(50450, 18); -- sfix18_En16
89
  CONSTANT coeff_b1_section3              : signed(17 DOWNTO 0) := to_signed(32768, 18); -- sfix18_En15
90
  CONSTANT coeff_b2_section3              : signed(17 DOWNTO 0) := to_signed(65516, 18); -- sfix18_En15
91
  CONSTANT coeff_b3_section3              : signed(17 DOWNTO 0) := to_signed(32758, 18); -- sfix18_En15
92
  CONSTANT coeff_a2_section3              : signed(17 DOWNTO 0) := to_signed(-119107, 18); -- sfix18_En16
93
  CONSTANT coeff_a3_section3              : signed(17 DOWNTO 0) := to_signed(55055, 18); -- sfix18_En16
94
  CONSTANT coeff_b1_section4              : signed(17 DOWNTO 0) := to_signed(32768, 18); -- sfix18_En15
95
  CONSTANT coeff_b2_section4              : signed(17 DOWNTO 0) := to_signed(64716, 18); -- sfix18_En15
96
  CONSTANT coeff_b3_section4              : signed(17 DOWNTO 0) := to_signed(31958, 18); -- sfix18_En15
97
  CONSTANT coeff_a2_section4              : signed(17 DOWNTO 0) := to_signed(-125624, 18); -- sfix18_En16
98
  CONSTANT coeff_a3_section4              : signed(17 DOWNTO 0) := to_signed(61654, 18); -- sfix18_En16
99
  -- Signals
100
  SIGNAL input_register                   : signed(31 DOWNTO 0); -- sfix32_En31
101
  SIGNAL scale1                           : signed(54 DOWNTO 0); -- sfix55_En77
102
  SIGNAL mul_temp                         : signed(49 DOWNTO 0); -- sfix50_En77
103
  SIGNAL scaletypeconvert1                : signed(17 DOWNTO 0); -- sfix18_En40
104
  -- Section 1 Signals 
105
  SIGNAL a1sum1                           : signed(39 DOWNTO 0); -- sfix40_En29
106
  SIGNAL a2sum1                           : signed(39 DOWNTO 0); -- sfix40_En29
107
  SIGNAL b1sum1                           : signed(39 DOWNTO 0); -- sfix40_En30
108
  SIGNAL b2sum1                           : signed(39 DOWNTO 0); -- sfix40_En30
109
  SIGNAL typeconvert1                     : signed(15 DOWNTO 0); -- sfix16_En15
110
  SIGNAL delay_section1                   : delay_pipeline_type(0 TO 1); -- sfix16_En15
111
  SIGNAL inputconv1                       : signed(39 DOWNTO 0); -- sfix40_En29
112
  SIGNAL a2mul1                           : signed(31 DOWNTO 0); -- sfix32_En29
113
  SIGNAL a3mul1                           : signed(31 DOWNTO 0); -- sfix32_En29
114
  SIGNAL b1mul1                           : signed(31 DOWNTO 0); -- sfix32_En30
115
  SIGNAL b2mul1                           : signed(31 DOWNTO 0); -- sfix32_En30
116
  SIGNAL b3mul1                           : signed(31 DOWNTO 0); -- sfix32_En30
117
  SIGNAL mul_temp_1                       : signed(33 DOWNTO 0); -- sfix34_En31
118
  SIGNAL mul_temp_2                       : signed(33 DOWNTO 0); -- sfix34_En31
119
  SIGNAL mul_temp_3                       : signed(33 DOWNTO 0); -- sfix34_En30
120
  SIGNAL mul_temp_4                       : signed(33 DOWNTO 0); -- sfix34_En30
121
  SIGNAL sub_cast                         : signed(39 DOWNTO 0); -- sfix40_En29
122
  SIGNAL sub_cast_1                       : signed(39 DOWNTO 0); -- sfix40_En29
123
  SIGNAL sub_temp                         : signed(40 DOWNTO 0); -- sfix41_En29
124
  SIGNAL sub_cast_2                       : signed(39 DOWNTO 0); -- sfix40_En29
125
  SIGNAL sub_cast_3                       : signed(39 DOWNTO 0); -- sfix40_En29
126
  SIGNAL sub_temp_1                       : signed(40 DOWNTO 0); -- sfix41_En29
127
  SIGNAL b1multypeconvert1                : signed(39 DOWNTO 0); -- sfix40_En30
128
  SIGNAL add_cast                         : signed(39 DOWNTO 0); -- sfix40_En30
129
  SIGNAL add_cast_1                       : signed(39 DOWNTO 0); -- sfix40_En30
130
  SIGNAL add_temp                         : signed(40 DOWNTO 0); -- sfix41_En30
131
  SIGNAL add_cast_2                       : signed(39 DOWNTO 0); -- sfix40_En30
132
  SIGNAL add_cast_3                       : signed(39 DOWNTO 0); -- sfix40_En30
133
  SIGNAL add_temp_1                       : signed(40 DOWNTO 0); -- sfix41_En30
134
  SIGNAL section_result1                  : signed(39 DOWNTO 0); -- sfix40_En29
135
  -- Section 2 Signals 
136
  SIGNAL a1sum2                           : signed(39 DOWNTO 0); -- sfix40_En29
137
  SIGNAL a2sum2                           : signed(39 DOWNTO 0); -- sfix40_En29
138
  SIGNAL b1sum2                           : signed(39 DOWNTO 0); -- sfix40_En30
139
  SIGNAL b2sum2                           : signed(39 DOWNTO 0); -- sfix40_En30
140
  SIGNAL typeconvert2                     : signed(15 DOWNTO 0); -- sfix16_En15
141
  SIGNAL delay_section2                   : delay_pipeline_type(0 TO 1); -- sfix16_En15
142
  SIGNAL inputconv2                       : signed(39 DOWNTO 0); -- sfix40_En29
143
  SIGNAL a2mul2                           : signed(31 DOWNTO 0); -- sfix32_En29
144
  SIGNAL a3mul2                           : signed(31 DOWNTO 0); -- sfix32_En29
145
  SIGNAL b1mul2                           : signed(31 DOWNTO 0); -- sfix32_En30
146
  SIGNAL b2mul2                           : signed(31 DOWNTO 0); -- sfix32_En30
147
  SIGNAL b3mul2                           : signed(31 DOWNTO 0); -- sfix32_En30
148
  SIGNAL mul_temp_5                       : signed(33 DOWNTO 0); -- sfix34_En31
149
  SIGNAL mul_temp_6                       : signed(33 DOWNTO 0); -- sfix34_En31
150
  SIGNAL mul_temp_7                       : signed(33 DOWNTO 0); -- sfix34_En30
151
  SIGNAL mul_temp_8                       : signed(33 DOWNTO 0); -- sfix34_En30
152
  SIGNAL sub_cast_4                       : signed(39 DOWNTO 0); -- sfix40_En29
153
  SIGNAL sub_cast_5                       : signed(39 DOWNTO 0); -- sfix40_En29
154
  SIGNAL sub_temp_2                       : signed(40 DOWNTO 0); -- sfix41_En29
155
  SIGNAL sub_cast_6                       : signed(39 DOWNTO 0); -- sfix40_En29
156
  SIGNAL sub_cast_7                       : signed(39 DOWNTO 0); -- sfix40_En29
157
  SIGNAL sub_temp_3                       : signed(40 DOWNTO 0); -- sfix41_En29
158
  SIGNAL b1multypeconvert2                : signed(39 DOWNTO 0); -- sfix40_En30
159
  SIGNAL add_cast_4                       : signed(39 DOWNTO 0); -- sfix40_En30
160
  SIGNAL add_cast_5                       : signed(39 DOWNTO 0); -- sfix40_En30
161
  SIGNAL add_temp_2                       : signed(40 DOWNTO 0); -- sfix41_En30
162
  SIGNAL add_cast_6                       : signed(39 DOWNTO 0); -- sfix40_En30
163
  SIGNAL add_cast_7                       : signed(39 DOWNTO 0); -- sfix40_En30
164
  SIGNAL add_temp_3                       : signed(40 DOWNTO 0); -- sfix41_En30
165
  SIGNAL section_result2                  : signed(39 DOWNTO 0); -- sfix40_En29
166
  -- Section 3 Signals 
167
  SIGNAL a1sum3                           : signed(39 DOWNTO 0); -- sfix40_En29
168
  SIGNAL a2sum3                           : signed(39 DOWNTO 0); -- sfix40_En29
169
  SIGNAL b1sum3                           : signed(39 DOWNTO 0); -- sfix40_En30
170
  SIGNAL b2sum3                           : signed(39 DOWNTO 0); -- sfix40_En30
171
  SIGNAL typeconvert3                     : signed(15 DOWNTO 0); -- sfix16_En15
172
  SIGNAL delay_section3                   : delay_pipeline_type(0 TO 1); -- sfix16_En15
173
  SIGNAL inputconv3                       : signed(39 DOWNTO 0); -- sfix40_En29
174
  SIGNAL a2mul3                           : signed(31 DOWNTO 0); -- sfix32_En29
175
  SIGNAL a3mul3                           : signed(31 DOWNTO 0); -- sfix32_En29
176
  SIGNAL b1mul3                           : signed(31 DOWNTO 0); -- sfix32_En30
177
  SIGNAL b2mul3                           : signed(31 DOWNTO 0); -- sfix32_En30
178
  SIGNAL b3mul3                           : signed(31 DOWNTO 0); -- sfix32_En30
179
  SIGNAL mul_temp_9                       : signed(33 DOWNTO 0); -- sfix34_En31
180
  SIGNAL mul_temp_10                      : signed(33 DOWNTO 0); -- sfix34_En31
181
  SIGNAL mul_temp_11                      : signed(33 DOWNTO 0); -- sfix34_En30
182
  SIGNAL mul_temp_12                      : signed(33 DOWNTO 0); -- sfix34_En30
183
  SIGNAL sub_cast_8                       : signed(39 DOWNTO 0); -- sfix40_En29
184
  SIGNAL sub_cast_9                       : signed(39 DOWNTO 0); -- sfix40_En29
185
  SIGNAL sub_temp_4                       : signed(40 DOWNTO 0); -- sfix41_En29
186
  SIGNAL sub_cast_10                      : signed(39 DOWNTO 0); -- sfix40_En29
187
  SIGNAL sub_cast_11                      : signed(39 DOWNTO 0); -- sfix40_En29
188
  SIGNAL sub_temp_5                       : signed(40 DOWNTO 0); -- sfix41_En29
189
  SIGNAL b1multypeconvert3                : signed(39 DOWNTO 0); -- sfix40_En30
190
  SIGNAL add_cast_8                       : signed(39 DOWNTO 0); -- sfix40_En30
191
  SIGNAL add_cast_9                       : signed(39 DOWNTO 0); -- sfix40_En30
192
  SIGNAL add_temp_4                       : signed(40 DOWNTO 0); -- sfix41_En30
193
  SIGNAL add_cast_10                      : signed(39 DOWNTO 0); -- sfix40_En30
194
  SIGNAL add_cast_11                      : signed(39 DOWNTO 0); -- sfix40_En30
195
  SIGNAL add_temp_5                       : signed(40 DOWNTO 0); -- sfix41_En30
196
  SIGNAL section_result3                  : signed(39 DOWNTO 0); -- sfix40_En29
197
  -- Section 4 Signals 
198
  SIGNAL a1sum4                           : signed(39 DOWNTO 0); -- sfix40_En29
199
  SIGNAL a2sum4                           : signed(39 DOWNTO 0); -- sfix40_En29
200
  SIGNAL b1sum4                           : signed(39 DOWNTO 0); -- sfix40_En30
201
  SIGNAL b2sum4                           : signed(39 DOWNTO 0); -- sfix40_En30
202
  SIGNAL typeconvert4                     : signed(15 DOWNTO 0); -- sfix16_En15
203
  SIGNAL delay_section4                   : delay_pipeline_type(0 TO 1); -- sfix16_En15
204
  SIGNAL inputconv4                       : signed(39 DOWNTO 0); -- sfix40_En29
205
  SIGNAL a2mul4                           : signed(31 DOWNTO 0); -- sfix32_En29
206
  SIGNAL a3mul4                           : signed(31 DOWNTO 0); -- sfix32_En29
207
  SIGNAL b1mul4                           : signed(31 DOWNTO 0); -- sfix32_En30
208
  SIGNAL b2mul4                           : signed(31 DOWNTO 0); -- sfix32_En30
209
  SIGNAL b3mul4                           : signed(31 DOWNTO 0); -- sfix32_En30
210
  SIGNAL mul_temp_13                      : signed(33 DOWNTO 0); -- sfix34_En31
211
  SIGNAL mul_temp_14                      : signed(33 DOWNTO 0); -- sfix34_En31
212
  SIGNAL mul_temp_15                      : signed(33 DOWNTO 0); -- sfix34_En30
213
  SIGNAL mul_temp_16                      : signed(33 DOWNTO 0); -- sfix34_En30
214
  SIGNAL sub_cast_12                      : signed(39 DOWNTO 0); -- sfix40_En29
215
  SIGNAL sub_cast_13                      : signed(39 DOWNTO 0); -- sfix40_En29
216
  SIGNAL sub_temp_6                       : signed(40 DOWNTO 0); -- sfix41_En29
217
  SIGNAL sub_cast_14                      : signed(39 DOWNTO 0); -- sfix40_En29
218
  SIGNAL sub_cast_15                      : signed(39 DOWNTO 0); -- sfix40_En29
219
  SIGNAL sub_temp_7                       : signed(40 DOWNTO 0); -- sfix41_En29
220
  SIGNAL b1multypeconvert4                : signed(39 DOWNTO 0); -- sfix40_En30
221
  SIGNAL add_cast_12                      : signed(39 DOWNTO 0); -- sfix40_En30
222
  SIGNAL add_cast_13                      : signed(39 DOWNTO 0); -- sfix40_En30
223
  SIGNAL add_temp_6                       : signed(40 DOWNTO 0); -- sfix41_En30
224
  SIGNAL add_cast_14                      : signed(39 DOWNTO 0); -- sfix40_En30
225
  SIGNAL add_cast_15                      : signed(39 DOWNTO 0); -- sfix40_En30
226
  SIGNAL add_temp_7                       : signed(40 DOWNTO 0); -- sfix41_En30
227
  SIGNAL output_typeconvert               : signed(31 DOWNTO 0); -- sfix32_En26
228
  SIGNAL output_register                  : signed(31 DOWNTO 0); -- sfix32_En26
229
230
231
BEGIN
232
233
  -- Block Statements
234
  input_reg_process : PROCESS (clk, reset)
235
  BEGIN
236
    IF reset = '1' THEN
237
      input_register <= (OTHERS => '0');
238
    ELSIF clk'event AND clk = '1' THEN
239
      IF clk_enable = '1' THEN
240
        input_register <= signed(filter_in);
241
      END IF;
242
    END IF; 
243
  END PROCESS input_reg_process;
244
245
  mul_temp <= input_register * scaleconst1;
246
  scale1 <= resize(mul_temp, 55);
247
248
  scaletypeconvert1 <= resize(shift_right(scale1(54 DOWNTO 0) + ( "0" & (scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37) & NOT scale1(37))), 37), 18);
249
250
  --   ------------------ Section 1 ------------------
251
252
  typeconvert1 <= resize(shift_right(a1sum1(29 DOWNTO 0) + ( "0" & (a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14) & NOT a1sum1(14))), 14), 16);
253
254
  delay_process_section1 : PROCESS (clk, reset)
255
  BEGIN
256
    IF reset = '1' THEN
257
      delay_section1 <= (OTHERS => (OTHERS => '0'));
258
    ELSIF clk'event AND clk = '1' THEN
259
      IF clk_enable = '1' THEN
260
        delay_section1(1) <= delay_section1(0);
261
        delay_section1(0) <= typeconvert1;
262
      END IF;
263
    END IF;
264
  END PROCESS delay_process_section1;
265
266
  inputconv1 <= resize(shift_right(scaletypeconvert1(17) & scaletypeconvert1(17 DOWNTO 0) + ( "0" & (scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11) & NOT scaletypeconvert1(11))), 11), 40);
267
268
  mul_temp_1 <= delay_section1(0) * coeff_a2_section1;
269
  a2mul1 <= resize(shift_right(mul_temp_1(33 DOWNTO 0) + ( "0" & (mul_temp_1(2) & NOT mul_temp_1(2))), 2), 32);
270
271
  mul_temp_2 <= delay_section1(1) * coeff_a3_section1;
272
  a3mul1 <= resize(shift_right(mul_temp_2(33 DOWNTO 0) + ( "0" & (mul_temp_2(2) & NOT mul_temp_2(2))), 2), 32);
273
274
  b1mul1 <= resize(typeconvert1(15 DOWNTO 0) & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32);
275
276
  mul_temp_3 <= delay_section1(0) * coeff_b2_section1;
277
  b2mul1 <= mul_temp_3(31 DOWNTO 0);
278
279
  mul_temp_4 <= delay_section1(1) * coeff_b3_section1;
280
  b3mul1 <= mul_temp_4(31 DOWNTO 0);
281
282
  sub_cast <= inputconv1;
283
  sub_cast_1 <= resize(a2mul1, 40);
284
  sub_temp <= resize(sub_cast, 41) - resize(sub_cast_1, 41);
285
  a2sum1 <= sub_temp(39 DOWNTO 0);
286
287
  sub_cast_2 <= a2sum1;
288
  sub_cast_3 <= resize(a3mul1, 40);
289
  sub_temp_1 <= resize(sub_cast_2, 41) - resize(sub_cast_3, 41);
290
  a1sum1 <= sub_temp_1(39 DOWNTO 0);
291
292
  b1multypeconvert1 <= resize(b1mul1, 40);
293
294
  add_cast <= b1multypeconvert1;
295
  add_cast_1 <= resize(b2mul1, 40);
296
  add_temp <= resize(add_cast, 41) + resize(add_cast_1, 41);
297
  b2sum1 <= add_temp(39 DOWNTO 0);
298
299
  add_cast_2 <= b2sum1;
300
  add_cast_3 <= resize(b3mul1, 40);
301
  add_temp_1 <= resize(add_cast_2, 41) + resize(add_cast_3, 41);
302
  b1sum1 <= add_temp_1(39 DOWNTO 0);
303
304
  section_result1 <= resize(shift_right(b1sum1(39) & b1sum1(39 DOWNTO 0) + ( "0" & (b1sum1(1))), 1), 40);
305
306
  --   ------------------ Section 2 ------------------
307
308
  typeconvert2 <= resize(shift_right(a1sum2(29 DOWNTO 0) + ( "0" & (a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14) & NOT a1sum2(14))), 14), 16);
309
310
  delay_process_section2 : PROCESS (clk, reset)
311
  BEGIN
312
    IF reset = '1' THEN
313
      delay_section2 <= (OTHERS => (OTHERS => '0'));
314
    ELSIF clk'event AND clk = '1' THEN
315
      IF clk_enable = '1' THEN
316
        delay_section2(1) <= delay_section2(0);
317
        delay_section2(0) <= typeconvert2;
318
      END IF;
319
    END IF;
320
  END PROCESS delay_process_section2;
321
322
  inputconv2 <= section_result1;
323
324
  mul_temp_5 <= delay_section2(0) * coeff_a2_section2;
325
  a2mul2 <= resize(shift_right(mul_temp_5(33 DOWNTO 0) + ( "0" & (mul_temp_5(2) & NOT mul_temp_5(2))), 2), 32);
326
327
  mul_temp_6 <= delay_section2(1) * coeff_a3_section2;
328
  a3mul2 <= resize(shift_right(mul_temp_6(33 DOWNTO 0) + ( "0" & (mul_temp_6(2) & NOT mul_temp_6(2))), 2), 32);
329
330
  b1mul2 <= resize(typeconvert2(15 DOWNTO 0) & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32);
331
332
  mul_temp_7 <= delay_section2(0) * coeff_b2_section2;
333
  b2mul2 <= mul_temp_7(31 DOWNTO 0);
334
335
  mul_temp_8 <= delay_section2(1) * coeff_b3_section2;
336
  b3mul2 <= mul_temp_8(31 DOWNTO 0);
337
338
  sub_cast_4 <= inputconv2;
339
  sub_cast_5 <= resize(a2mul2, 40);
340
  sub_temp_2 <= resize(sub_cast_4, 41) - resize(sub_cast_5, 41);
341
  a2sum2 <= sub_temp_2(39 DOWNTO 0);
342
343
  sub_cast_6 <= a2sum2;
344
  sub_cast_7 <= resize(a3mul2, 40);
345
  sub_temp_3 <= resize(sub_cast_6, 41) - resize(sub_cast_7, 41);
346
  a1sum2 <= sub_temp_3(39 DOWNTO 0);
347
348
  b1multypeconvert2 <= resize(b1mul2, 40);
349
350
  add_cast_4 <= b1multypeconvert2;
351
  add_cast_5 <= resize(b2mul2, 40);
352
  add_temp_2 <= resize(add_cast_4, 41) + resize(add_cast_5, 41);
353
  b2sum2 <= add_temp_2(39 DOWNTO 0);
354
355
  add_cast_6 <= b2sum2;
356
  add_cast_7 <= resize(b3mul2, 40);
357
  add_temp_3 <= resize(add_cast_6, 41) + resize(add_cast_7, 41);
358
  b1sum2 <= add_temp_3(39 DOWNTO 0);
359
360
  section_result2 <= resize(shift_right(b1sum2(39) & b1sum2(39 DOWNTO 0) + ( "0" & (b1sum2(1))), 1), 40);
361
362
  --   ------------------ Section 3 ------------------
363
364
  typeconvert3 <= resize(shift_right(a1sum3(29 DOWNTO 0) + ( "0" & (a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14) & NOT a1sum3(14))), 14), 16);
365
366
  delay_process_section3 : PROCESS (clk, reset)
367
  BEGIN
368
    IF reset = '1' THEN
369
      delay_section3 <= (OTHERS => (OTHERS => '0'));
370
    ELSIF clk'event AND clk = '1' THEN
371
      IF clk_enable = '1' THEN
372
        delay_section3(1) <= delay_section3(0);
373
        delay_section3(0) <= typeconvert3;
374
      END IF;
375
    END IF;
376
  END PROCESS delay_process_section3;
377
378
  inputconv3 <= section_result2;
379
380
  mul_temp_9 <= delay_section3(0) * coeff_a2_section3;
381
  a2mul3 <= resize(shift_right(mul_temp_9(33 DOWNTO 0) + ( "0" & (mul_temp_9(2) & NOT mul_temp_9(2))), 2), 32);
382
383
  mul_temp_10 <= delay_section3(1) * coeff_a3_section3;
384
  a3mul3 <= resize(shift_right(mul_temp_10(33 DOWNTO 0) + ( "0" & (mul_temp_10(2) & NOT mul_temp_10(2))), 2), 32);
385
386
  b1mul3 <= resize(typeconvert3(15 DOWNTO 0) & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32);
387
388
  mul_temp_11 <= delay_section3(0) * coeff_b2_section3;
389
  b2mul3 <= mul_temp_11(31 DOWNTO 0);
390
391
  mul_temp_12 <= delay_section3(1) * coeff_b3_section3;
392
  b3mul3 <= mul_temp_12(31 DOWNTO 0);
393
394
  sub_cast_8 <= inputconv3;
395
  sub_cast_9 <= resize(a2mul3, 40);
396
  sub_temp_4 <= resize(sub_cast_8, 41) - resize(sub_cast_9, 41);
397
  a2sum3 <= sub_temp_4(39 DOWNTO 0);
398
399
  sub_cast_10 <= a2sum3;
400
  sub_cast_11 <= resize(a3mul3, 40);
401
  sub_temp_5 <= resize(sub_cast_10, 41) - resize(sub_cast_11, 41);
402
  a1sum3 <= sub_temp_5(39 DOWNTO 0);
403
404
  b1multypeconvert3 <= resize(b1mul3, 40);
405
406
  add_cast_8 <= b1multypeconvert3;
407
  add_cast_9 <= resize(b2mul3, 40);
408
  add_temp_4 <= resize(add_cast_8, 41) + resize(add_cast_9, 41);
409
  b2sum3 <= add_temp_4(39 DOWNTO 0);
410
411
  add_cast_10 <= b2sum3;
412
  add_cast_11 <= resize(b3mul3, 40);
413
  add_temp_5 <= resize(add_cast_10, 41) + resize(add_cast_11, 41);
414
  b1sum3 <= add_temp_5(39 DOWNTO 0);
415
416
  section_result3 <= resize(shift_right(b1sum3(39) & b1sum3(39 DOWNTO 0) + ( "0" & (b1sum3(1))), 1), 40);
417
418
  --   ------------------ Section 4 ------------------
419
420
  typeconvert4 <= resize(shift_right(a1sum4(29 DOWNTO 0) + ( "0" & (a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14) & NOT a1sum4(14))), 14), 16);
421
422
  delay_process_section4 : PROCESS (clk, reset)
423
  BEGIN
424
    IF reset = '1' THEN
425
      delay_section4 <= (OTHERS => (OTHERS => '0'));
426
    ELSIF clk'event AND clk = '1' THEN
427
      IF clk_enable = '1' THEN
428
        delay_section4(1) <= delay_section4(0);
429
        delay_section4(0) <= typeconvert4;
430
      END IF;
431
    END IF;
432
  END PROCESS delay_process_section4;
433
434
  inputconv4 <= section_result3;
435
436
  mul_temp_13 <= delay_section4(0) * coeff_a2_section4;
437
  a2mul4 <= resize(shift_right(mul_temp_13(33 DOWNTO 0) + ( "0" & (mul_temp_13(2) & NOT mul_temp_13(2))), 2), 32);
438
439
  mul_temp_14 <= delay_section4(1) * coeff_a3_section4;
440
  a3mul4 <= resize(shift_right(mul_temp_14(33 DOWNTO 0) + ( "0" & (mul_temp_14(2) & NOT mul_temp_14(2))), 2), 32);
441
442
  b1mul4 <= resize(typeconvert4(15 DOWNTO 0) & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32);
443
444
  mul_temp_15 <= delay_section4(0) * coeff_b2_section4;
445
  b2mul4 <= mul_temp_15(31 DOWNTO 0);
446
447
  mul_temp_16 <= delay_section4(1) * coeff_b3_section4;
448
  b3mul4 <= mul_temp_16(31 DOWNTO 0);
449
450
  sub_cast_12 <= inputconv4;
451
  sub_cast_13 <= resize(a2mul4, 40);
452
  sub_temp_6 <= resize(sub_cast_12, 41) - resize(sub_cast_13, 41);
453
  a2sum4 <= sub_temp_6(39 DOWNTO 0);
454
455
  sub_cast_14 <= a2sum4;
456
  sub_cast_15 <= resize(a3mul4, 40);
457
  sub_temp_7 <= resize(sub_cast_14, 41) - resize(sub_cast_15, 41);
458
  a1sum4 <= sub_temp_7(39 DOWNTO 0);
459
460
  b1multypeconvert4 <= resize(b1mul4, 40);
461
462
  add_cast_12 <= b1multypeconvert4;
463
  add_cast_13 <= resize(b2mul4, 40);
464
  add_temp_6 <= resize(add_cast_12, 41) + resize(add_cast_13, 41);
465
  b2sum4 <= add_temp_6(39 DOWNTO 0);
466
467
  add_cast_14 <= b2sum4;
468
  add_cast_15 <= resize(b3mul4, 40);
469
  add_temp_7 <= resize(add_cast_14, 41) + resize(add_cast_15, 41);
470
  b1sum4 <= add_temp_7(39 DOWNTO 0);
471
472
  output_typeconvert <= resize(shift_right(b1sum4(35 DOWNTO 0) + ( "0" & (b1sum4(4) & NOT b1sum4(4) & NOT b1sum4(4) & NOT b1sum4(4))), 4), 32);
473
474
  Output_Register_process : PROCESS (clk, reset)
475
  BEGIN
476
    IF reset = '1' THEN
477
      output_register <= (OTHERS => '0');
478
    ELSIF clk'event AND clk = '1' THEN
479
      IF clk_enable = '1' THEN
480
        output_register <= output_typeconvert;
481
      END IF;
482
    END IF; 
483
  END PROCESS Output_Register_process;
484
485
  -- Assignment Statements
486
  filter_out <= std_logic_vector(output_register);
487
END rtl;

: Bearbeitet durch User
von Gerald G. (gerald_g)


Angehängte Dateien:

Lesenswert?

Ich habe das ganze einmal direkt mit einem relativ einfachen FIR-Filter 
versucht.
Oben im Bild sind die ADC Daten so wie ich sie messe, unten sind die 
Daten nach dem Filter.
Man sieht deutlich die Ausreiser. Was auch auffällt, sobald der Sinus 
eine Linkskurve macht, gehen die Ausreiser nach oben, sobald er in einer 
Rechtskurve ist, gehen sie nach unten.
Doch vom Timing her sollte es doch klappen, wenn ich mir die Daten immer 
an der steigenden Flanke hole, oder?

von Duke Scarring (Gast)


Lesenswert?

Gerald G. schrieb:
> Doch vom Timing her sollte es doch klappen
Sind die Constraints richtig gesetzt?
Hast Du dem Filter genügen Bits spendiert?
Tritt der Fehler auch auf, wenn Dein Eingangssignal eine geringere 
Amplitude hat?

Duke

von Gerald G. (gerald_g)


Lesenswert?

Ich habe es jetzt einmal mit der IP core von Altera getestet. 
Funktioniert damit genau wie es soll.
Ist sogar sehr sparsam. Leider nicht so gut konfigurierbar wie bei 
Matlab. Vielleicht ist die implementation von Matlab zu langsam für 
150MSPS.
Selbst bei einem einfachen FIR Filter mit wenigen Koeffizienten, mit 16 
Bit Input und 16 Bit Koeffizienten, alles andere auf "full precision" 
funktioniert es nicht.
Ich teste mal den IP Core Decimation Filter und danach den Matlab 
Filter.

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
Noch kein Account? Hier anmelden.