Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Using Xilinx fft core

Status
Not open for further replies.

Radhikamkr

Newbie level 5
Joined
Jul 23, 2018
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
451
I was trying to read data from a file and input it to xilinx fft core.

This is my code

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
--------------------------------------------------------------------------------
-- (c) Copyright 2010 - 2013 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
-- Description:
-- This is an example testbench for the Fast Fourier Transform IP core.
-- The testbench has been generated by Vivado to accompany the IP core
-- instance you have generated.
--
-- This testbench is for demonstration purposes only.  See note below for
-- instructions on how to use it with your core.
--
-- See the Fast Fourier Transform product guide for further information
-- about this core.
--
--------------------------------------------------------------------------------
-- Using this testbench
--
-- This testbench instantiates your generated Fast Fourier Transform core
-- instance named "xfft_0".
--
-- Use Vivado's Run Simulation flow to run this testbench.  See the Vivado
-- documentation for details.
--------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use STD.textio.all;
 
entity tb_xfft_0 is
end tb_xfft_0;
 
architecture tb of tb_xfft_0 is
 
  -----------------------------------------------------------------------
  -- Timing constants
  -----------------------------------------------------------------------
  constant CLOCK_PERIOD : time := 100 ns;
  constant T_HOLD       : time := 10 ns;
  constant T_STROBE     : time := CLOCK_PERIOD - (1 ns);
 
  -----------------------------------------------------------------------
  -- DUT signals
  -----------------------------------------------------------------------
 
  -- General signals
  signal aclk                        : std_logic := '0';  -- the master clock
  signal aresetn                     : std_logic := '1';  -- synchronous active low reset
 
  -- Config slave channel signals
  signal s_axis_config_tvalid        : std_logic := '0';  -- payload is valid
  signal s_axis_config_tready        : std_logic := '1';  -- slave is ready
  signal s_axis_config_tdata         : std_logic_vector(15 downto 0) := (others => '0');  -- data payload
 
  -- Data slave channel signals
  signal s_axis_data_tvalid          : std_logic := '0';  -- payload is valid
  signal s_axis_data_tready          : std_logic := '1';  -- slave is ready
  signal s_axis_data_tdata           : std_logic_vector(47 downto 0) := (others => '0');  -- data payload
  signal s_axis_data_tlast           : std_logic := '0';  -- indicates end of packet
 
  -- Data master channel signals
  signal m_axis_data_tvalid          : std_logic := '0';  -- payload is valid
  signal m_axis_data_tready          : std_logic := '1';  -- slave is ready
  signal m_axis_data_tdata           : std_logic_vector(47 downto 0) := (others => '0');  -- data payload
  signal m_axis_data_tlast           : std_logic := '0';  -- indicates end of packet
 
  -- Event signals
  signal event_frame_started         : std_logic := '0';
  signal event_tlast_unexpected      : std_logic := '0';
  signal event_tlast_missing         : std_logic := '0';
  signal event_status_channel_halt   : std_logic := '0';
  signal event_data_in_channel_halt  : std_logic := '0';
  signal event_data_out_channel_halt : std_logic := '0';
 
  -----------------------------------------------------------------------
  -- Aliases for AXI channel TDATA and TUSER fields
  -- These are a convenience for viewing data in a simulator waveform viewer.
  -- If using ModelSim or Questa, add "-voptargs=+acc=n" to the vsim command
  -- to prevent the simulator optimizing away these signals.
  -----------------------------------------------------------------------
 
  -- Config slave channel alias signals
  signal s_axis_config_tdata_fwd_inv      : std_logic                    := '0';              -- forward or inverse
  signal s_axis_config_tdata_scale_sch    : std_logic_vector(9 downto 0) := (others => '0');  -- scaling schedule
 
  -- Data slave channel alias signals
  signal s_axis_data_tdata_re             : std_logic_vector(17 downto 0) := (others => '0');  -- real data
  signal s_axis_data_tdata_im             : std_logic_vector(17 downto 0) := (others => '0');  -- imaginary data
 
  -- Data master channel alias signals
  signal m_axis_data_tdata_re             : std_logic_vector(17 downto 0) := (others => '0');  -- real data
  signal m_axis_data_tdata_im             : std_logic_vector(17 downto 0) := (others => '0');  -- imaginary data
 
  -----------------------------------------------------------------------
  -- Constants, types and functions to create input data
  -----------------------------------------------------------------------
 
  constant IP_WIDTH    : integer := 18;
  constant MAX_SAMPLES : integer := 2**9;  -- maximum number of samples in a frame
  type T_IP_SAMPLE is record
    re : std_logic_vector(IP_WIDTH-1 downto 0);
    im : std_logic_vector(IP_WIDTH-1 downto 0);
  end record;
  type T_IP_TABLE is array (0 to MAX_SAMPLES-1) of T_IP_SAMPLE;
 
  -- Zeroed input data table, for reset and initialization
  constant IP_TABLE_CLEAR : T_IP_TABLE := (others => (re => (others => '0'),
                                                      im => (others => '0')));
 
  -- Function to generate input data table
  -- Data is a complex sinusoid exp(-jwt) with a frequency 2.6 times the frame size
  -- added to another with a lower magnitude and a higher frequency
  
   impure function create_ip_table return T_IP_TABLE is
    variable result : T_IP_TABLE;
    variable theta  : real;
    variable theta2 : real;
    variable re_real : real;
    variable im_real : real;
    variable re_int : integer;
    variable im_int : integer;
    constant DATA_WIDTH : integer := 16;
    file inFile : text;
    variable i : integer;
    variable v_ILINE     : line;
    
 
   
  begin
      file_open(inFile, "in.txt",read_mode); 
      i :=0;
      while not endfile(inFile) loop
      theta :=0.0;
      theta2 :=0.0;
      readline(inFile, v_ILINE);
      read(v_ILINE, re_real);
      re_int  := integer(round(re_real * real(2**(DATA_WIDTH))));
      im_int  := 0;
      result(i).re := std_logic_vector(to_signed(re_int, IP_WIDTH));
      result(i).im := std_logic_vector(to_signed(im_int, IP_WIDTH));
      i := i+1;
    end loop;
    return result;
    file_close(inFile);
  end function create_ip_table;
 
  -- Call the function to create the input data
  constant IP_DATA : T_IP_TABLE := create_ip_table;
 
  -----------------------------------------------------------------------
  -- Testbench signals
  -----------------------------------------------------------------------
 
  -- Communication between processes regarding DUT configuration
  type T_DO_CONFIG is (NONE, IMMEDIATE, AFTER_START, DONE);
  shared variable do_config : T_DO_CONFIG := NONE;  -- instruction for driving config slave channel
  type T_CFG_FWD_INV is (FWD, INV);
  signal cfg_fwd_inv : T_CFG_FWD_INV := FWD;
  type T_CFG_SCALE_SCH is (ZERO, DEFAULT);
  signal cfg_scale_sch : T_CFG_SCALE_SCH := DEFAULT;
 
  -- Recording output data, for reuse as input data
  signal op_sample       : integer    := 0;    -- output sample number
  signal op_sample_first : std_logic  := '1';  -- indicates first output sample of a frame
  signal ip_frame        : integer    := 0;    -- input / configuration frame number
  signal op_data         : T_IP_TABLE := IP_TABLE_CLEAR;  -- recorded output data
  signal op_frame        : integer    := 0;    -- output frame number (incremented at end of frame output)
 
 
begin
 
  -----------------------------------------------------------------------
  -- Instantiate the DUT
  -----------------------------------------------------------------------
 
  dut : entity work.xfft_0
    port map (
      aclk                        => aclk,
      aresetn                     => aresetn,
      s_axis_config_tvalid        => s_axis_config_tvalid,
      s_axis_config_tready        => s_axis_config_tready,
      s_axis_config_tdata         => s_axis_config_tdata,
      s_axis_data_tvalid          => s_axis_data_tvalid,
      s_axis_data_tready          => s_axis_data_tready,
      s_axis_data_tdata           => s_axis_data_tdata,
      s_axis_data_tlast           => s_axis_data_tlast,
      m_axis_data_tvalid          => m_axis_data_tvalid,
      m_axis_data_tready          => m_axis_data_tready,
      m_axis_data_tdata           => m_axis_data_tdata,
      m_axis_data_tlast           => m_axis_data_tlast,
      event_frame_started         => event_frame_started,
      event_tlast_unexpected      => event_tlast_unexpected,
      event_tlast_missing         => event_tlast_missing,
      event_status_channel_halt   => event_status_channel_halt,
      event_data_in_channel_halt  => event_data_in_channel_halt,
      event_data_out_channel_halt => event_data_out_channel_halt
      );
 
  -----------------------------------------------------------------------
  -- Generate clock
  -----------------------------------------------------------------------
 
  clock_gen : process
  begin
    aclk <= '0';
    wait for CLOCK_PERIOD;
    loop
      aclk <= '0';
      wait for CLOCK_PERIOD/2;
      aclk <= '1';
      wait for CLOCK_PERIOD/2;
    end loop;
  end process clock_gen;
 
  -----------------------------------------------------------------------
  -- Generate data slave channel inputs
  -----------------------------------------------------------------------
 
  data_stimuli : process
 
    -- Variables for random number generation
    variable seed1, seed2 : positive;
    variable rand         : real;
 
    -- Procedure to drive an input sample with specific data
    -- data is the data value to drive on the tdata signal
    -- last is the bit value to drive on the tlast signal
    -- valid_mode defines how to drive TVALID: 0 = TVALID always high, 1 = TVALID low occasionally
    procedure drive_sample ( data       : std_logic_vector(47 downto 0);
                             last       : std_logic;
                             valid_mode : integer := 0 ) is
    begin
      s_axis_data_tdata  <= data;
      s_axis_data_tlast  <= last;
 
      if valid_mode = 1 then
        uniform(seed1, seed2, rand);  -- generate random number
        if rand < 0.25 then
          s_axis_data_tvalid <= '0';
          uniform(seed1, seed2, rand);  -- generate another random number
          wait for CLOCK_PERIOD * integer(round(rand * 4.0));  -- hold TVALID low for up to 4 cycles
          s_axis_data_tvalid <= '1';  -- now assert TVALID
        else
          s_axis_data_tvalid <= '1';
        end if;
      else
        s_axis_data_tvalid <= '1';
      end if;
      loop
        wait until rising_edge(aclk);
        exit when s_axis_data_tready = '1';
      end loop;
      wait for T_HOLD;
      s_axis_data_tvalid <= '0';
    end procedure drive_sample;
 
    -- Procedure to drive an input frame with a table of data
    -- data is the data table containing input data
    -- valid_mode defines how to drive TVALID: 0 = TVALID always high, 1 = TVALID low occasionally
    procedure drive_frame ( data         : T_IP_TABLE;
                            valid_mode   : integer := 0 ) is
      variable samples : integer;
      variable index   : integer;
      variable sample_data : std_logic_vector(47 downto 0);
      variable sample_last : std_logic;
    begin
      samples := data'length;
      index  := 0;
      while index < data'length loop
        -- Look up sample data in data table, construct TDATA value
        sample_data(17 downto 0)  := data(index).re;                  -- real data
        sample_data(23 downto 18) := (others => data(index).re(17));  -- sign-extend
        sample_data(41 downto 24) := data(index).im;                  -- imaginary data
        sample_data(47 downto 42) := (others => data(index).im(17));  -- sign-extend
        -- Construct TLAST's value
        index := index + 1;
        if index >= data'length then
          sample_last := '1';
        else
          sample_last := '0';
        end if;
        -- Drive the sample
        drive_sample(sample_data, sample_last, valid_mode);
      end loop;
    end procedure drive_frame;
 
    variable op_data_saved : T_IP_TABLE;  -- to save a copy of recorded output data
 
 
  begin
 
    -- Drive inputs T_HOLD time after rising edge of clock
    wait until rising_edge(aclk) and aresetn = '1';
    wait for T_HOLD;
 
    -- Drive a frame of input data
    ip_frame <= 1;
    drive_frame(IP_DATA);
 
    -- Allow the result to emerge
    wait until m_axis_data_tlast = '1';
    wait until rising_edge(aclk);
    wait for T_HOLD;
 
    -- Take a copy of the result, to use later as input
    op_data_saved := op_data;
 
    -- Now perform an inverse transform on the result to get back to the original input
    -- Set up the configuration (config_stimuli process handles the config slave channel)
    ip_frame <= 2;
    cfg_fwd_inv <= INV;
    do_config := IMMEDIATE;
    while do_config /= DONE loop
      wait until rising_edge(aclk) and aresetn = '1';
    end loop;
    wait for T_HOLD;
 
    -- Configuration is done.  Set up another configuration to return to forward transforms,
    -- and make the configuration occur as soon as the next frame has begun
    ip_frame <= 3;
    cfg_fwd_inv <= FWD;
    do_config := AFTER_START;
 
    -- Now drive the input data, using the output data of the last frame
    drive_frame(op_data);
    wait until m_axis_data_tlast = '1';
    wait until rising_edge(aclk);
    wait for T_HOLD;
 
    -- The frame is complete, and the configuration to forward transforms has already been done,
    -- so drive the input data, using the output data of the last frame,
    -- which is the same as the original input (excepting scaling and finite precision effects).
    -- This time, deassert the data slave channel TVALID occasionally to illustrate AXI handshaking effects:
    -- as the core is configured to use Non Real Time throttle scheme, it will pause when TVALID is low.
    drive_frame(op_data, 1);
 
    -- During the output of this frame, deassert the data master channel TREADY occasionally:
    -- as the core is configured to use Non Real Time throttle scheme, it will pause when TREADY is low.
    wait until m_axis_data_tvalid = '1';
    wait until rising_edge(aclk);
    while m_axis_data_tlast /= '1' loop
      wait for T_HOLD;
      uniform(seed1, seed2, rand);  -- generate random number
      if rand < 0.25 then
        m_axis_data_tready <= '0';
      else
        m_axis_data_tready <= '1';
      end if;
      wait until rising_edge(aclk);
    end loop;
    wait for T_HOLD;
    m_axis_data_tready <= '1';
    wait for CLOCK_PERIOD;
 
    -- Demonstrate use of aresetn to reset the core: start another frame but reset the core before it completes
    ip_frame <= 4;
    drive_frame(IP_DATA);
    wait for CLOCK_PERIOD * 5;
    aresetn <= '0';  -- assert reset (active low)
    wait for CLOCK_PERIOD * 2;  -- hold reset active for 2 cycles, as stated in the FFT Datasheet
    aresetn <= '1';  -- deassert reset
    wait for CLOCK_PERIOD * 5;
 
    -- Now run 4 back-to-back transforms, as quickly as possible.
    -- First queue up 2 configurations: these will be applied successively over the next 2 transforms.
    -- 1st configuration
    ip_frame <= 4;
    cfg_fwd_inv <= FWD;  -- forward transform
    cfg_scale_sch <= DEFAULT;  -- default scaling schedule
    do_config := IMMEDIATE;
    while do_config /= DONE loop
      wait until rising_edge(aclk) and aresetn = '1';
    end loop;
    wait for T_HOLD;
 
    -- 2nd configuration: same as 1st, except:
    ip_frame <= 5;
    cfg_fwd_inv <= INV;  -- inverse transform
    cfg_scale_sch <= ZERO;  -- no scaling
    do_config := IMMEDIATE;
    while do_config /= DONE loop
      wait until rising_edge(aclk) and aresetn = '1';
    end loop;
    wait for T_HOLD;
 
    -- Drive the 1st data frame
    drive_frame(IP_DATA);
 
    -- Request a 3rd configuration, to be sent after 2nd data frame starts
    ip_frame <= 6;
    cfg_fwd_inv <= FWD;  -- forward transform
    cfg_scale_sch <= ZERO;  -- no scaling
    do_config := AFTER_START;
 
    -- Drive the 2nd data frame
    drive_frame(op_data_saved);
 
    -- Request a 4th configuration, to be sent after 3rd data frame starts: same as 3rd, except:
    ip_frame <= 7;
    cfg_fwd_inv <= INV;  -- inverse transform
    cfg_scale_sch <= DEFAULT;  -- default scaling schedule
    do_config := AFTER_START;
 
    -- Drive the 3rd data frame
    drive_frame(IP_DATA);
 
    -- Drive the 4th data frame
    drive_frame(op_data_saved);
 
    -- Wait until all the output data from all frames has been produced
    wait until op_frame = 7;
    wait for CLOCK_PERIOD * 10;
 
    -- End of test
    report "Not a real failure. Simulation finished successfully. Test completed successfully" severity failure;
    wait;
 
  end process data_stimuli;
 
  -----------------------------------------------------------------------
  -- Generate config slave channel inputs
  -----------------------------------------------------------------------
 
  config_stimuli : process
    variable scale_sch : std_logic_vector(9 downto 0);
  begin
 
    -- Drive a configuration when requested by data_stimuli process
    wait until rising_edge(aclk) and aresetn = '1';
    while do_config = NONE or do_config = DONE loop
      wait until rising_edge(aclk) and aresetn = '1';
    end loop;
 
    -- If the configuration is requested to occur after the next frame starts, wait for that event
    if do_config = AFTER_START then
      wait until event_frame_started = '1';
      wait until rising_edge(aclk) and aresetn = '1';
    end if;
 
    -- Drive inputs T_HOLD time after rising edge of clock
    wait for T_HOLD;
 
    -- Construct the config slave channel TDATA signal
    s_axis_config_tdata <= (others => '0');  -- clear unused bits
    -- Format the transform direction
    if cfg_fwd_inv = FWD then
      s_axis_config_tdata(0) <= '1';  -- forward
    elsif cfg_fwd_inv = INV then
      s_axis_config_tdata(0) <= '0';  -- inverse
    end if;
    -- Format the scaling schedule
    if cfg_scale_sch = ZERO then  -- no scaling
      scale_sch := (others => '0');
    elsif cfg_scale_sch = DEFAULT then  -- default scaling, for largest magnitude output with no overflow guaranteed
      scale_sch(1 downto 0) := "11";  -- largest scaling at first stage
      for s in 2 to 4 loop
        scale_sch(s*2-1 downto s*2-2) := "10";  -- less scaling at later stages
      end loop;
      scale_sch(9 downto 8) := "01";  -- least scaling at last stage
    end if;
    s_axis_config_tdata(10 downto 1) <= scale_sch;
 
    -- Drive the transaction on the config slave channel
    s_axis_config_tvalid <= '1';
    loop
      wait until rising_edge(aclk);
      exit when s_axis_config_tready = '1';
    end loop;
    wait for T_HOLD;
    s_axis_config_tvalid <= '0';
 
    -- Tell the data_stimuli process that the configuration has been done
    do_config := DONE;
 
  end process config_stimuli;
 
  -----------------------------------------------------------------------
  -- Record outputs, to use later as inputs for another frame
  -----------------------------------------------------------------------
 
  record_outputs : process (aclk)
    variable index : integer := 0;
 
  begin
    if rising_edge(aclk) then
      if aresetn = '0' then  -- aresetn is active low
        op_sample_first <= '1';
        op_sample       <= 0;
        op_data         <= IP_TABLE_CLEAR;
      elsif m_axis_data_tvalid = '1' and m_axis_data_tready = '1' then
        -- Record output data such that it can be used as input data
        index := op_sample;
        op_data(index).re <= m_axis_data_tdata(17 downto 0);
        op_data(index).im <= m_axis_data_tdata(41 downto 24);
        -- Increment output sample counter
        if m_axis_data_tlast = '1' then  -- end of output frame: reset sample counter and increment frame counter
          op_sample <= 0;
          op_frame <= op_frame + 1;
          op_sample_first <= '1';  -- for next output frame
        else
          op_sample_first <= '0';
          op_sample <= op_sample + 1;
        end if;
      end if;
    end if;
  end process record_outputs;
 
  -----------------------------------------------------------------------
  -- Check outputs
  -----------------------------------------------------------------------
 
  check_outputs : process
    variable check_ok : boolean := true;
    -- Previous values of data master channel signals
    variable m_data_tvalid_prev : std_logic := '0';
    variable m_data_tready_prev : std_logic := '0';
    variable m_data_tdata_prev  : std_logic_vector(47 downto 0) := (others => '0');
  begin
 
    -- Check outputs T_STROBE time after rising edge of clock
    wait until rising_edge(aclk);
    wait for T_STROBE;
 
    -- Do not check the output payload values, as this requires a numerical model
    -- which would make this demonstration testbench unwieldy.
    -- Instead, check the protocol of the data master channel:
    -- check that the payload is valid (not X) when TVALID is high
    -- and check that the payload does not change while TVALID is high until TREADY goes high
 
    if m_axis_data_tvalid = '1' and aresetn = '1' then
      if is_x(m_axis_data_tdata) then
        report "ERROR: m_axis_data_tdata is invalid when m_axis_data_tvalid is high" severity error;
        check_ok := false;
      end if;
 
      if m_data_tvalid_prev = '1' and m_data_tready_prev = '0' then  -- payload must be the same as last cycle
        if m_axis_data_tdata /= m_data_tdata_prev then
          report "ERROR: m_axis_data_tdata changed while m_axis_data_tvalid was high and m_axis_data_tready was low" severity error;
          check_ok := false;
        end if;
      end if;
 
    end if;
 
    assert check_ok
      report "ERROR: terminating test with failures." severity failure;
 
    -- Record payload values for checking next clock cycle
    if check_ok then
      m_data_tvalid_prev  := m_axis_data_tvalid;
      m_data_tready_prev  := m_axis_data_tready;
      m_data_tdata_prev   := m_axis_data_tdata;
    end if;
 
  end process check_outputs;
 
  -----------------------------------------------------------------------
  -- Assign TDATA / TUSER fields to aliases, for easy simulator waveform viewing
  -----------------------------------------------------------------------
 
  -- Config slave channel alias signals
  s_axis_config_tdata_fwd_inv    <= s_axis_config_tdata(0);
  s_axis_config_tdata_scale_sch  <= s_axis_config_tdata(10 downto 1);
 
  -- Data slave channel alias signals
  s_axis_data_tdata_re           <= s_axis_data_tdata(17 downto 0);
  s_axis_data_tdata_im           <= s_axis_data_tdata(41 downto 24);
 
  -- Data master channel alias signals
  m_axis_data_tdata_re           <= m_axis_data_tdata(17 downto 0);
  m_axis_data_tdata_im           <= m_axis_data_tdata(41 downto 24);
 
end tb;



While simulating it, am getting the following errors :

failed to open VHDL file 'in.txt' in mode 'r' [C:/Users/HP/fftfinal/fftfinal.srcs/sources_1/imports/xfft_0/demo_tb/tb_xfft_0.vhd:175]
ERROR: [XSIM 43-3321] Static elaboration of top level VHDL design unit tb_xfft_0 in library work failed.

How do I solve it?
Please help.
 
Last edited by a moderator:

You dont add the text file to the project, you need to ensure the path to the file is correct from the VHDL, relative to where the working folder is.
Vivado has a truly terrible path structure, where it has the base path as folders that do not exist until you create the project or start the runs. You probably need to put the file in

<your folder>/<bld folder>/<your_project_name>.runs/sim_1/

Or have the VHDL search relative to this folder for the file.
 

I was able to solve that problem by inputting data using a memory file.
However my output of fft core is not proper.
I modified the test bench provided by Xilinx to get FFT output of input file.
This is the code

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use STD.textio.all;
 
entity tb_xfft_0 is
end tb_xfft_0;
 
architecture tb of tb_xfft_0 is
 
  -----------------------------------------------------------------------
  -- Timing constants
  -----------------------------------------------------------------------
  constant CLOCK_PERIOD : time := 100 ns;
  constant T_HOLD       : time := 10 ns;
  constant T_STROBE     : time := CLOCK_PERIOD - (1 ns);
 
  -----------------------------------------------------------------------
  -- DUT signals
  -----------------------------------------------------------------------
 
  -- General signals
  signal aclk                        : std_logic := '0';  -- the master clock
  signal aresetn                     : std_logic := '1';  -- synchronous active low reset
 
  -- Config slave channel signals
  signal s_axis_config_tvalid        : std_logic := '0';  -- payload is valid
  signal s_axis_config_tready        : std_logic := '1';  -- slave is ready
  signal s_axis_config_tdata         : std_logic_vector(15 downto 0) := (others => '0');  -- data payload
 
  -- Data slave channel signals
  signal s_axis_data_tvalid          : std_logic := '0';  -- payload is valid
  signal s_axis_data_tready          : std_logic := '1';  -- slave is ready
  signal s_axis_data_tdata           : std_logic_vector(47 downto 0) := (others => '0');  -- data payload
  signal s_axis_data_tlast           : std_logic := '0';  -- indicates end of packet
 
  -- Data master channel signals
  signal m_axis_data_tvalid          : std_logic := '0';  -- payload is valid
  signal m_axis_data_tready          : std_logic := '1';  -- slave is ready
  signal m_axis_data_tdata           : std_logic_vector(47 downto 0) := (others => '0');  -- data payload
  signal m_axis_data_tlast           : std_logic := '0';  -- indicates end of packet
 
  -- Event signals
  signal event_frame_started         : std_logic := '0';
  signal event_tlast_unexpected      : std_logic := '0';
  signal event_tlast_missing         : std_logic := '0';
  signal event_status_channel_halt   : std_logic := '0';
  signal event_data_in_channel_halt  : std_logic := '0';
  signal event_data_out_channel_halt : std_logic := '0';
 
  -----------------------------------------------------------------------
  -- Aliases for AXI channel TDATA and TUSER fields
  -- These are a convenience for viewing data in a simulator waveform viewer.
  -- If using ModelSim or Questa, add "-voptargs=+acc=n" to the vsim command
  -- to prevent the simulator optimizing away these signals.
  -----------------------------------------------------------------------
 
  -- Config slave channel alias signals
  signal s_axis_config_tdata_fwd_inv      : std_logic                    := '0';              -- forward or inverse
  signal s_axis_config_tdata_scale_sch    : std_logic_vector(9 downto 0) := (others => '0');  -- scaling schedule
 
  -- Data slave channel alias signals
  signal s_axis_data_tdata_re             : std_logic_vector(17 downto 0) := (others => '0');  -- real data
  signal s_axis_data_tdata_im             : std_logic_vector(17 downto 0) := (others => '0');  -- imaginary data
 
  -- Data master channel alias signals
  signal m_axis_data_tdata_re             : std_logic_vector(17 downto 0) := (others => '0');  -- real data
  signal m_axis_data_tdata_im             : std_logic_vector(17 downto 0) := (others => '0');  -- imaginary data
 
  -----------------------------------------------------------------------
  -- Constants, types and functions to create input data
  -----------------------------------------------------------------------
 
  constant IP_WIDTH    : integer := 18;
  constant MAX_SAMPLES : integer := 2**9;  -- maximum number of samples in a frame
  type T_IP_SAMPLE is record
    re : std_logic_vector(IP_WIDTH-1 downto 0);
    im : std_logic_vector(IP_WIDTH-1 downto 0);
  end record;
  type T_IP_TABLE is array (0 to MAX_SAMPLES-1) of T_IP_SAMPLE;
 
  -- Zeroed input data table, for reset and initialization
   constant IP_TABLE_CLEAR : T_IP_TABLE := (others => (re => (others => '0'),
                                                      im => (others => '0')));
 
  -- Function to generate input data table
  -- Data is a complex sinusoid exp(-jwt) with a frequency 2.6 times the frame size
  -- added to another with a lower magnitude and a higher frequency
  
   impure function create_ip_table return T_IP_TABLE is
    variable result : T_IP_TABLE;
    variable theta  : real;
    variable theta2 : real;
    variable re_real : real;
    variable im_real : real;
    variable re_int : integer;
    variable im_int : integer;
    constant DATA_WIDTH : integer := 16;
    file inFile : text;
    variable i : integer;
    variable v_ILINE     : line;
    begin
      file_open(inFile, "in.mem",read_mode); 
      for i in 0 to MAX_SAMPLES-1 loop
      theta :=0.0;
      theta2 :=0.0;
      readline(inFile, v_ILINE);
      read(v_ILINE, re_real);
      re_int  := integer(round(re_real));
      im_int  := 0;
      result(i).re := std_logic_vector(to_signed(re_int, IP_WIDTH));
      result(i).im := std_logic_vector(to_signed(im_int, IP_WIDTH));
     
    end loop;
    return result;
    file_close(inFile);
  end function create_ip_table;
 
  -- Call the function to create the input data
  constant IP_DATA : T_IP_TABLE := create_ip_table;
 
  -----------------------------------------------------------------------
  -- Testbench signals
  -----------------------------------------------------------------------
 
  -- Communication between processes regarding DUT configuration
  type T_DO_CONFIG is (NONE, IMMEDIATE, AFTER_START, DONE);
  shared variable do_config : T_DO_CONFIG := NONE;  -- instruction for driving config slave channel
  type T_CFG_FWD_INV is (FWD, INV);
  signal cfg_fwd_inv : T_CFG_FWD_INV := FWD;
  type T_CFG_SCALE_SCH is (ZERO, DEFAULT);
  signal cfg_scale_sch : T_CFG_SCALE_SCH := DEFAULT;
    signal op_sample       : integer    := 0;    -- output sample number
    signal op_sample_first : std_logic  := '1';  -- indicates first output sample of a frame
    signal ip_frame        : integer    := 0;    -- input / configuration frame number
    signal op_data         : T_IP_TABLE := IP_TABLE_CLEAR;  -- recorded output data
    signal op_frame        : integer    := 0;    -- output frame number (incremented at end of frame output)
 
 
 
 
begin
 
  -----------------------------------------------------------------------
  -- Instantiate the DUT
  -----------------------------------------------------------------------
 
  dut : entity work.xfft_0
    port map (
      aclk                        => aclk,
      aresetn                     => aresetn,
      s_axis_config_tvalid        => s_axis_config_tvalid,
      s_axis_config_tready        => s_axis_config_tready,
      s_axis_config_tdata         => s_axis_config_tdata,
      s_axis_data_tvalid          => s_axis_data_tvalid,
      s_axis_data_tready          => s_axis_data_tready,
      s_axis_data_tdata           => s_axis_data_tdata,
      s_axis_data_tlast           => s_axis_data_tlast,
      m_axis_data_tvalid          => m_axis_data_tvalid,
      m_axis_data_tready          => m_axis_data_tready,
      m_axis_data_tdata           => m_axis_data_tdata,
      m_axis_data_tlast           => m_axis_data_tlast,
      event_frame_started         => event_frame_started,
      event_tlast_unexpected      => event_tlast_unexpected,
      event_tlast_missing         => event_tlast_missing,
      event_status_channel_halt   => event_status_channel_halt,
      event_data_in_channel_halt  => event_data_in_channel_halt,
      event_data_out_channel_halt => event_data_out_channel_halt
      );
 
  -----------------------------------------------------------------------
  -- Generate clock
  -----------------------------------------------------------------------
 
  clock_gen : process
  begin
    aclk <= '0';
    wait for CLOCK_PERIOD;
    loop
      aclk <= '0';
      wait for CLOCK_PERIOD/2;
      aclk <= '1';
      wait for CLOCK_PERIOD/2;
    end loop;
  end process clock_gen;
 
  -----------------------------------------------------------------------
  -- Generate data slave channel inputs
  -----------------------------------------------------------------------
 
  data_stimuli : process
 
    -- Variables for random number generation
    variable seed1, seed2 : positive;
    variable rand         : real;
 
    -- Procedure to drive an input sample with specific data
    -- data is the data value to drive on the tdata signal
    -- last is the bit value to drive on the tlast signal
    -- valid_mode defines how to drive TVALID: 0 = TVALID always high, 1 = TVALID low occasionally
    procedure drive_sample ( data       : std_logic_vector(47 downto 0);
                             last       : std_logic;
                             valid_mode : integer := 0 ) is
    begin
      s_axis_data_tdata  <= data;
      s_axis_data_tlast  <= last;
 
      if valid_mode = 1 then
        uniform(seed1, seed2, rand);  -- generate random number
        if rand < 0.25 then
          s_axis_data_tvalid <= '0';
          uniform(seed1, seed2, rand);  -- generate another random number
          wait for CLOCK_PERIOD * integer(round(rand * 4.0));  -- hold TVALID low for up to 4 cycles
          s_axis_data_tvalid <= '1';  -- now assert TVALID
        else
          s_axis_data_tvalid <= '1';
        end if;
      else
        s_axis_data_tvalid <= '1';
      end if;
      loop
        wait until rising_edge(aclk);
        exit when s_axis_data_tready = '1';
      end loop;
      wait for T_HOLD;
      s_axis_data_tvalid <= '0';
    end procedure drive_sample;
 
    -- Procedure to drive an input frame with a table of data
    -- data is the data table containing input data
    -- valid_mode defines how to drive TVALID: 0 = TVALID always high, 1 = TVALID low occasionally
    procedure drive_frame ( data         : T_IP_TABLE;
                            valid_mode   : integer := 0 ) is
      variable samples : integer;
      variable index   : integer;
      variable sample_data : std_logic_vector(47 downto 0);
      variable sample_last : std_logic;
    begin
      samples := data'length;
      index  := 0;
      while index < data'length loop
        -- Look up sample data in data table, construct TDATA value
        sample_data(17 downto 0)  := data(index).re;                  -- real data
        sample_data(23 downto 18) := (others => data(index).re(17));  -- sign-extend
        sample_data(41 downto 24) := data(index).im;                  -- imaginary data
        sample_data(47 downto 42) := (others => data(index).im(17));  -- sign-extend
        -- Construct TLAST's value
        index := index + 1;
        if index >= data'length then
          sample_last := '1';
        else
          sample_last := '0';
        end if;
        -- Drive the sample
        drive_sample(sample_data, sample_last, valid_mode);
      end loop;
    end procedure drive_frame;
 
    variable op_data_saved : T_IP_TABLE;  -- to save a copy of recorded output data
 
 
  begin
 
    -- Drive inputs T_HOLD time after rising edge of clock
    wait until rising_edge(aclk) and aresetn = '1';
    wait for T_HOLD;
 
    -- Drive a frame of input data
 
    drive_frame(IP_DATA);
 
    -- Allow the result to emerge
    wait until m_axis_data_tlast = '1';
    wait until rising_edge(aclk);
    wait for T_HOLD;
     op_data_saved := op_data; 
 
    wait for CLOCK_PERIOD * 10;
 
    -- End of test
    report "Not a real failure. Simulation finished successfully. Test completed successfully" severity failure;
    wait;
 
  end process data_stimuli;
 
  -----------------------------------------------------------------------
  -- Generate config slave channel inputs
  -----------------------------------------------------------------------
 
  config_stimuli : process
    variable scale_sch : std_logic_vector(9 downto 0);
  begin
 
    -- Drive a configuration when requested by data_stimuli process
    wait until rising_edge(aclk) and aresetn = '1';
    while do_config = NONE or do_config = DONE loop
      wait until rising_edge(aclk) and aresetn = '1';
    end loop;
 
    -- If the configuration is requested to occur after the next frame starts, wait for that event
    if do_config = AFTER_START then
      wait until event_frame_started = '1';
      wait until rising_edge(aclk) and aresetn = '1';
    end if;
 
    -- Drive inputs T_HOLD time after rising edge of clock
    wait for T_HOLD;
 
    -- Construct the config slave channel TDATA signal
    s_axis_config_tdata <= (others => '0');  -- clear unused bits
    -- Format the transform direction
    if cfg_fwd_inv = FWD then
      s_axis_config_tdata(0) <= '1';  -- forward
    elsif cfg_fwd_inv = INV then
      s_axis_config_tdata(0) <= '0';  -- inverse
    end if;
    -- Format the scaling schedule
    if cfg_scale_sch = ZERO then  -- no scaling
      scale_sch := (others => '0');
    elsif cfg_scale_sch = DEFAULT then  -- default scaling, for largest magnitude output with no overflow guaranteed
      scale_sch(1 downto 0) := "11";  -- largest scaling at first stage
      for s in 2 to 4 loop
        scale_sch(s*2-1 downto s*2-2) := "10";  -- less scaling at later stages
      end loop;
      scale_sch(9 downto 8) := "01";  -- least scaling at last stage
    end if;
    s_axis_config_tdata(10 downto 1) <= scale_sch;
 
    -- Drive the transaction on the config slave channel
    s_axis_config_tvalid <= '1';
    loop
      wait until rising_edge(aclk);
      exit when s_axis_config_tready = '1';
    end loop;
    wait for T_HOLD;
    s_axis_config_tvalid <= '0';
 
    -- Tell the data_stimuli process that the configuration has been done
    do_config := DONE;
 
  end process config_stimuli;
 
  -----------------------------------------------------------------------
  -- Record outputs, to use later as inputs for another frame
  -----------------------------------------------------------------------
 
  record_outputs : process (aclk)
    variable index : integer := 0;
 
  begin
    if rising_edge(aclk) then
      if aresetn = '0' then  -- aresetn is active low
        op_sample_first <= '1';
        op_sample       <= 0;
        op_data         <= IP_TABLE_CLEAR;
      elsif m_axis_data_tvalid = '1' and m_axis_data_tready = '1' then
        -- Record output data such that it can be used as input data
        index := op_sample;
        op_data(index).re <= m_axis_data_tdata(17 downto 0);
        op_data(index).im <= m_axis_data_tdata(41 downto 24);
        -- Increment output sample counter
        if m_axis_data_tlast = '1' then  -- end of output frame: reset sample counter and increment frame counter
          op_sample <= 0;
          op_frame <= op_frame + 1;
          op_sample_first <= '1';  -- for next output frame
        else
          op_sample_first <= '0';
          op_sample <= op_sample + 1;
        end if;
      end if;
    end if;
  end process record_outputs;
 
  -----------------------------------------------------------------------
  -- Check outputs
  -----------------------------------------------------------------------
 
  check_outputs : process
    variable check_ok : boolean := true;
    -- Previous values of data master channel signals
    variable m_data_tvalid_prev : std_logic := '0';
    variable m_data_tready_prev : std_logic := '0';
    variable m_data_tdata_prev  : std_logic_vector(47 downto 0) := (others => '0');
  begin
 
    -- Check outputs T_STROBE time after rising edge of clock
    wait until rising_edge(aclk);
    wait for T_STROBE;
 
    -- Do not check the output payload values, as this requires a numerical model
    -- which would make this demonstration testbench unwieldy.
    -- Instead, check the protocol of the data master channel:
    -- check that the payload is valid (not X) when TVALID is high
    -- and check that the payload does not change while TVALID is high until TREADY goes high
 
    if m_axis_data_tvalid = '1' and aresetn = '1' then
      if is_x(m_axis_data_tdata) then
        report "ERROR: m_axis_data_tdata is invalid when m_axis_data_tvalid is high" severity error;
        check_ok := false;
      end if;
 
      if m_data_tvalid_prev = '1' and m_data_tready_prev = '0' then  -- payload must be the same as last cycle
        if m_axis_data_tdata /= m_data_tdata_prev then
          report "ERROR: m_axis_data_tdata changed while m_axis_data_tvalid was high and m_axis_data_tready was low" severity error;
          check_ok := false;
        end if;
      end if;
 
    end if;
 
    assert check_ok
      report "ERROR: terminating test with failures." severity failure;
 
    -- Record payload values for checking next clock cycle
    if check_ok then
      m_data_tvalid_prev  := m_axis_data_tvalid;
      m_data_tready_prev  := m_axis_data_tready;
      m_data_tdata_prev   := m_axis_data_tdata;
    end if;
 
  end process check_outputs;
 
  -----------------------------------------------------------------------
  -- Assign TDATA / TUSER fields to aliases, for easy simulator waveform viewing
  -----------------------------------------------------------------------
 
  -- Config slave channel alias signals
  s_axis_config_tdata_fwd_inv    <= s_axis_config_tdata(0);
  s_axis_config_tdata_scale_sch  <= s_axis_config_tdata(10 downto 1);
 
  -- Data slave channel alias signals
  s_axis_data_tdata_re           <= s_axis_data_tdata(17 downto 0);
  s_axis_data_tdata_im           <= s_axis_data_tdata(41 downto 24);
 
  -- Data master channel alias signals
  m_axis_data_tdata_re           <= m_axis_data_tdata(17 downto 0);
  m_axis_data_tdata_im           <= m_axis_data_tdata(41 downto 24);
 
end tb;



I don't know why output is not proper.
Please advise.
 
Last edited by a moderator:

However my output of fft core is not proper.
Xilinx has a proper documentation to the FFT core and its use with the test-bench/example_design it provides. Please read that *carefully* to see where you are deviating.
 

Error while instantiating xilinx fft core

I was trying to instantiate xilinx fft core inside a verilog module.
While simulating it is throwing an error :
syntax error near xfft_0.

Here is my code:

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 08/07/2018 02:52:59 PM
// Design Name: 
// Module Name: tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
 
 
module tb(
    m_axis_data_tdata_re, 
    m_axis_data_tdata_im,
    aclk,
    aresetn,
    s_axis_data_tvalid,
    s_axis_config_tvalid,
    s_axis_data_tdata,
    s_axis_data_tlast 
     
    );
    parameter CLOCK_PERIOD=100;
    parameter T_HOLD      =10;
    parameter T_STROBE    = CLOCK_PERIOD - 1 ;
    input aclk;
    input aresetn;  
    input s_axis_config_tvalid; 
    input s_axis_data_tvalid; 
    input [19:0] s_axis_data_tdata;
    reg m_axis_data_tready;
    output reg [19:0] m_axis_data_tdata_re;
    output reg [19:0] m_axis_data_tdata_im;
   
    input s_axis_data_tlast;
    
    wire m_axis_data_tlast ;
    reg [7:0] s_axis_config_tdata;   
    reg event_frame_started;
    reg event_tlast_unexpected;
    reg event_tlast_missing;
    reg event_status_channel_halt;
    reg event_data_in_channel_halt ;
    reg event_data_out_channel_halt;
                  
    wire [0:47] m_axis_data_tdata;
    wire  s_axis_config_tready;
    wire  s_axis_data_tready;
    wire m_axis_data_tvalid;
    
    always @(posedge aclk)
    begin 
        if(aresetn)
        begin
        s_axis_config_tdata            <=8'b0; 
        m_axis_data_tready             <=1;
        event_frame_started            <=0;
        event_tlast_unexpected         <=0;
        event_tlast_missing            <=0;
        event_status_channel_halt      <=0;
        event_data_in_channel_halt     <=0;
        event_data_out_channel_halt    <=0;
        end
        else if(s_axis_config_tvalid)
        begin
              xfft_0 uut(
              aclk,
              aresetn,
              s_axis_config_tvalid,
              s_axis_config_tready,
              s_axis_config_tdata,
              s_axis_data_tvalid,
              s_axis_data_tready,
              s_axis_data_tdata,
              s_axis_data_tlast,
              m_axis_data_tvalid,
              m_axis_data_tready,
              m_axis_data_tdata,
              m_axis_data_tlast,
              event_frame_started,
              event_tlast_unexpected,
              event_tlast_missing,
              event_status_channel_halt,
              event_data_in_channel_halt,
              event_data_out_channel_halt
              );
       
            if(m_axis_data_tvalid==1)
            begin
                m_axis_data_tdata_re <= m_axis_data_tdata[19:0];
                m_axis_data_tdata_im <= m_axis_data_tdata[43:24];
            end
        end
    end  
 
 
 
endmodule



Please help
 

Re: Error while instantiating xilinx fft core

You can't instantiate modules within an always block. Instantiated modules are not behavioral code they are like putting ICs on a board.
 
I simulated Xilinx fft core.
I am using fixed point unscaled version with convergent rounding.
I compared the output with that from MATLAB.
The maximum difference I found is 16.
Why is there such huge roundoff error?
 

Be careful when you compare MATLAB fft and Xilinx fft core results.
Look for MATLAB fft function that is equivalent to Xilinx fft implementation - then you will get results that would be different at +/-1 bit level.
 
There is only one fft function in MATLAB right?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top