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] Innput data at 30MHz and Output data at 80 MHz. How to do it usgin A cyclone IV?

Status
Not open for further replies.

flote21

Advanced Member level 1
Joined
Jan 22, 2014
Messages
411
Helped
1
Reputation
2
Reaction score
3
Trophy points
1,298
Activity points
5,595
Hello guys!

i am using a sensor which is providind data at 40MHz and after doing a data processing of this data. And my ETH IP is working at 80 MHz. I am working with Altera Cyclone IV FPGA and I would like to know if the only posibility to adapt this speed is using a DCFIFIO with a input clock of 40MHZ and a output clock of 80MHz. Or maybe there is another solution much more easier?

Thanks!
 

It's not clear what you want to achieve.

Sampled data with a rate of 30 MS/s (or is it 40 MS/s ?) can be transferred to a 80 MHz clock domain by a DCFIFO, but the data rate of 30 MS/s is maintained on an average. For a sample rate conversion, an interpolating filter would be needed.
 
Use a FIFO, it's the easiest option.

Not using a FIFO would require a much better understanding of the design. If the 40MHz and 80 MHz are synchronous you can play tricks with the clock domain transfer of the data with the correct timing constraints, but I would advise against that unless you know what you are doing.

If the input clock is actually 30MHz then you should definitely use a FIFO as it would be significantly more complicated to perform the transfers without a FIFO. I've used various buffering schemes with double buffering registers and distributed memory when I've had designs that would not have fit if I made the clock domain crossing for a large number of channels as FIFOs, but I wouldn't recommend doing that unless you know exactly what you are doing.

It's been a while since I've used the Altera Ethernet IP, so I don't recall if the data needs to be sent as a contiguous packet payload or if there is internal buffering in the IP already. If you have to supply the entire payload contiguously then the FIFO will have to be used with an almost empty level set to the packet payload length.
 
you are right ads-ee, the data must sent as a continuous pay-load, so I need a fifo like you described. I will try all this stuff and I will tell u how was it...
Thanks!
 

Hello again people!!

I am testing my design with the FIFO and something strange is happening. The DCFIFO is able to buffering all the pixels for almost all the FRAME RATES that I want to set up. And here is the issue, for example when I set up a frame rate = 300Hz, data output is right, all the pixels are buffered, however when I set up a FRAME RATE = 301, I am losing the last 4 pixels of every frame and then the data output is not right. I am checking the fifo full flags and there is not any overflow. Here is the code:

Reminn: Incomming data at 30 MHZ and output data at 80MHZ

HTML:
  FIFO_WR <= (VID_F_SOI or VID_F_SOL or VID_F_DAV);  
  FIFO_IN <= VID_F_SOI &  VID_F_SOL &  VID_F_DAV & VID_F_DATA & VID_F_DARK;
  
  -- Clock Domain Crossing FIFO
  -- Show Ahead Mode, Output Registered
  -- Data Width 32 bits, Fifo Depth = 2**FIFO_DEPTH
  i_O_FIFO : DCFIFO
    generic map (                               
      CLOCKS_ARE_SYNCHRONIZED => "FALSE",       
      INTENDED_DEVICE_FAMILY  => "Cyclone V",   
      LPM_NUMWORDS            => 2**FIFO_DEPTH, 
      LPM_SHOWAHEAD           => "ON",          
      LPM_TYPE                => "dcfifo",      
      LPM_WIDTH               => FIFO_WIDTH,    
      LPM_WIDTHU              => FIFO_DEPTH,    
      OVERFLOW_CHECKING       => "ON",          
      UNDERFLOW_CHECKING      => "ON",          
      USE_EAB                 => "ON",            
      WRSYNC_DELAYPIPE        =>3,           
      RDSYNC_DELAYPIPE        => 3,          
      READ_ACLR_SYNCH         => "ON",         
      WRITE_ACLR_SYNCH        => "ON"          
    )                                           
    port map (                                  
      ACLR    => VID_I_RST,                     
      WRCLK   => VID_I_CLK,                     
      WRREQ   => FIFO_WR  ,                     
      DATA    => FIFO_IN  ,                     
      WRUSEDW => open     ,                     
      WRFULL  => FIFO_FUL ,                     
      RDCLK   => VID_O_CLK,                     
      RDEMPTY => FIFO_EMP ,                    
      RDREQ   => FIFO_RD  ,                     
      Q       => FIFO_OUT ,                      
      RDUSEDW => open  
    );

  -- FIFO Full Error Detection      
  process(VID_I_CLK, VID_I_RST)
  begin
    if VID_I_RST = '1' then
      FIFO_FUL_ERR <= '0';
    elsif rising_edge(VID_I_CLK) then
      if FIFO_FUL = '1' and FIFO_WR = '1' then
        FIFO_FUL_ERR <= '1';
      end if;
    end if;
  end process;	  
            
  -- Checking FIFO Flags  
  process(VID_I_CLK)
  begin
    if rising_edge(VID_I_CLK) then
      assert not ( FIFO_WR = '1' and FIFO_FUL = '1' )
      report "[BINNING_4PIX] WRITE while i_O_FIFO Full !!!" severity failure;
    end if;
  end process;
  process(VID_O_CLK)
  begin
    if rising_edge(VID_O_CLK) then
      assert not ( FIFO_RD = '1' and FIFO_EMP = '1' )
      report "[BINNING_4PIX] READ while i_O_FIFO Empty !!!" severity failure;
    end if;
  end process;


Which values should I configure in the generics WRSYNC_DELAYPIPE and RDSYNC_DELAYPIPE ???

Thanks
 

3 means you are adding 3 stages of synchronization pipelining. That should be left alone.

I doubt that the problem is the FIFO. You state that you are missing the last 4 pixels are the pixels 8-bit (i.e. one 32-bit word)? As you didn't supply any of the code used to write/read the FIFO I can only assume you are probably not writing the last word. Did you simulate your code or are you doing the code/download/test/doesn't_work/code/download/test/doesn't_work/.....routine? Save yourself some time and run a simulation on the design and debug it in the simulation, you'll probably find you missed the last write.
 

right. i was missing some info before.

the dimension of the fifo is 256words x 64bits. I have to buffering 1564 pixels of 64 bits. and clkin of the fifo is 30 MHz and clk out 80mhz. as I told you it is possible to change the frame rate of the incoming pixels from 250hz to 800hz.for the most of the frame rates I got the 1564 pixels. but the are some frame rates combinations where I lost always the 4 last pixels delivering then 1560 pixels....
I simulated with modelsim and I also debugged with signal tap and I checked that at the input of the fifo I definitely have 1364pixels for all the frame rates... the incoming data to the fifo is sync with the 30mhz. however one pixel of 64 bits is written in the fifo every 6 clocks of 30mhz.
I also could check that changing the generics mentioned in my previous post from 3 to 4. I have less frame rates where all 1364 pixels are provided. but I still have this issue with some of them.furthermore I checked that if the number of 30mhz clocks between 2 consecutive pixels is higher or lower the number of pixels at the output of the fifo is less or more and I was not able to find any relation and to explain why this is happening...
any idea?


QUOTE=ads-ee;1413550]3 means you are adding 3 stages of synchronization pipelining. That should be left alone.

I doubt that the problem is the FIFO. You state that you are missing the last 4 pixels are the pixels 8-bit (i.e. one 32-bit word)? As you didn't supply any of the code used to write/read the FIFO I can only assume you are probably not writing the last word. Did you simulate your code or are you doing the code/download/test/doesn't_work/code/download/test/doesn't_work/.....routine? Save yourself some time and run a simulation on the design and debug it in the simulation, you'll probably find you missed the last write.[/QUOTE]
 

the dimension of the fifo is 256words x 64bits. I have to buffering 1564 pixels of 64 bits.
That's not what is in your post, the comment shows 32-bit wide FIFO. That is why you should always post ALL of your code not just some random snippet with no context! Where are the signal declarations?

I also could check that changing the generics mentioned in my previous post from 3 to 4. I have less frame rates where all 1364 pixels are provided.
What do you mean by this? If you change the synchronization scheme from 3 registers to 4 (increasing flag latency!) you have more cases where the pixel count is wrong!?

That is a design problem with handling the FIFO! You obviously didn't do a very thorough job of checking the design in modelsim.

I'm just wasting my time with this thread.
 

I am sorry I was writtting from my phone and I was not able to post my code. Here it is



Code dot - [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
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
------------------------
entity BINNING_4PIX is
------------------------
  generic (  
    DEBUG     : boolean := false;  -- True for Simu only : will manage smaller image
    DATA_BITS : positive := 12       -- Data Bus Width
  );
  port (    
    FPGA_MODE   : in  std_logic_vector(2 downto 0);            -- FPGA data processing modes
     RAW_DATA    : in  std_logic;                               -- No Binning modes flag
     SHIFT_COL   : in  std_logic_vector(15 downto 0);           -- To shift columns
     LINE_ID     : in  std_logic;                               -- Odd/Even line is first?
     MEM_INIT_OK : in std_logic;                                -- when = '1' all the memory are ready to start the data processing
    -- Video Input Parallel Interface, sync'ed on VID_I_CLK
    VID_I_CLK   : in  std_logic;                                -- Video  Input Clock
    VID_I_RST   : in  std_logic;                                -- Video  Input Reset (Async Active High)
    VID_I_SOI   : in  std_logic;                                -- Video  Input Start Of Image
    VID_I_SOL   : in  std_logic;                                -- Video  Input Start Of Line
    VID_I_EOI   : in  std_logic;                                -- Video  Input   End Of Image
    VID_I_DARK  : in  std_logic;                                -- Video  Input Dark Image '1', Bright '0'
    VID_I_DAV   : in  std_logic;                                -- Video  Input Pixel Data Valid Flag
    VID_I_DATA  : in  std_logic_vector(4*DATA_BITS-1 downto 0); -- Video  Input Pixel Data : 4 pixels
     -- Misc
     FIFO_FUL_ERR : out std_logic;                               -- Fifo Out Full Error 
    -- Video Output Parallel Interface, sync'ed on VID_O_CLK
    VID_O_CLK   : in  std_logic;                                -- Video Output Clock
    VID_O_RST   : in  std_logic;                                -- Video Output Reset (Async Active High)
    VID_O_XSIZE : in  std_logic_vector(12 downto 0);            -- Video Output X Size
    VID_O_YSIZE : in  std_logic_vector(12 downto 0);            -- Video Output Y Size
    VID_O_SOI   : out std_logic;                                -- Video Output Start of Image
    VID_O_SOL   : out std_logic;                                -- Video Output Start of Line
    VID_O_EOI   : out std_logic;                                -- Video Output   End of Image
    VID_O_DARK  : out std_logic;                                -- Video Output Dark Image '1', Bright '0'
    VID_O_DAV   : out std_logic;                                -- Video Output Pixels Data Valid Flag
    VID_O_DATA  : out std_logic_vector(63 downto 0);            -- Video Output Pixels Data (4 pixels)
    VID_O_XCNT  : out std_logic_vector(12 downto 0);            -- Video Output Pixels Counter (0 for 1st pixel)
    VID_O_YCNT  : out std_logic_vector(12 downto 0)             -- Video Output  Lines Counter (0 for 1st line )
  );
-------------------------------------
end entity BINNING_4PIX;
-------------------------------------
 
-------------------------------------
architecture RTL of BINNING_4PIX is
-------------------------------------
 
  -- signal limits
   signal H_ACTIV_SIZE_RGB_BIN  : positive;  
   signal V_ACTIV_SIZE_RGB_BIN  : positive;
    
  -- --------------------------
  --  Altera Single Clock FIFO
  -- --------------------------
  component SCFIFO is
    generic (
      ADD_RAM_OUTPUT_REGISTER : string;
      INTENDED_DEVICE_FAMILY  : string;
      LPM_NUMWORDS            : natural;
      LPM_SHOWAHEAD           : string;
      LPM_TYPE                : string;
      LPM_WIDTH               : natural;
      LPM_WIDTHU              : natural;
      OVERFLOW_CHECKING       : string;
      UNDERFLOW_CHECKING      : string;
      USE_EAB                 : string
    );
    port (
      ACLR  : in  std_logic ;
      CLOCK : in  std_logic ;
      SCLR  : in  std_logic ;
      WRREQ : in  std_logic ;
      DATA  : in  std_logic_vector(LPM_WIDTH -1 downto 0);
      FULL  : out std_logic ;
      USEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
      EMPTY : out std_logic ;
      RDREQ : in  std_logic ;
      Q     : out std_logic_vector(LPM_WIDTH -1 downto 0)
    );
  end component SCFIFO;
  
  -- FIFO to store one input line 1
  constant FIFO_LINE_1_DEPTH : positive := 9;    
  constant FIFO_LINE_1_WSIZE : positive := 48;   
  signal FIFO_LINE_1_CLR   : std_logic;
  signal FIFO_LINE_1_WR    : std_logic;
  signal FIFO_LINE_1_IN    : std_logic_vector(FIFO_LINE_1_WSIZE-1 downto 0);
  signal FIFO_LINE_1_FUL   : std_logic;
  signal FIFO_LINE_1_NB    : std_logic_vector(FIFO_LINE_1_DEPTH-1 downto 0);
  signal FIFO_LINE_1_EMP   : std_logic;
  signal FIFO_LINE_1_RD    : std_logic;
  signal FIFO_LINE_1_RD_s  : std_logic;
  signal FIFO_LINE_1_OUT   : std_logic_vector(FIFO_LINE_1_WSIZE-1 downto 0);     
  -- FIFO to store one input line 2
  constant FIFO_LINE_2_DEPTH : positive := 9;    
  constant FIFO_LINE_2_WSIZE : positive := 48;   
  signal FIFO_LINE_2_CLR   : std_logic;
  signal FIFO_LINE_2_WR    : std_logic;
  signal FIFO_LINE_2_IN    : std_logic_vector(FIFO_LINE_2_WSIZE-1 downto 0);
  signal FIFO_LINE_2_FUL   : std_logic;
  signal FIFO_LINE_2_NB    : std_logic_vector(FIFO_LINE_2_DEPTH-1 downto 0);
  signal FIFO_LINE_2_EMP   : std_logic;
  signal FIFO_LINE_2_EMP_1x: std_logic;  
  signal FIFO_LINE_2_RD    : std_logic;
  signal FIFO_LINE_2_RD_s  : std_logic;
  signal FIFO_LINE_2_OUT   : std_logic_vector(FIFO_LINE_2_WSIZE-1 downto 0);      
  
  -- Other signals
  -- 
  type BIN_FSM_t is ( s_IDLE, s_BINNING  );
  signal BIN_FSM : BIN_FSM_t;  
  signal RAW_DATAs      : std_logic;
  signal RAW_DATAss     : std_logic;
  signal LINE_BIN       : std_logic;  
  signal BIN_SEL        : unsigned(7 downto 0);  
  signal BIN_CNT        : integer RANGE 0 to 8000;
  signal BIN_SAVE       : unsigned(DATA_BITS-1 downto 0);    
  signal PIX_LINE1_SAVE : unsigned(DATA_BITS-1 downto 0);    
  signal PIX_LINE2_SAVE : unsigned(DATA_BITS-1 downto 0);        
  signal VID_I_YCNT     : unsigned(VID_O_YCNT'range);  
  --  
  signal BIN_DAV        : std_logic;
  signal BIN_DATA       : std_logic_vector(63 downto 0);      
  constant RESIZE_BIN_DATAs : positive := 12;            
  signal BIN_DATAs      : std_logic_vector(4*RESIZE_BIN_DATAs-1 downto 0);      
  signal VID_F_SOI   : std_logic;
  signal VID_F_SOL   : std_logic;  
  signal VID_F_DARK  : std_logic;
  signal VID_F_DAV   : std_logic;
  signal VID_F_DATA  : std_logic_vector(63 downto 0);   
  --  
  signal VID_O_SOIi  : std_logic;
  signal VID_O_SOLi  : std_logic;
  signal VID_O_EOIi  : std_logic;
  signal VID_O_DARKi : std_logic;  
  signal VID_O_DAVi  : std_logic;
  signal VID_O_XCNTi : unsigned(VID_O_XCNT'range);
  signal VID_O_YCNTi : unsigned(VID_O_YCNT'range);
  signal RAW_DATA_O  : std_logic;  
 
  -- --------------------------
  --  Altera Dual Clock FIFO
  -- --------------------------
  component DCFIFO is
    generic (
      CLOCKS_ARE_SYNCHRONIZED : string;
      INTENDED_DEVICE_FAMILY  : string;
      LPM_NUMWORDS            : natural;
      LPM_SHOWAHEAD           : string;
      LPM_TYPE                : string;
      LPM_WIDTH               : natural;
      LPM_WIDTHU              : natural;
      OVERFLOW_CHECKING       : string;
      UNDERFLOW_CHECKING      : string;
      USE_EAB                 : string;
      WRSYNC_DELAYPIPE        : natural;
      RDSYNC_DELAYPIPE        : natural;
      WRITE_ACLR_SYNCH        : string;
      READ_ACLR_SYNCH         : string
    );
    port (
      ACLR    : in  std_logic;
      WRCLK   : in  std_logic;
      WRREQ   : in  std_logic;
      DATA    : in  std_logic_vector(LPM_WIDTH -1 downto 0);
       WRUSEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
      WRFULL  : out std_logic;
      RDCLK   : in  std_logic;
      RDEMPTY : out std_logic;
       RDUSEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
      RDREQ   : in  std_logic;
      Q       : out std_logic_vector(LPM_WIDTH -1 downto 0)
    );
  end component DCFIFO;   
  
  constant FIFO_DEPTH : positive := 8;  
  constant FIFO_WIDTH : positive := VID_F_DATA'length+1+1+1+1;  -- DATA + SOI + SOL + DAV + Dark  
  signal FIFO_WR      : std_logic;
  signal FIFO_IN      : std_logic_vector(FIFO_WIDTH-1 downto 0);
  signal FIFO_FUL     : std_logic;
  signal FIFO_EMP     : std_logic;
  signal FIFO_RD      : std_logic;
  signal FIFO_OUT     : std_logic_vector(FIFO_WIDTH-1 downto 0);
 
 
  
-------
begin
-------   
 
  LIMITS_proC : process(VID_I_CLK)  
  begin
   if rising_edge(VID_I_CLK) then  
        if not DEBUG then
            H_ACTIV_SIZE_RGB_BIN  <= H_ACTIV_SIZE_RGB_6RTDI_REAL_BIN;
            V_ACTIV_SIZE_RGB_BIN  <= V_ACTIV_SIZE_RGB_6RTDI_REAL_BIN;
        else
            H_ACTIV_SIZE_RGB_BIN  <= H_ACTIV_SIZE_RGB_6RTDI_SIMU_BIN;
            V_ACTIV_SIZE_RGB_BIN  <= V_ACTIV_SIZE_RGB_6RTDI_SIMU_BIN;
        end if;
    end if;
  end process;
 
 
    
 
  -- -------------------------------
  -- FIFO LINE 1
  -- -------------------------------
  FIFO_LINE_1_CLR <= VID_I_SOI or VID_I_RST;  
--  FIFO_LINE_1_WR  <= VID_I_DAV and LINE_BIN and not RAW_DATAss when (VID_I_YCNT < 3 and MEM_INIT_OK = '1') else '0';
  FIFO_LINE_1_WR  <= VID_I_DAV and LINE_BIN and not RAW_DATAss when (VID_I_YCNT < 3) else '0';
  FIFO_LINE_1_IN  <= VID_I_DATA;
    
  -- FIFO to store one incoming lines of pixels  
  i_FIFO_LINE_1 : SCFIFO
    generic map (
      ADD_RAM_OUTPUT_REGISTER => "ON",
      INTENDED_DEVICE_FAMILY  => "Cyclone IV",
      LPM_NUMWORDS            => 2**FIFO_LINE_1_DEPTH,
      LPM_SHOWAHEAD           => "ON",
      LPM_TYPE                => "SCFIFO",
      LPM_WIDTH               => FIFO_LINE_1_WSIZE,
      LPM_WIDTHU              => FIFO_LINE_1_DEPTH,
      OVERFLOW_CHECKING       => "ON",
      UNDERFLOW_CHECKING      => "ON",
      USE_EAB                 => "ON"
    )
    port map (
      ACLR  => FIFO_LINE_1_CLR ,
      CLOCK => VID_I_CLK    ,
      SCLR  => FIFO_LINE_1_CLR ,
      WRREQ => FIFO_LINE_1_WR  ,
      DATA  => FIFO_LINE_1_IN  ,
      FULL  => FIFO_LINE_1_FUL ,
      USEDW => FIFO_LINE_1_NB  ,
      EMPTY => FIFO_LINE_1_EMP ,
      RDREQ => FIFO_LINE_1_RD  ,
      Q     => FIFO_LINE_1_OUT
    );
        
  FIFO_LINE_1_RD <= FIFO_LINE_1_RD_s and not FIFO_LINE_1_EMP;    
  
  -- Checking FIFO_LINE_1 Flags  
  process(VID_I_CLK)
  begin
    if rising_edge(VID_I_CLK) then
      assert not ( FIFO_LINE_1_WR = '1' and FIFO_LINE_1_FUL = '1' )
      report "[BINNING_4PIX] WRITE while i_O_FIFO_LINE_1 Full !!!" severity failure;
    end if;
  end process;
  process(VID_I_CLK)
  begin
    if rising_edge(VID_I_CLK) then
      assert not ( FIFO_LINE_1_RD = '1' and FIFO_LINE_1_EMP = '1' )
      report "[BINNING_4PIX] READ while i_O_FIFO_LINE_1 Empty !!!" severity failure;
    end if;
  end process; 
  
  -- -------------------------------
  -- FIFO LINE 2
  -- -------------------------------
  FIFO_LINE_2_CLR <= VID_I_SOI or VID_I_RST;  
--  FIFO_LINE_2_WR  <= VID_I_DAV and not LINE_BIN and not RAW_DATAss when (VID_I_YCNT < 3 and MEM_INIT_OK = '1') else '0';
  FIFO_LINE_2_WR  <= VID_I_DAV and not LINE_BIN and not RAW_DATAss when (VID_I_YCNT < 3) else '0';  
  FIFO_LINE_2_IN  <= VID_I_DATA;
    
  -- FIFO to store one incoming lines of pixels  
  i_FIFO_LINE_2 : SCFIFO
    generic map (
      ADD_RAM_OUTPUT_REGISTER => "ON",
      INTENDED_DEVICE_FAMILY  => "Cyclone IV",
      LPM_NUMWORDS            => 2**FIFO_LINE_2_DEPTH,
      LPM_SHOWAHEAD           => "ON",
      LPM_TYPE                => "SCFIFO",
      LPM_WIDTH               => FIFO_LINE_2_WSIZE,
      LPM_WIDTHU              => FIFO_LINE_2_DEPTH,
      OVERFLOW_CHECKING       => "ON",
      UNDERFLOW_CHECKING      => "ON",
      USE_EAB                 => "ON"
    )
    port map (
      ACLR  => FIFO_LINE_2_CLR ,
      CLOCK => VID_I_CLK    ,
      SCLR  => FIFO_LINE_2_CLR ,
      WRREQ => FIFO_LINE_2_WR  ,
      DATA  => FIFO_LINE_2_IN  ,
      FULL  => FIFO_LINE_2_FUL ,
      USEDW => FIFO_LINE_2_NB  ,
      EMPTY => FIFO_LINE_2_EMP ,
      RDREQ => FIFO_LINE_2_RD  ,
      Q     => FIFO_LINE_2_OUT
    );
        
  FIFO_LINE_2_RD <= FIFO_LINE_2_RD_s and not FIFO_LINE_2_EMP;    
  
  -- Checking FIFO_LINE_2 Flags  
  process(VID_I_CLK)
  begin
    if rising_edge(VID_I_CLK) then
      assert not ( FIFO_LINE_2_WR = '1' and FIFO_LINE_2_FUL = '1' )
      report "[BINNING_4PIX] WRITE while i_O_FIFO_LINE_2 Full !!!" severity failure;
    end if;
  end process;
  
  -- Resync on VID_I_CLK
  RAW_DATAs  <= RAW_DATA  when rising_edge(VID_I_CLK);
  RAw_DATAss <= RAW_DATAs when rising_edge(VID_I_CLK);
  
  -- ---------------------------------
  --  RGB Binning process
  -- --------------------------------- 
  BINNING_RGB_proc : process(VID_I_CLK, VID_I_RST)  
  begin
   if VID_I_RST = '1' then      
        VID_F_SOI   <= '0';
      VID_F_SOL   <= '0';
       LINE_BIN    <= '0';
        BIN_SEL    <= (others=> '0');   
       FIFO_LINE_1_RD_s <= '0'; 
        FIFO_LINE_2_RD_s <= '0';    
        BIN_CNT     <= 0;       
      BIN_SEL     <= (others=> '0');        
        BIN_DAV     <= '0';    
        BIN_DATAs   <= (others => '0'); 
    BIN_SAVE    <= (others => '0'); 
        PIX_LINE1_SAVE <= (others => '0');  
        PIX_LINE2_SAVE <= (others => '0');          
        VID_I_YCNT     <= (others => '0');          
        FIFO_LINE_2_EMP_1x <= '1';
        BIN_FSM <= s_IDLE;       
   elsif rising_edge(VID_I_CLK) then                
    
--  if MEM_INIT_OK = '1' then
 
        -- Reading FIFOs + Computing
        FIFO_LINE_1_RD_s <= '0';
        FIFO_LINE_2_RD_s <= '0';
        BIN_DAV <= '0';
        FIFO_LINE_2_EMP_1x <= FIFO_LINE_2_EMP;              
 
      case BIN_FSM is
    
        when s_IDLE =>
                 BIN_CNT     <= 0;      
                 if FIFO_LINE_2_FUL = '1' then
                    BIN_FSM <= s_BINNING;       
                 end if;
          
          -- Read data from the fifo and make the TDI binning.
          -- Between 2 BIN_DAB there is a system_clock GAP to avoid overflow in the FIFO_OUT
          -- After playing a lot with this GAP, it is possible to achieve frame rates until the maximum sensor frame_rate
          -- If the GAP is very small the FIFO_OUT is overflow and it is not possible to reach the maximum sensor frame rate
          -- After some test with Signal TAP this GAP system_clock is ok for this design!
          when s_BINNING =>       
                if BIN_CNT < unsigned(VID_O_XSIZE)  then 
                    BIN_SEL <= BIN_SEL + 1;         
                    if BIN_SEL = 0 then             
                        FIFO_LINE_1_RD_s <= '1';
                        FIFO_LINE_2_RD_s <= '1';
                        --
                        BIN_DATAs <= std_logic_vector(resize(unsigned(FIFO_LINE_2_OUT(35 downto 24)), RESIZE_BIN_DATAs) &                                         
                                                                resize((unsigned(FIFO_LINE_1_OUT(11 downto 0)) + unsigned(FIFO_LINE_2_OUT(23 downto 12)))/2, RESIZE_BIN_DATAs) & 
                                                                resize(unsigned(FIFO_LINE_1_OUT(23 downto 12)), RESIZE_BIN_DATAs) & resize(unsigned(FIFO_LINE_2_OUT(11 downto 00)), RESIZE_BIN_DATAs));         
                        --
                        BIN_DAV <= '1';
                        --
                        BIN_CNT <= BIN_CNT + 4;
                    elsif BIN_SEL = 1 then 
                        BIN_DATAs <= std_logic_vector(resize(unsigned(FIFO_LINE_1_OUT(47 downto 36)), RESIZE_BIN_DATAs) & resize(unsigned(FIFO_LINE_2_OUT(35 downto 24)), RESIZE_BIN_DATAs) &
                                                                resize((unsigned(FIFO_LINE_1_OUT(35 downto 24)) + unsigned(FIFO_LINE_2_OUT(23 downto 12)))/2, RESIZE_BIN_DATAs) &
                                                                resize(unsigned(FIFO_LINE_1_OUT(23 downto 12)), RESIZE_BIN_DATAs));
                        --
                        PIX_LINE1_SAVE <= unsigned(FIFO_LINE_1_OUT(47 downto 36));
                        PIX_LINE2_SAVE <= unsigned(FIFO_LINE_2_OUT(47 downto 36));              
                        BIN_SAVE <=(unsigned(FIFO_LINE_1_OUT(35 downto 24)) + unsigned(FIFO_LINE_2_OUT(47 downto 36)))/2;               
                        --
                        BIN_DAV <= '1';
                        --
                        BIN_CNT <= BIN_CNT + 4;
                    elsif BIN_SEL = 3 then
                        BIN_DATAs <= std_logic_vector(resize((unsigned(FIFO_LINE_1_OUT(11 downto 00)) + PIX_LINE2_SAVE)/2, RESIZE_BIN_DATAs) &
                                                                resize(PIX_LINE1_SAVE, RESIZE_BIN_DATAs) & resize(unsigned(FIFO_LINE_2_OUT(11 downto 00)), RESIZE_BIN_DATAs) & resize(BIN_SAVE,RESIZE_BIN_DATAs));
                        --
                        BIN_DAV <= '1';
                        -- 
                        BIN_CNT <= BIN_CNT + 4;
                    elsif BIN_SEL = 6 then -- Waste time to avoid overflow in the output fifo. Caution! You have to waste the same cycles between BIN_DAV!!!
                        BIN_SEL <= (others=>'0');           
                    end if;
                    --
                else
                    BIN_FSM <= s_IDLE;       
                end if;       
          
        end case;   
 
         -- ******Next Code is mandatory to place it after the TDI binning code!!!!*******
         
         -- Latch Dropping Factors + Reset Counters
        VID_F_SOI  <= '0';
       if VID_I_SOI = '1' then
         VID_F_DARK <= VID_I_DARK;    -- Latch Dark Info                    
           if RAW_DATAss = '1' then     -- No Binning => Delivering RAW pixels
                 VID_F_SOI  <= VID_I_SOI;          
            else                    
                LINE_BIN   <= '0'; -- to be sure that the first incoming line is even line => FIFO 1
                VID_I_YCNT <= (others => '0');          
                VID_F_SOI  <= VID_I_SOI;           
          end if;                       
       end if;       
 
        -- Valid Lines Management        
        VID_F_SOL <= '0';     
        if VID_I_SOL = '1' then   -- New line                     
          if RAW_DATAss = '1' then -- No Binning => Output every line!!!
              VID_F_SOL <= VID_I_SOL;         
            else                         -- Binning!                
                LINE_BIN <= not LINE_BIN; -- switching every SOL => Odd/Even Line Identification...           
                BIN_SEL <= (others=> '0');              
                BIN_SEL  <= (others=> '0');     
                BIN_DAV  <= '0';
                BIN_DATAs <= (others => '0');                                                   
                BIN_SAVE <= (others => '0');                                    
                PIX_LINE1_SAVE <= (others => '0');                                  
                PIX_LINE2_SAVE <= (others => '0');                                  
                VID_I_YCNT     <= VID_I_YCNT + 1;               
                if VID_I_YCNT = 1 then 
                    VID_F_SOL <= VID_I_SOL;                         
                end if;             
          end if;
       end if;      
        
        
        -- ***************************************************************
        
--  end if; -- of MEM_INIT_OK
        
  end if;   -- from the rising_edge(VID_I_CLK)
  end process BINNING_RGB_proc  ;
  
  BIN_DATA(63 downto 48) <= x"0" & BIN_DATAs(47 downto 36);  
  BIN_DATA(47 downto 32) <= x"0" & BIN_DATAs(35 downto 24);  
  BIN_DATA(31 downto 16) <= x"0" & BIN_DATAs(23 downto 12);  
  BIN_DATA(15 downto 00) <= x"0" & BIN_DATAs(11 downto 00);        
  
  -- ---------------------------------
  --  Packing process
  -- ---------------------------------  
  PACK_proc : process(VID_I_CLK, VID_I_RST)  
  begin
    if VID_I_RST = '1' then
      VID_F_DAV      <= '0';
      VID_F_DATA     <= (others => '0');      
    elsif rising_edge(VID_I_CLK) then
 
        VID_F_DAV <= '0';   
 
        -- Binning Enabled!          
        if RAW_DATAss = '0' and BIN_DAV='1' then                        
            VID_F_DATA <= BIN_DATA;             
            VID_F_DAV <= '1';
        end if; 
        
      -- RGB Sensor : All lines are outputted (no lines to add)
      -- and 48bits Data (received from Sensor) sent on one 64bits word
      if RAW_DATAss = '1' and VID_I_DAV = '1' then         
        VID_F_DATA(63 downto 48) <= x"0" & VID_I_DATA(47 downto 36);  
        VID_F_DATA(47 downto 32) <= x"0" & VID_I_DATA(35 downto 24);  
        VID_F_DATA(31 downto 16) <= x"0" & VID_I_DATA(23 downto 12);  
        VID_F_DATA(15 downto 00) <= x"0" & VID_I_DATA(11 downto 00);  
          VID_F_DAV <= '1';
      end if;                   
      
    end if;
  end process PACK_proc;
  
  
  -- -------------------------------------
  -- Clock Domain Crossing to VID_O_CLK
  -- -------------------------------------
    
  -- FIFO to store the 64bits Binning Results
  -- and to perform the Clock Domain Crossing to VID_O_CLK
  -- Show Ahead Mode, Output Registered
  
  -- Writing in FIFO
--  FIFO_WR <= (VID_F_SOI or VID_F_SOL or VID_F_DAV) when MEM_INIT_OK = '1' else '0' ;  
  FIFO_WR <= (VID_F_SOI or VID_F_SOL or VID_F_DAV);  
  FIFO_IN <= VID_F_SOI &  VID_F_SOL &  VID_F_DAV & VID_F_DATA & VID_F_DARK;
  
  -- Clock Domain Crossing FIFO
  -- Show Ahead Mode, Output Registered
  -- Data Width 32 bits, Fifo Depth = 2**FIFO_DEPTH
  i_O_FIFO : DCFIFO
    generic map (                               
      CLOCKS_ARE_SYNCHRONIZED => "FALSE",       
      INTENDED_DEVICE_FAMILY  => "Cyclone V",   
      LPM_NUMWORDS            => 2**FIFO_DEPTH, 
      LPM_SHOWAHEAD           => "ON",          
      LPM_TYPE                => "dcfifo",      
      LPM_WIDTH               => FIFO_WIDTH,    
      LPM_WIDTHU              => FIFO_DEPTH,    
      OVERFLOW_CHECKING       => "ON",          
      UNDERFLOW_CHECKING      => "ON",          
      USE_EAB                 => "ON",            
      WRSYNC_DELAYPIPE        => 3   , 
      RDSYNC_DELAYPIPE        => 3   , 
      READ_ACLR_SYNCH         => "ON",         
      WRITE_ACLR_SYNCH        => "ON"          
    )                                           
    port map (                                  
      ACLR    => VID_I_RST,                     
      WRCLK   => VID_I_CLK,                     
      WRREQ   => FIFO_WR  ,                     
      DATA    =>  FIFO_IN  ,                     
      WRUSEDW => open     ,                     
      WRFULL  => FIFO_FUL ,                     
      RDCLK   => VID_O_CLK,                     
      RDEMPTY => FIFO_EMP ,                    
      RDREQ   => FIFO_RD  ,                     
      Q       => FIFO_OUT ,                      
      RDUSEDW => open  
    );
 
  -- FIFO Full Error Detection      
  process(VID_I_CLK, VID_I_RST)
  begin
    if VID_I_RST = '1' then
      FIFO_FUL_ERR <= '0';
    elsif rising_edge(VID_I_CLK) then
      if FIFO_FUL = '1' and FIFO_WR = '1' then
        FIFO_FUL_ERR <= '1';
      end if;
    end if;
  end process;    
            
  -- Checking FIFO Flags  
  process(VID_I_CLK)
  begin
    if rising_edge(VID_I_CLK) then
      assert not ( FIFO_WR = '1' and FIFO_FUL = '1' )
      report "[BINNING_4PIX] WRITE while i_O_FIFO Full !!!" severity failure;
    end if;
  end process;
  process(VID_O_CLK)
  begin
    if rising_edge(VID_O_CLK) then
      assert not ( FIFO_RD = '1' and FIFO_EMP = '1' )
      report "[BINNING_4PIX] READ while i_O_FIFO Empty !!!" severity failure;
    end if;
  end process;
 
  -- Reading the FIFO
  FIFO_RD <= not FIFO_EMP;
  
  -- Video Outputs
  VID_O_SOIi <= FIFO_RD and FIFO_OUT(67) when rising_edge(VID_O_CLK);
  VID_O_SOLi <= FIFO_RD and FIFO_OUT(66) when rising_edge(VID_O_CLK); 
  VID_O_DAVi <= FIFO_RD and FIFO_OUT(65) when rising_edge(VID_O_CLK);   
  VID_O_DATA <= FIFO_OUT(64 downto 1)    when rising_edge(VID_O_CLK); 
  
  -- --------------------------------------------
  --  Clock Domain Crossing for some Flags 
  -- --------------------------------------------
  i_RAW_DATA_O_CDC : entity WORK.CDC_FLAG
    port map (
      I_CLK  => VID_I_CLK  ,
      I_RST  => VID_I_RST  ,
      I_FLAG => RAW_DATAss ,
      O_CLK  => VID_O_CLK  ,
      O_RST  => VID_O_RST  ,
      O_FLAG => RAW_DATA_O ,
      O_RISE => open       ,
      O_FALL => open
    );       
 
  -- -----------------------------------------------------
  --  Outputting Data on VID_O_CLK clock domain
  -- -----------------------------------------------------
  OUT_proc : process(VID_O_CLK, VID_O_RST)
  begin
    if VID_O_RST = '1' then
      VID_O_DARKi <= '0';
      VID_O_EOIi  <= '0';
      VID_O_XCNTi <= (others => '0');
      VID_O_YCNTi <= (others => '0');       
    elsif rising_edge(VID_O_CLK) then 
 
      -- Dark/Bright Info
      if FIFO_RD = '1' and FIFO_OUT(67) = '1' then  -- SOI 
            VID_O_DARKi <= FIFO_OUT(0);
      end if;
 
      -- Output Pixel Counter
        if RAW_DATA_O = '0' then -- No RAW_DATA 
            if VID_O_DAVi = '1' then
                VID_O_XCNTi <= VID_O_XCNTi + 4; -- 4 pixels per 64 bits
            end if;             
        else                     -- RAW DATA!
            if VID_O_DAVi = '1' then
                VID_O_XCNTi <= VID_O_XCNTi + 4;  -- 4 pixels per 32bits                 
            end if;     
        end if;
 
      -- Output Line Counter
      if VID_O_SOIi = '1' then
        VID_O_YCNTi <= (others => '1');
      elsif VID_O_SOLi = '1' then
        VID_O_XCNTi <= (others => '0');
        VID_O_YCNTi <= VID_O_YCNTi + 1;
      end if;
 
      -- End of Image
      VID_O_EOIi  <= '0';
        if RAW_DATA_O = '0' then -- No RAW_DATA 
            if VID_O_DAVi = '1' and VID_O_XCNTi = unsigned(VID_O_XSIZE)-4 then 
                    VID_O_EOIi <= '1';              
            end if;         
        else                     -- RAW Data 
            if VID_O_DAVi = '1' and 
                VID_O_XCNTi = unsigned(VID_O_XSIZE)-4 and               
                VID_O_YCNTi = unsigned(VID_O_YSIZE)-1 then 
                VID_O_EOIi <= '1';
            end if;                     
        end if;
        
        
      
    end if;
  end process OUT_proc;
 
  VID_O_SOI  <= VID_O_SOIi ;
  VID_O_SOL  <= VID_O_SOLi ;
  VID_O_EOI  <= VID_O_EOIi ;  
  VID_O_DAV  <= VID_O_DAVi ;
  VID_O_XCNT <= std_logic_vector(VID_O_XCNTi);
  VID_O_YCNT <= std_logic_vector(VID_O_YCNTi); 
  VID_O_DARK <= VID_O_DARKi; 
 
  
-----------------------
end architecture RTL;
-----------------------




That's not what is in your post, the comment shows 32-bit wide FIFO. That is why you should always post ALL of your code not just some random snippet with no context! Where are the signal declarations?


What do you mean by this? If you change the synchronization scheme from 3 registers to 4 (increasing flag latency!) you have more cases where the pixel count is wrong!?

That is a design problem with handling the FIFO! You obviously didn't do a very thorough job of checking the design in modelsim.

I'm just wasting my time with this thread.

- - - Updated - - -

I have been debuggin with signal tap and I figured out that there is something wrong in the FIFO_OUT. As you can see in the precoiud code. In the binning process I have to wait some cycles before sending the next pixel to avoid overflow of the FIFO. Maybe here is the problem....But in modelsim everything is working fine. And I dont´have any issue with ouputing less pixels.

I don¨t know. I am a little bit frustated....Anyway thanks for your reply!
 
Last edited by a moderator:

I have been debuggin with signal tap and I figured out that there is something wrong in the FIFO_OUT. As you can see in the precoiud code. In the binning process I have to wait some cycles before sending the next pixel to avoid overflow of the FIFO. Maybe here is the problem....But in modelsim everything is working fine. And I dont´have any issue with ouputing less pixels.
Why are you waiting for anything on the write side? You should write whenever you have data, the FIFO is there to absorb the data and smoothly output it at the new rate. Does this mean you didn't size the FIFO properly?

Grrr, Tabs and VHDL type conversions!
Tabs should be forbidden and one should think about what type they should use to minimize the number of conversions, or use Verilog so you don't have to convert types ;-)
 

Hello,

hehehe you are right, i should use tabs but this design need it.....anyway the main problem is the space. I can't use a biggest FIFO because currently the FPGA is at 98%....This is the reason becasue I can´t provide the data so fast that I would like...If you have another idea about that...

Thanks anyway!



Why are you waiting for anything on the write side? You should write whenever you have data, the FIFO is there to absorb the data and smoothly output it at the new rate. Does this mean you didn't size the FIFO properly?

Grrr, Tabs and VHDL type conversions!
Tabs should be forbidden and one should think about what type they should use to minimize the number of conversions, or use Verilog so you don't have to convert types ;-)
 

Ok O already solved the problem. I was cleaning some flags before ending the 6144 pixels and this was the reason because I lost pixels a the output of the FIFO. Thanks for your help anyway!!!
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top