OpenCores
URL https://opencores.org/ocsvn/sd_mmc_emulator/sd_mmc_emulator/trunk

Subversion Repositories sd_mmc_emulator

[/] [sd_mmc_emulator/] [trunk/] [rtl/] [fifo_pack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jclaytons
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
 
5
package fifo_pack is
6
 
7
  component generic_fifo
8
    generic(
9
      WIDTH          : integer;
10
      DEPTH          : integer;
11
      PF_FULL_POINT  : integer;
12
      PF_FLAG_POINT  : integer;
13
      PF_EMPTY_POINT : integer
14
    );
15
    port (
16
      sys_rst_n     : in  std_logic; -- Asynchronous
17
      sys_clk       : in  std_logic;
18
      sys_clk_en    : in  std_logic;
19
 
20
      reset_i       : in std_logic;  -- Synchronous
21
 
22
      fifo_rd_i     : in  std_logic;
23
      fifo_dout     : out unsigned(WIDTH-1 downto 0);
24
 
25
      fifo_wr_i     : in  std_logic;
26
      fifo_din      : in  unsigned(WIDTH-1 downto 0);
27
 
28
      fifo_full     : out std_logic;
29
      fifo_empty    : out std_logic;
30
      fifo_pf_full  : out std_logic;
31
      fifo_pf_flag  : out std_logic;
32
      fifo_pf_empty : out std_logic
33
    );
34
  end component;
35
 
36
  component fifo_with_fill_level
37
    generic(
38
      WIDTH            : integer;
39
      DEPTH            : integer;
40
      FILL_LEVEL_BITS  : integer; -- Should be at least int(floor(log2(DEPTH))+1.0)
41
      PF_FULL_POINT    : integer;
42
      PF_FLAG_POINT    : integer;
43
      PF_EMPTY_POINT   : integer
44
    );
45
    port (
46
      sys_rst_n       : in  std_logic; -- Asynchronous
47
      sys_clk         : in  std_logic;
48
      sys_clk_en      : in std_logic;
49
 
50
      reset_i         : in std_logic;  -- Synchronous
51
 
52
      fifo_rd_i       : in  std_logic;
53
      fifo_dout       : out unsigned(WIDTH-1 downto 0);
54
 
55
      fifo_wr_i       : in  std_logic;
56
      fifo_din        : in  unsigned(WIDTH-1 downto 0);
57
 
58
      fifo_fill_level : out unsigned(FILL_LEVEL_BITS-1 downto 0);
59
      fifo_full       : out std_logic;
60
      fifo_empty      : out std_logic;
61
      fifo_pf_full    : out std_logic;
62
      fifo_pf_flag    : out std_logic;
63
      fifo_pf_empty   : out std_logic
64
    );
65
  end component;
66
 
67
  component swiss_army_fifo
68
    generic(
69
      USE_BRAM         : integer; -- Set to nonzero value for BRAM, zero for distributed RAM
70
      WIDTH            : integer;
71
      DEPTH            : integer;
72
      FILL_LEVEL_BITS  : integer; -- Should be at least int(floor(log2(DEPTH))+1.0)
73
      PF_FULL_POINT    : integer;
74
      PF_FLAG_POINT    : integer;
75
      PF_EMPTY_POINT   : integer
76
    );
77
    port (
78
      sys_rst_n       : in  std_logic; -- Asynchronous
79
      sys_clk         : in  std_logic;
80
      sys_clk_en      : in  std_logic;
81
 
82
      reset_i         : in std_logic;  -- Synchronous
83
 
84
      fifo_wr_i       : in  std_logic;
85
      fifo_din        : in  unsigned(WIDTH-1 downto 0);
86
 
87
      fifo_rd_i       : in  std_logic;
88
      fifo_dout       : out unsigned(WIDTH-1 downto 0);
89
 
90
      fifo_fill_level : out unsigned(FILL_LEVEL_BITS-1 downto 0);
91
      fifo_full       : out std_logic;
92
      fifo_empty      : out std_logic;
93
      fifo_pf_full    : out std_logic;
94
      fifo_pf_flag    : out std_logic;
95
      fifo_pf_empty   : out std_logic
96
    );
97
  end component;
98
 
99
  component swiss_army_fifo_cdc
100
    generic (
101
      USE_BRAM         : integer; -- Set to nonzero value for BRAM, zero for distributed RAM
102
      WIDTH            : integer;
103
      DEPTH            : integer;
104
      FILL_LEVEL_BITS  : integer; -- Should be at least int(floor(log2(DEPTH))+1.0)
105
      PF_FULL_POINT    : integer;
106
      PF_FLAG_POINT    : integer;
107
      PF_EMPTY_POINT   : integer
108
    );
109
    port (
110
      sys_rst_n        : in  std_logic; -- Asynchronous
111
 
112
      wr_clk_i         : in  std_logic;
113
      wr_clk_en_i      : in  std_logic;
114
      wr_reset_i       : in  std_logic;  -- Synchronous
115
      wr_en_i          : in  std_logic;
116
      wr_dat_i         : in  unsigned(WIDTH-1 downto 0);
117
      wr_fifo_level    : out unsigned(FILL_LEVEL_BITS-1 downto 0);
118
      wr_fifo_full     : out std_logic;
119
      wr_fifo_empty    : out std_logic;
120
      wr_fifo_pf_full  : out std_logic;
121
      wr_fifo_pf_flag  : out std_logic;
122
      wr_fifo_pf_empty : out std_logic;
123
 
124
      rd_clk_i         : in  std_logic;
125
      rd_clk_en_i      : in  std_logic;
126
      rd_reset_i       : in  std_logic;  -- Synchronous
127
      rd_en_i          : in  std_logic;
128
      rd_dat_o         : out unsigned(WIDTH-1 downto 0);
129
      rd_fifo_level    : out unsigned(FILL_LEVEL_BITS-1 downto 0);
130
      rd_fifo_full     : out std_logic;
131
      rd_fifo_empty    : out std_logic;
132
      rd_fifo_pf_full  : out std_logic;
133
      rd_fifo_pf_flag  : out std_logic;
134
      rd_fifo_pf_empty : out std_logic
135
    );
136
  end component;
137
 
138
  component data_packer
139
    generic (
140
      ADR_W          : integer; -- Bit width of snoop address
141
      DATA_IN_W      : integer; -- Maximum in_dat_i word size
142
      LOG2_DATA_IN_W : integer; -- Bit width of in_word_size_i
143
      DATA_OUT_W     : integer; -- Bit width of archive data
144
      FIFO_DEPTH     : integer  -- Size of BRAM FIFO buffer
145
    );
146
    port (
147
 
148
      sys_rst_n  : in std_logic;
149
      sys_clk    : in std_logic;
150
      sys_clk_en : in std_logic;
151
 
152
      -- Input Port
153
      in_dat_i        : in  unsigned(DATA_IN_W-1 downto 0);
154
      in_word_size_i  : in  unsigned(LOG2_DATA_IN_W downto 0);
155
      in_last_word_i  : in  std_logic;
156
      in_adr_i        : in  unsigned(ADR_W-1 downto 0);
157
      in_match_adr_i  : in  unsigned(ADR_W-1 downto 0);
158
      in_cyc_i        : in  std_logic;
159
      in_ack_i        : in  std_logic;
160
 
161
      -- Status
162
      fifo_full_o     : out std_logic;
163
      fifo_reset_i    : in  std_logic;
164
 
165
      -- Output Port
166
      tx_done_i       : in  std_logic;
167
      tx_buff_i       : in  unsigned(ADR_W-1 downto 0);
168
      out_dat_o       : out unsigned(DATA_OUT_W-1 downto 0);
169
      out_last_word_o : out std_logic;
170
      out_cyc_o       : out std_logic;
171
      out_ack_i       : in  std_logic
172
 
173
    );
174
  end component;
175
 
176
end fifo_pack;
177
 
178
 
179
--------------------------------------------------------------
180
-- Generic FIFO
181
--------------------------------------------------------------
182
-- Description:
183
--
184
-- This is a generic, parameterized FIFO module meant to be used
185
-- by logic which is already synchronous to the system clock.
186
-- The input and output use a single system clock.
187
-- Also, there is no handshaking for read/write requests.
188
-- This means that Read/Write request assertions must conform to
189
-- setup & hold times within the system clock domain in order for
190
-- this FIFO to operate correctly.  In other words, don't use
191
-- this FIFO with any inputs originating from a different clock
192
-- domain.
193
--
194
-- This FIFO has a memory array which is not address pipelined,
195
-- and which operates in a "single clock cycle response" mode
196
-- so that writes and reads are completed at the first clock
197
-- edge following the assertion of a read or write request.
198
-- Therefore, the system clock speed must be limited to speeds
199
-- at which the memory can respond in that fashion.  Also, it is
200
-- assumed that the memory array used for the FIFO storage will
201
-- be synthesized with separate input and output data paths, such
202
-- that reads and writes can occur at the same clock edge.  Thus
203
-- there does not need to be a prioritization of read vs. write
204
-- operations, since they can both occur at any given clock edge.
205
--
206
-- NOTES:
207
-- The DEPTH does not need to be a power of two.
208
-- This FIFO has been simulated using DEPTH values down to as
209
-- low as 2.  Depths less than this are considered degenerate 
210
-- cases, and will produce errors.
211
--
212
-- Since the read_row points to the data about to be read,
213
-- the fifo_dout bus contains the read data before a read
214
-- request is actually asserted.  In the case of an empty
215
-- FIFO, the output data bus is driven by the input data bus.
216
--
217
-- If read and write are requested simultaneously to a full
218
-- FIFO, it will remain full and it operates as an N stage
219
-- delay line.
220
--
221
-- If read and write are requested simultaneously to an empty
222
-- FIFO, it will remain empty.  No actual access to storage
223
-- is performed, and the input is simply passed to the output,
224
-- which could be considered to be a zero stage delay line...
225
--
226
-- If the PF empty and full points are set to be overlapping,
227
-- they can conceivably both be active at the same time.
228
-- PF empty values less than zero cause the fifo_pf_empty
229
-- output to stay inactive.  PF full values greater than the
230
-- FIFO depth cause the fifo_pf_full output to behave exactly
231
-- the same as fifo_full.
232
-- There is a third fifo fill level output, fifo_pf_flag.
233
-- It is high only when the FIFO fill level is greater than
234
-- or equal to the desired set value.
235
--
236
 
237
library IEEE;
238
use IEEE.STD_LOGIC_1164.ALL;
239
use IEEE.NUMERIC_STD.ALL;
240
use IEEE.MATH_REAL.ALL;
241
 
242
library work;
243
use work.convert_pack.all;
244
 
245
entity generic_fifo is
246
    generic (
247
      WIDTH          : integer :=  8;
248
      DEPTH          : integer :=  5;
249
      PF_FULL_POINT  : integer :=  3;
250
      PF_FLAG_POINT  : integer :=  2;
251
      PF_EMPTY_POINT : integer :=  0
252
    );
253
    port (
254
      sys_rst_n     : in  std_logic; -- Asynchronous
255
      sys_clk       : in  std_logic;
256
      sys_clk_en    : in  std_logic;
257
 
258
      reset_i       : in std_logic;  -- Synchronous
259
 
260
      fifo_rd_i     : in  std_logic;
261
      fifo_dout     : out unsigned(WIDTH-1 downto 0);
262
 
263
      fifo_wr_i     : in  std_logic;
264
      fifo_din      : in  unsigned(WIDTH-1 downto 0);
265
 
266
      fifo_full     : out std_logic;
267
      fifo_empty    : out std_logic;
268
      fifo_pf_full  : out std_logic;
269
      fifo_pf_flag  : out std_logic;
270
      fifo_pf_empty : out std_logic
271
    );
272
end generic_fifo;
273
 
274
architecture beh of generic_fifo is
275
 
276
  -- Constants
277
  constant FLG_WIDTH : integer := bit_width(DEPTH); -- Bit Width of memory address.  Pointers are one bit wider,
278
                                                    -- so that fill_level can represent the full quantity of 
279
                                                    -- items stored in the FIFO.  This is important when DEPTH
280
                                                    -- is an even power of 2.
281
 
282
  -- Signal Declarations
283
  signal rd_row     : unsigned(FLG_WIDTH downto 0);
284
  signal wr_row     : unsigned(FLG_WIDTH downto 0);
285
  signal fill_level : unsigned(FLG_WIDTH downto 0);
286
 
287
  TYPE memory_array IS
288
    ARRAY (integer RANGE 0 TO DEPTH-1) OF unsigned(WIDTH-1 DOWNTO 0);
289
 
290
  SIGNAL fifo_array: memory_array;
291
 
292
  TYPE STATE_TYPE IS (st_empty, st_data, st_full);
293
 
294
  signal current_state : STATE_TYPE ;
295
 
296
 
297
BEGIN
298
 
299
  fifo_empty    <= '1' when (current_state=st_empty) else '0';
300
  fifo_full     <= '1' when (current_state=st_full)  else '0';
301
  fifo_pf_full  <= '1' when (fill_level>=PF_FULL_POINT or current_state=st_full) else '0';
302
  fifo_pf_flag  <= '1' when (fill_level>=PF_FLAG_POINT) else '0';
303
  fifo_pf_empty <= '1' when (fill_level<=PF_EMPTY_POINT and current_state/=st_full) else '0';
304
 
305
-------------------------
306
-- The FIFO Fill Level
307
fill_level_proc: process(wr_row, rd_row, current_state)
308
  begin
309
    if (current_state=st_empty) then
310
      fill_level <= (others=>'0');
311
    elsif (wr_row>rd_row) then
312
      fill_level <= wr_row-rd_row;
313
    else
314
      fill_level <= DEPTH+(wr_row-rd_row);
315
    end if;
316
  end process;
317
 
318
-------------------------
319
-- The FIFO memory
320
memory: process (sys_clk, sys_rst_n)
321
  variable i : integer;
322
  begin
323
    -- The memory initialization at reset was included for simulation only.
324
    -- It can be removed for synthesis if desired.
325
    if (sys_rst_n='0') then
326
      for i in 0 to DEPTH-1 loop
327
        fifo_array(i) <= (others=>'0');
328
      end loop;
329
    elsif (sys_clk'event and sys_clk = '1') then
330
      if (sys_clk_en='1') then
331
        if ((fifo_wr_i='1' and current_state/=st_full) or
332
            (fifo_wr_i='1' and current_state=st_full and fifo_rd_i='1')) then
333
          fifo_array(to_integer(wr_row(FLG_WIDTH-1 downto 0))) <= fifo_din;
334
        end if;
335
      end if;
336
    end if;
337
  end process;
338
fifo_dout <= fifo_array(to_integer(rd_row(FLG_WIDTH-1 downto 0))) when (current_state/=st_empty)
339
             else fifo_din;
340
 
341
 
342
-------------------------
343
-- The FIFO state machine
344
  clocked : PROCESS(sys_clk, sys_rst_n)
345
 
346
  procedure do_write is
347
  begin
348
    if (wr_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
349
      wr_row <= (others=>'0');
350
    else
351
      wr_row<=wr_row+1;
352
    end if;
353
  end do_write;
354
 
355
  procedure do_read is
356
  begin
357
    if (rd_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
358
      rd_row <= (others=>'0');
359
    else
360
      rd_row<=rd_row+1;
361
    end if;
362
  end do_read;
363
 
364
  begin
365
    if (sys_rst_n = '0') then
366
      current_state <= st_empty;
367
      rd_row   <= (others=>'0');
368
      wr_row   <= (others=>'0');
369
 
370
    elsif (sys_clk'EVENT and sys_clk = '1') then
371
      if (sys_clk_en='1') then
372
        if (reset_i='1') then
373
          current_state <= st_empty;
374
          wr_row <= (others=>'0');
375
          rd_row <= (others=>'0');
376
        else
377
          case current_state is
378
 
379
          when st_empty =>
380
            if (fifo_wr_i='1') then
381
              do_write;
382
              if (fifo_rd_i='0') then
383
                current_state<=st_data;
384
              else
385
                do_read;
386
              end if;
387
            end if;
388
 
389
          when st_data =>
390
            if (fifo_wr_i='1') then
391
              do_write;
392
              if (fifo_rd_i='0' and fill_level=DEPTH-1) then
393
                current_state<=st_full;
394
              end if;
395
            end if;
396
            if (fifo_rd_i='1') then
397
              do_read;
398
              if (fifo_wr_i='0' and fill_level=1) then
399
                current_state<=st_empty;
400
              end if;
401
            end if;
402
 
403
          when st_full =>
404
            if (fifo_rd_i='1') then
405
              do_read;
406
              if (fifo_wr_i='0') then
407
                current_state<=st_data;
408
              else
409
                do_write;
410
              end if;
411
            end if;
412
 
413
          when others => null;
414
          end case;
415
 
416
        end if;
417
      end if; -- sys_clk_en
418
    end if; -- sys_clk
419
  end process clocked;
420
 
421
 
422
end beh;
423
 
424
 
425
--------------------------------------------------------------
426
-- FIFO with fill level output
427
--------------------------------------------------------------
428
-- Description:
429
--
430
-- This is the same as "generic_fifo" but with an additional
431
-- output providing the fifo_fill_level.
432
--
433
-- The bit width of this additional output is set by a generic
434
-- parameter 
435
--
436
--
437
 
438
library IEEE;
439
use IEEE.STD_LOGIC_1164.ALL;
440
use IEEE.NUMERIC_STD.ALL;
441
use IEEE.MATH_REAL.ALL;
442
 
443
library work;
444
use work.convert_pack.all;
445
 
446
entity fifo_with_fill_level is
447
    generic (
448
      WIDTH            : integer :=  8;
449
      DEPTH            : integer :=  5;
450
      FILL_LEVEL_BITS  : integer :=  3; -- Should be at least int(floor(log2(DEPTH))+1.0)
451
      PF_FULL_POINT    : integer :=  3;
452
      PF_FLAG_POINT    : integer :=  2;
453
      PF_EMPTY_POINT   : integer :=  0
454
    );
455
    port (
456
      sys_rst_n       : in  std_logic; -- Asynchronous
457
      sys_clk         : in  std_logic;
458
      sys_clk_en      : in  std_logic;
459
 
460
      reset_i         : in std_logic;  -- Synchronous
461
 
462
      fifo_rd_i       : in  std_logic;
463
      fifo_dout       : out unsigned(WIDTH-1 downto 0);
464
 
465
      fifo_wr_i       : in  std_logic;
466
      fifo_din        : in  unsigned(WIDTH-1 downto 0);
467
 
468
      fifo_fill_level : out unsigned(FILL_LEVEL_BITS-1 downto 0);
469
      fifo_full       : out std_logic;
470
      fifo_empty      : out std_logic;
471
      fifo_pf_full    : out std_logic;
472
      fifo_pf_flag    : out std_logic;
473
      fifo_pf_empty   : out std_logic
474
    );
475
end fifo_with_fill_level;
476
 
477
architecture beh of fifo_with_fill_level is
478
 
479
  -- Constants
480
  constant FLG_WIDTH : integer := bit_width(DEPTH); -- Bit Width of memory address.  Pointers are one bit wider,
481
                                                    -- so that fill_level can represent the full quantity of 
482
                                                    -- items stored in the FIFO.  This is important when DEPTH
483
                                                    -- is an even power of 2.
484
 
485
  -- Signal Declarations
486
  signal rd_row     : unsigned(FLG_WIDTH downto 0);
487
  signal wr_row     : unsigned(FLG_WIDTH downto 0);
488
  signal fill_level : unsigned(FLG_WIDTH downto 0);
489
 
490
  TYPE memory_array IS
491
    ARRAY (integer RANGE 0 TO DEPTH-1) OF unsigned(WIDTH-1 DOWNTO 0);
492
 
493
  SIGNAL fifo_array: memory_array;
494
 
495
  TYPE STATE_TYPE IS (st_empty, st_data, st_full);
496
 
497
  signal current_state : STATE_TYPE ;
498
 
499
 
500
BEGIN
501
 
502
  fifo_empty      <= '1' when (current_state=st_empty) else '0';
503
  fifo_full       <= '1' when (current_state=st_full)  else '0';
504
  fifo_pf_full    <= '1' when (fill_level>=PF_FULL_POINT or current_state=st_full) else '0';
505
  fifo_pf_flag    <= '1' when (fill_level>=PF_FLAG_POINT) else '0';
506
  fifo_pf_empty   <= '1' when (fill_level<=PF_EMPTY_POINT and current_state/=st_full) else '0';
507
  fifo_fill_level <= u_resize(fill_level,FILL_LEVEL_BITS);
508
 
509
-------------------------
510
-- The FIFO Fill Level
511
fill_level_proc: process(wr_row, rd_row, current_state)
512
  begin
513
    if (current_state=st_empty) then
514
      fill_level <= (others=>'0');
515
    elsif (wr_row>rd_row) then
516
      fill_level <= wr_row-rd_row;
517
    else
518
      fill_level <= DEPTH+(wr_row-rd_row);
519
    end if;
520
  end process;
521
 
522
-------------------------
523
-- The FIFO memory
524
memory: process (sys_clk, sys_rst_n)
525
  variable i : integer;
526
  begin
527
    -- The memory initialization at reset was included for simulation only.
528
    -- It can be removed for synthesis if desired.
529
    if (sys_rst_n='0') then
530
      for i in 0 to DEPTH-1 loop
531
        fifo_array(i) <= (others=>'0');
532
      end loop;
533
    elsif (sys_clk'event and sys_clk = '1') then
534
      if (sys_clk_en='1') then
535
        if ((fifo_wr_i='1' and current_state/=st_full) or
536
            (fifo_wr_i='1' and current_state=st_full and fifo_rd_i='1')) then
537
          fifo_array(to_integer(wr_row(FLG_WIDTH-1 downto 0))) <= fifo_din;
538
        end if;
539
      end if;
540
    end if;
541
end process;
542
fifo_dout <= fifo_array(to_integer(rd_row(FLG_WIDTH-1 downto 0))) when (current_state/=st_empty)
543
             else fifo_din;
544
 
545
 
546
-------------------------
547
-- The FIFO state machine
548
  clocked : PROCESS(sys_clk, sys_rst_n)
549
 
550
  procedure do_write is
551
  begin
552
    if (wr_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
553
      wr_row <= (others=>'0');
554
    else
555
      wr_row<=wr_row+1;
556
    end if;
557
  end do_write;
558
 
559
  procedure do_read is
560
  begin
561
    if (rd_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
562
      rd_row <= (others=>'0');
563
    else
564
      rd_row<=rd_row+1;
565
    end if;
566
  end do_read;
567
 
568
  begin
569
    if (sys_rst_n = '0') then
570
      current_state <= st_empty;
571
      rd_row   <= (others=>'0');
572
      wr_row   <= (others=>'0');
573
 
574
    elsif (sys_clk'EVENT and sys_clk = '1') then
575
      if (sys_clk_en='1') then
576
        if (reset_i='1') then
577
          current_state <= st_empty;
578
          wr_row <= (others=>'0');
579
          rd_row <= (others=>'0');
580
        else
581
          case current_state is
582
 
583
          when st_empty =>
584
            if (fifo_wr_i='1') then
585
              do_write;
586
              if (fifo_rd_i='0') then
587
                current_state<=st_data;
588
              else
589
                do_read;
590
              end if;
591
            end if;
592
 
593
          when st_data =>
594
            if (fifo_wr_i='1') then
595
              do_write;
596
              if (fifo_rd_i='0' and fill_level=DEPTH-1) then
597
                current_state<=st_full;
598
              end if;
599
            end if;
600
            if (fifo_rd_i='1') then
601
              do_read;
602
              if (fifo_wr_i='0' and fill_level=1) then
603
                current_state<=st_empty;
604
              end if;
605
            end if;
606
 
607
          when st_full =>
608
            if (fifo_rd_i='1') then
609
              do_read;
610
              if (fifo_wr_i='0') then
611
                current_state<=st_data;
612
              else
613
                do_write;
614
              end if;
615
            end if;
616
 
617
          when others => null;
618
          end case;
619
 
620
        end if;
621
      end if; -- sys_clk_en
622
    end if; -- sys_clk
623
  end process clocked;
624
 
625
 
626
end beh;
627
 
628
 
629
--------------------------------------------------------------
630
-- SWISS ARMY FIFO with fill level output
631
--------------------------------------------------------------
632
-- Description:
633
--
634
-- This is the same as "fifo_with_fill_level" but it has been
635
-- coded to select whether Block RAMs or distributed RAMs are inferred.
636
--
637
-- The bit width of this additional output is set by a generic
638
-- parameter 
639
--
640
-- Note : When USE_BRAM=0, the behavior when reading the FIFO is to
641
--        make read data available immediately during the clock cycle
642
--        in which fifo_rd_i='1'.  When USE_BRAM/=0, then an additional
643
--        clock cycle occurs following the fifo_rd_i pulse, before the
644
--        output data is available.
645
--        Please be aware of this.
646
--
647
--
648
 
649
library IEEE;
650
use IEEE.STD_LOGIC_1164.ALL;
651
use IEEE.NUMERIC_STD.ALL;
652
use IEEE.MATH_REAL.ALL;
653
 
654
library work;
655
use work.convert_pack.all;
656
use work.block_ram_pack.all;
657
 
658
entity swiss_army_fifo is
659
    generic (
660
      USE_BRAM         : integer :=  1; -- Set to nonzero value for BRAM, zero for distributed RAM
661
      WIDTH            : integer :=  8;
662
      DEPTH            : integer :=  5;
663
      FILL_LEVEL_BITS  : integer :=  3; -- Should be at least int(floor(log2(DEPTH))+1.0)
664
      PF_FULL_POINT    : integer :=  3;
665
      PF_FLAG_POINT    : integer :=  2;
666
      PF_EMPTY_POINT   : integer :=  0
667
    );
668
    port (
669
      sys_rst_n       : in  std_logic; -- Asynchronous
670
      sys_clk         : in  std_logic;
671
      sys_clk_en      : in  std_logic;
672
 
673
      reset_i         : in  std_logic;  -- Synchronous
674
 
675
      fifo_wr_i       : in  std_logic;
676
      fifo_din        : in  unsigned(WIDTH-1 downto 0);
677
 
678
      fifo_rd_i       : in  std_logic;
679
      fifo_dout       : out unsigned(WIDTH-1 downto 0);
680
 
681
      fifo_fill_level : out unsigned(FILL_LEVEL_BITS-1 downto 0);
682
      fifo_full       : out std_logic;
683
      fifo_empty      : out std_logic;
684
      fifo_pf_full    : out std_logic;
685
      fifo_pf_flag    : out std_logic;
686
      fifo_pf_empty   : out std_logic
687
    );
688
end swiss_army_fifo;
689
 
690
architecture beh of swiss_army_fifo is
691
 
692
  -- Constants
693
  constant FLG_WIDTH : integer := bit_width(DEPTH); -- Bit Width of memory address.  Pointers are one bit wider,
694
                                                    -- so that fill_level can represent the full quantity of 
695
                                                    -- items stored in the FIFO.  This is important when DEPTH
696
                                                    -- is an even power of 2.
697
 
698
  -- Signal Declarations
699
  signal rd_row     : unsigned(FLG_WIDTH downto 0);
700
  signal wr_row     : unsigned(FLG_WIDTH downto 0);
701
  signal fill_level : unsigned(FLG_WIDTH downto 0);
702
  signal ram_we_a   : std_logic;
703
  signal ram_dout   : unsigned(WIDTH-1 downto 0);
704
 
705
  TYPE STATE_TYPE IS (st_empty, st_data, st_full);
706
  signal current_state : STATE_TYPE ;
707
 
708
  signal bram_dat_b : unsigned(WIDTH-1 downto 0);
709
 
710
BEGIN
711
 
712
  fifo_empty      <= '1' when (current_state=st_empty) else '0';
713
  fifo_full       <= '1' when (current_state=st_full)  else '0';
714
  fifo_pf_full    <= '1' when (fill_level>=PF_FULL_POINT or current_state=st_full) else '0';
715
  fifo_pf_flag    <= '1' when (fill_level>=PF_FLAG_POINT) else '0';
716
  fifo_pf_empty   <= '1' when (fill_level<=PF_EMPTY_POINT and current_state/=st_full) else '0';
717
  fifo_fill_level <= u_resize(fill_level,FILL_LEVEL_BITS);
718
 
719
-------------------------
720
-- The FIFO Fill Level
721
fill_level_proc: process(wr_row, rd_row, current_state)
722
  begin
723
    if (current_state=st_empty) then
724
      fill_level <= (others=>'0');
725
    elsif (wr_row>rd_row) then
726
      fill_level <= wr_row-rd_row;
727
    else
728
      fill_level <= DEPTH+(wr_row-rd_row);
729
    end if;
730
  end process;
731
 
732
-------------------------
733
-- The FIFO memory
734
 
735
-- Port A is the write side.
736
-- Port B is dedicated to reading only.
737
-- The hexfile is used to permit initialization of the RAM
738
 
739
  fifo_ram : swiss_army_ram
740
    generic map(
741
      USE_BRAM  => USE_BRAM,
742
      WRITETHRU => 0, -- Set to nonzero value for writethrough mode
743
      USE_FILE  => 0, -- Set to nonzero value to use INIT_FILE
744
      INIT_VAL  => 0,
745
      INIT_SEL  => 0, -- No generate loop here
746
      INIT_FILE => ".\foo.txt", -- ASCII hexadecimal initialization file name
747
      FIL_WIDTH => 32, -- Bit width of init file lines
748
      ADR_WIDTH => FLG_WIDTH,
749
      DAT_WIDTH => WIDTH
750
    )
751
    port map (
752
       clk_a    => sys_clk,
753
       clk_b    => sys_clk,
754
 
755
       adr_a_i  => wr_row(FLG_WIDTH-1 downto 0),
756
       adr_b_i  => rd_row(FLG_WIDTH-1 downto 0),
757
 
758
       we_a_i   => ram_we_a,
759
       en_a_i   => sys_clk_en,
760
       dat_a_i  => fifo_din,
761
       dat_a_o  => open,
762
 
763
       we_b_i   => '0',
764
       en_b_i   => sys_clk_en,
765
       dat_b_i  => bram_dat_b,
766
       dat_b_o  => ram_dout
767
    );
768
 
769
  bram_dat_b <= (others=>'0');
770
  ram_we_a <= '1' when fifo_wr_i='1' and (current_state/=st_full or (current_state=st_full and fifo_rd_i='1')) else '0';
771
  fifo_dout <= ram_dout;
772
 
773
 
774
-------------------------
775
-- The FIFO state machine
776
  clocked : PROCESS(sys_clk, sys_rst_n)
777
 
778
  procedure do_write is
779
  begin
780
    if (wr_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
781
      wr_row <= (others=>'0');
782
    else
783
      wr_row<=wr_row+1;
784
    end if;
785
  end do_write;
786
 
787
  procedure do_read is
788
  begin
789
    if (rd_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
790
      rd_row <= (others=>'0');
791
    else
792
      rd_row<=rd_row+1;
793
    end if;
794
  end do_read;
795
 
796
  begin
797
    if (sys_rst_n = '0') then
798
      current_state <= st_empty;
799
      rd_row   <= (others=>'0');
800
      wr_row   <= (others=>'0');
801
 
802
    elsif (sys_clk'EVENT and sys_clk = '1') then
803
      if (sys_clk_en='1') then
804
        if (reset_i='1') then
805
          current_state <= st_empty;
806
          wr_row <= (others=>'0');
807
          rd_row <= (others=>'0');
808
        else
809
          case current_state is
810
 
811
          -- When empty, one can only read if also writing
812
          when st_empty =>
813
            if (fifo_wr_i='1') then
814
              do_write;
815
              if (fifo_rd_i='1') then
816
                do_read;
817
              else
818
                current_state<=st_data;
819
              end if;
820
            end if;
821
 
822
          when st_data =>
823
            if (fifo_wr_i='1') then
824
              do_write;
825
              if (fifo_rd_i='0' and fill_level=DEPTH-1) then
826
                current_state<=st_full;
827
              end if;
828
            end if;
829
            if (fifo_rd_i='1') then
830
              do_read;
831
              if (fifo_wr_i='0' and fill_level=1) then
832
                current_state<=st_empty;
833
              end if;
834
            end if;
835
 
836
          -- When full, one can only write if also reading
837
          when st_full =>
838
            if (fifo_rd_i='1') then
839
              do_read;
840
              if (fifo_wr_i='1') then
841
                do_write;
842
              else
843
                current_state<=st_data;
844
              end if;
845
            end if;
846
 
847
          when others => null;
848
          end case;
849
 
850
        end if;
851
      end if; -- sys_clk_en
852
    end if; -- sys_clk
853
  end process clocked;
854
 
855
 
856
end beh;
857
 
858
--------------------------------------------------------------
859
-- SWISS ARMY FIFO "Clock Domain Crossing" version
860
--------------------------------------------------------------
861
-- Description:
862
--
863
-- This is the same as "swiss_army_fifo" but it has been
864
-- coded to include two separate clock domains.  Originally,
865
-- the status signals were all synchronized to their respective
866
-- clock domains.  However, it was taken out so that the user of
867
-- this module must take care as the status signals are not delayed,
868
-- but they are possibly subject to metastability.
869
--
870
-- Note : When USE_BRAM=0, the behavior when reading the FIFO is to
871
--        make read data available immediately during the clock cycle
872
--        in which fifo_rd_i='1'.  When USE_BRAM/=0, then an additional
873
--        clock cycle occurs following the fifo_rd_i pulse, before the
874
--        output data is available.
875
--        Please be aware of this.
876
--
877
--
878
 
879
library IEEE;
880
use IEEE.STD_LOGIC_1164.ALL;
881
use IEEE.NUMERIC_STD.ALL;
882
use IEEE.MATH_REAL.ALL;
883
 
884
library work;
885
use work.convert_pack.all;
886
use work.block_ram_pack.all;
887
 
888
entity swiss_army_fifo_cdc is
889
    generic (
890
      USE_BRAM         : integer :=  1; -- Set to nonzero value for BRAM, zero for distributed RAM
891
      WIDTH            : integer :=  8;
892
      DEPTH            : integer :=  5;
893
      FILL_LEVEL_BITS  : integer :=  3; -- Should be at least int(floor(log2(DEPTH))+1.0)
894
      PF_FULL_POINT    : integer :=  3;
895
      PF_FLAG_POINT    : integer :=  2;
896
      PF_EMPTY_POINT   : integer :=  0
897
    );
898
    port (
899
      sys_rst_n        : in  std_logic; -- Asynchronous
900
 
901
      wr_clk_i         : in  std_logic;
902
      wr_clk_en_i      : in  std_logic;
903
      wr_reset_i       : in  std_logic;  -- Synchronous
904
      wr_en_i          : in  std_logic;
905
      wr_dat_i         : in  unsigned(WIDTH-1 downto 0);
906
      wr_fifo_level    : out unsigned(FILL_LEVEL_BITS-1 downto 0);
907
      wr_fifo_full     : out std_logic;
908
      wr_fifo_empty    : out std_logic;
909
      wr_fifo_pf_full  : out std_logic;
910
      wr_fifo_pf_flag  : out std_logic;
911
      wr_fifo_pf_empty : out std_logic;
912
 
913
      rd_clk_i         : in  std_logic;
914
      rd_clk_en_i      : in  std_logic;
915
      rd_reset_i       : in  std_logic;  -- Synchronous
916
      rd_en_i          : in  std_logic;
917
      rd_dat_o         : out unsigned(WIDTH-1 downto 0);
918
      rd_fifo_level    : out unsigned(FILL_LEVEL_BITS-1 downto 0);
919
      rd_fifo_full     : out std_logic;
920
      rd_fifo_empty    : out std_logic;
921
      rd_fifo_pf_full  : out std_logic;
922
      rd_fifo_pf_flag  : out std_logic;
923
      rd_fifo_pf_empty : out std_logic
924
 
925
    );
926
end swiss_army_fifo_cdc;
927
 
928
architecture beh of swiss_army_fifo_cdc is
929
 
930
  -- Constants
931
  constant FLG_WIDTH : integer := bit_width(DEPTH); -- Bit Width of memory address.  Pointers are one bit wider,
932
                                                    -- so that fill_level can represent the full quantity of 
933
                                                    -- items stored in the FIFO.  This is important when DEPTH
934
                                                    -- is an even power of 2.
935
 
936
  -- Signal Declarations
937
  signal rd_row     : unsigned(FLG_WIDTH downto 0);
938
  signal wr_row     : unsigned(FLG_WIDTH downto 0);
939
  signal fill_level : unsigned(FLG_WIDTH+1 downto 0);
940
  signal ram_we_a   : std_logic;
941
  signal bram_dat_b : unsigned(WIDTH-1 downto 0);
942
 
943
  signal fifo_level       : unsigned(FILL_LEVEL_BITS-1 downto 0);
944
  signal fifo_full        : std_logic;
945
  signal fifo_empty       : std_logic;
946
  signal fifo_pf_full     : std_logic;
947
  signal fifo_pf_flag     : std_logic;
948
  signal fifo_pf_empty    : std_logic;
949
 
950
begin
951
 
952
  fifo_level    <= u_resize(fill_level,FILL_LEVEL_BITS);
953
  fifo_full     <= '1' when (fill_level=DEPTH) else '0';
954
  fifo_empty    <= '1' when (fill_level=0) else '0';
955
  fifo_pf_full  <= '1' when (fill_level>=PF_FULL_POINT) else '0';
956
  fifo_pf_flag  <= '1' when (fill_level>=PF_FLAG_POINT) else '0';
957
  fifo_pf_empty <= '1' when (fill_level<=PF_EMPTY_POINT) else '0';
958
 
959
-------------------------
960
-- The FIFO Fill Level
961
 
962
fill_level <= (others=>'0') when wr_row=rd_row else
963
              ('0' & wr_row)-('0' & rd_row) when wr_row>rd_row else
964
              (2**(FLG_WIDTH+1))+(('0' & wr_row)-('0' & rd_row));
965
 
966
-------------------------
967
-- The FIFO memory
968
 
969
-- Port A is the write side.
970
-- Port B is dedicated to reading only.
971
-- The hexfile is used to permit initialization of the RAM
972
 
973
  fifo_ram : swiss_army_ram
974
    generic map(
975
      USE_BRAM  => USE_BRAM,
976
      WRITETHRU => 0, -- Set to nonzero value for writethrough mode
977
      USE_FILE  => 0, -- Set to nonzero value to use INIT_FILE
978
      INIT_VAL  => 0,
979
      INIT_SEL  => 0, -- No generate loop here
980
      INIT_FILE => ".\foo.txt", -- ASCII hexadecimal initialization file name
981
      FIL_WIDTH => 32, -- Bit width of init file lines
982
      ADR_WIDTH => FLG_WIDTH,
983
      DAT_WIDTH => WIDTH
984
    )
985
    port map (
986
       clk_a    => wr_clk_i,
987
       clk_b    => rd_clk_i,
988
 
989
       adr_a_i  => wr_row(FLG_WIDTH-1 downto 0),
990
       adr_b_i  => rd_row(FLG_WIDTH-1 downto 0),
991
 
992
       we_a_i   => ram_we_a,
993
       en_a_i   => wr_clk_en_i,
994
       dat_a_i  => wr_dat_i,
995
       dat_a_o  => open,
996
 
997
       we_b_i   => '0',
998
       en_b_i   => rd_clk_en_i,
999
       dat_b_i  => bram_dat_b,
1000
       dat_b_o  => rd_dat_o
1001
    );
1002
 
1003
  bram_dat_b <= (others=>'0');
1004
  ram_we_a <= '1' when wr_en_i='1' and fifo_full='0' else '0';
1005
 
1006
-------------------------
1007
-- The FIFO writing process
1008
  wr_proc : PROCESS(wr_clk_i, sys_rst_n)
1009
  begin
1010
    if (sys_rst_n = '0') then
1011
      wr_row   <= (others=>'0');
1012
    elsif (wr_clk_i'event and wr_clk_i = '1') then
1013
      if (wr_clk_en_i='1') then
1014
        if (wr_reset_i='1') then
1015
          wr_row <= (others=>'0');
1016
        else
1017
          if (ram_we_a='1') then
1018
            if (fifo_level=DEPTH) then
1019
              null; -- FIFO is full!  Don't do any writes.
1020
            else
1021
              wr_row <= wr_row+1;
1022
            end if;
1023
          end if;
1024
        end if;
1025
        -- Synchronize all dataflow outputs to the
1026
        -- wr_clk_i clock domain
1027
--        wr_fifo_level    <= fifo_level;
1028
--        wr_fifo_full     <= fifo_full;
1029
--        wr_fifo_empty    <= fifo_empty;
1030
--        wr_fifo_pf_full  <= fifo_pf_full;
1031
--        wr_fifo_pf_flag  <= fifo_pf_flag;
1032
--        wr_fifo_pf_empty <= fifo_pf_empty;
1033
      end if; -- wr_clk_en
1034
    end if; -- wr_clk_i
1035
  end process wr_proc;
1036
  -- Synchronized version removed, because it added an extra clock
1037
  -- cycle of delay.
1038
  -- This may be dangerous in terms of flip-flop metastability
1039
  wr_fifo_level    <= fifo_level;
1040
  wr_fifo_full     <= fifo_full;
1041
  wr_fifo_empty    <= fifo_empty;
1042
  wr_fifo_pf_full  <= fifo_pf_full;
1043
  wr_fifo_pf_flag  <= fifo_pf_flag;
1044
  wr_fifo_pf_empty <= fifo_pf_empty;
1045
 
1046
-------------------------
1047
-- The FIFO reading process
1048
  rd_proc : PROCESS(rd_clk_i, sys_rst_n)
1049
  begin
1050
    if (sys_rst_n = '0') then
1051
      rd_row   <= (others=>'0');
1052
    elsif (rd_clk_i'event and rd_clk_i = '1') then
1053
      if (rd_clk_en_i='1') then
1054
        if (rd_reset_i='1') then
1055
          rd_row <= (others=>'0');
1056
        else
1057
          if (rd_en_i='1' and fifo_empty='0') then
1058
            if (fifo_level=0) then
1059
              null; -- FIFO is empty!  Don't read anything.
1060
            else
1061
              rd_row <= rd_row+1;
1062
            end if;
1063
          end if;
1064
        end if;
1065
        -- Synchronize all dataflow outputs to the
1066
        -- rd_clk_i clock domain
1067
--        rd_fifo_level    <= fifo_level;
1068
--        rd_fifo_full     <= fifo_full;
1069
--        rd_fifo_empty    <= fifo_empty;
1070
--        rd_fifo_pf_full  <= fifo_pf_full;
1071
--        rd_fifo_pf_flag  <= fifo_pf_flag;
1072
--        rd_fifo_pf_empty <= fifo_pf_empty;
1073
      end if; -- rd_clk_en
1074
    end if; -- rd_clk_i
1075
  end process rd_proc;
1076
  -- Synchronized version removed, because it added an extra clock
1077
  -- cycle of delay.
1078
  -- This may be dangerous in terms of flip-flop metastability
1079
  rd_fifo_level    <= fifo_level;
1080
  rd_fifo_full     <= fifo_full;
1081
  rd_fifo_empty    <= fifo_empty;
1082
  rd_fifo_pf_full  <= fifo_pf_full;
1083
  rd_fifo_pf_flag  <= fifo_pf_flag;
1084
  rd_fifo_pf_empty <= fifo_pf_empty;
1085
 
1086
end beh;
1087
 
1088
-------------------------------------------------------------------------------
1089
-- Adjustable Data Packer
1090
-------------------------------------------------------------------------------
1091
--
1092
-- Author: John Clayton
1093
-- Date  : Sep.  04, 2012  Copied code from pcm_tx, and began
1094
--                         updating the description.
1095
--         July  18, 2013  Moved this module from decom_pack into
1096
--                         fifo_pack, and revised the description
1097
--                         to make it sound more generic.
1098
--
1099
-- Description
1100
-------------------------------------------------------------------------------
1101
-- This module is a very simple "bit packer" that takes in data on a parallel
1102
-- bus, along with a word size value that indicates which of the input least
1103
-- significant bits are to be "packed."
1104
--
1105
-- The input port is an address snooper, meaning that it is intended to be used
1106
-- on a bus with other units also receiving the data.  The other units will
1107
-- acknowledge the transfers, and this unit uses that acknowledge to latch the
1108
-- bus data.
1109
--
1110
-- The latched input word is shifted one bit at a time into the output
1111
-- word shift register.  When the output word shift register is full, the
1112
-- output word is latched, and an output cycle is produced.
1113
--
1114
-- This mechanism allows data words of dynamically programmable size to be
1115
-- "snooped up" for any selected data source on the input bus, and then sent 
1116
-- over the ethernet interface as 8-bit values.
1117
--
1118
-- When asserted, the "last word" input causes zero bits to be packed into the
1119
-- output word as needed to finish up a final output cycle.
1120
 
1121
library IEEE;
1122
use IEEE.STD_LOGIC_1164.ALL;
1123
use IEEE.NUMERIC_STD.ALL;
1124
use IEEE.MATH_REAL.ALL;
1125
 
1126
library work;
1127
use work.fifo_pack.all;
1128
use work.convert_pack.all;
1129
 
1130
  entity data_packer is
1131
    generic (
1132
      ADR_W          : integer :=   4; -- Bit width of snoop address
1133
      DATA_IN_W      : integer :=  16; -- Maximum in_dat_i word size
1134
      LOG2_DATA_IN_W : integer :=   4; -- Bit width of in_word_size_i
1135
      DATA_OUT_W     : integer :=   8; -- Bit width of archive data
1136
      FIFO_DEPTH     : integer := 512  -- Size of BRAM FIFO buffer
1137
    );
1138
    port (
1139
 
1140
      sys_rst_n  : in std_logic;
1141
      sys_clk    : in std_logic;
1142
      sys_clk_en : in std_logic;
1143
 
1144
      -- Input Port
1145
      in_dat_i        : in  unsigned(DATA_IN_W-1 downto 0);
1146
      in_word_size_i  : in  unsigned(LOG2_DATA_IN_W downto 0);
1147
      in_last_word_i  : in  std_logic;
1148
      in_adr_i        : in  unsigned(ADR_W-1 downto 0);
1149
      in_match_adr_i  : in  unsigned(ADR_W-1 downto 0);
1150
      in_cyc_i        : in  std_logic;
1151
      in_ack_i        : in  std_logic;
1152
 
1153
      -- Status
1154
      fifo_full_o     : out std_logic;
1155
      fifo_reset_i    : in  std_logic;
1156
 
1157
      -- Output Port
1158
      tx_done_i       : in  std_logic;
1159
      tx_buff_i       : in  unsigned(ADR_W-1 downto 0);
1160
      out_dat_o       : out unsigned(DATA_OUT_W-1 downto 0);
1161
      out_last_word_o : out std_logic;
1162
      out_cyc_o       : out std_logic;
1163
      out_ack_i       : in  std_logic
1164
 
1165
    );
1166
  end data_packer;
1167
 
1168
architecture beh of data_packer is
1169
 
1170
-- Constants
1171
constant FIFO_WIDTH      : natural := (LOG2_DATA_IN_W+1)+DATA_IN_W+1; -- word_size, data, 1 bit last word flag
1172
constant FIFO_FILL_BITS  : natural := timer_width(FIFO_DEPTH);
1173
constant LOG2_DATA_OUT_W : natural := bit_width(DATA_OUT_W);
1174
 
1175
-- Internal signal declarations
1176
signal fifo_din         : unsigned(FIFO_WIDTH-1 downto 0);
1177
signal fifo_dout        : unsigned(FIFO_WIDTH-1 downto 0);
1178
signal fifo_we          : std_logic;
1179
signal fifo_rd          : std_logic;
1180
signal fifo_empty       : std_logic;
1181
signal stored_data      : unsigned(DATA_IN_W-1 downto 0);
1182
signal stored_word_size : unsigned(LOG2_DATA_IN_W downto 0);
1183
signal stored_last_word : std_logic;
1184
 
1185
  -- Modified Miller Code State Machine
1186
type FSM_STATE_TYPE is (TRANSFER, READ_DATA, MAKE_TAIL, WRITE_DATA, WRITE_LAST_DATA);
1187
signal fsm_state        : FSM_STATE_TYPE;
1188
 
1189
 
1190
 
1191
signal bits_in        : unsigned(DATA_IN_W downto 0); -- includes "last word" bit
1192
signal bits_in_count  : unsigned(LOG2_DATA_IN_W downto 0);
1193
signal bit_sel        : unsigned(LOG2_DATA_IN_W downto 0);
1194
signal bits_out       : unsigned(DATA_OUT_W-1 downto 0);
1195
signal bits_out_count : unsigned(LOG2_DATA_OUT_W downto 0);
1196
signal transfer_bit   : std_logic;
1197
signal buffering      : std_logic;
1198
 
1199
begin
1200
 
1201
fifo_din <= in_word_size_i & in_dat_i & in_last_word_i;
1202
fifo_we  <= '1' when (in_adr_i=in_match_adr_i) and in_cyc_i='1' and in_ack_i='1' else '0';
1203
stored_word_size <= fifo_dout(DATA_IN_W+1+LOG2_DATA_IN_W downto DATA_IN_W+1);
1204
stored_data      <= fifo_dout(DATA_IN_W downto 1);
1205
stored_last_word <= fifo_dout(0);
1206
 
1207
packer_fifo : swiss_army_fifo
1208
  generic map(
1209
    USE_BRAM         => 1,
1210
    WIDTH            => FIFO_WIDTH,
1211
    DEPTH            => FIFO_DEPTH,
1212
    FILL_LEVEL_BITS  => FIFO_FILL_BITS,
1213
    PF_FULL_POINT    => FIFO_DEPTH-4,
1214
    PF_FLAG_POINT    => FIFO_DEPTH/2,
1215
    PF_EMPTY_POINT   => 4
1216
  )
1217
  port map(
1218
    sys_rst_n       => sys_rst_n,
1219
    sys_clk         => sys_clk,
1220
    sys_clk_en      => sys_clk_en,
1221
 
1222
    reset_i         => fifo_reset_i,
1223
 
1224
    fifo_wr_i       => fifo_we,
1225
    fifo_din        => fifo_din,
1226
 
1227
    fifo_rd_i       => fifo_rd,
1228
    fifo_dout       => fifo_dout,
1229
 
1230
    fifo_fill_level => open,
1231
    fifo_full       => fifo_full_o,
1232
    fifo_empty      => fifo_empty,
1233
    fifo_pf_full    => open,
1234
    fifo_pf_flag    => open,
1235
    fifo_pf_empty   => open
1236
  );
1237
 
1238
pack_proc: process(sys_clk, sys_rst_n)
1239
begin
1240
  if (sys_rst_n='0') then
1241
    buffering       <= '1';
1242
    bits_in         <= (others=>'0');
1243
    bits_in_count   <= (others=>'0');
1244
    bits_out        <= (others=>'0');
1245
    bits_out_count  <= (others=>'0');
1246
    bit_sel         <= (others=>'0');
1247
    fsm_state       <= READ_DATA;
1248
  elsif (sys_clk'event and sys_clk='1') then
1249
    if (sys_clk_en='1') then
1250
 
1251
      -- Handle transitions from packing state to buffering state
1252
      if (tx_done_i='1' and tx_buff_i=in_match_adr_i) then
1253
        buffering <= '0';
1254
      end if;
1255
 
1256
      if (buffering='0') then
1257
 
1258
        -- Default values
1259
 
1260
        -- Handle state transitions
1261
        case (fsm_state) is
1262
 
1263
          when TRANSFER =>
1264
            if (bits_in_count=0) then
1265
              if (transfer_bit='1') then -- Check last word bit.
1266
                fsm_state <= MAKE_TAIL;
1267
              else
1268
                fsm_state <= READ_DATA;
1269
              end if;
1270
              -- Writing completed data is highest priority
1271
              if (bits_out_count=DATA_OUT_W) then
1272
                if (transfer_bit='1') then
1273
                  fsm_state <= WRITE_LAST_DATA;
1274
                  bits_out_count <= (others=>'0');
1275
                else
1276
                  fsm_state <= WRITE_DATA;
1277
                  bits_out_count <= (others=>'0');
1278
                end if;
1279
              end if;
1280
            elsif (bits_out_count=DATA_OUT_W) then
1281
              fsm_state <= WRITE_DATA;
1282
              bits_out_count <= (others=>'0');
1283
            elsif (bits_in_count>0) then
1284
              bits_out <= bits_out(bits_out'length-2 downto 0) & transfer_bit;
1285
              bits_in  <= bits_in(bits_in'length-2 downto 0) & '0';
1286
              bits_in_count <= bits_in_count-1;
1287
              bits_out_count <= bits_out_count+1;
1288
            end if;
1289
 
1290
          when READ_DATA =>
1291
            bits_in       <= stored_data & stored_last_word;
1292
            bits_in_count <= stored_word_size;
1293
            bit_sel       <= stored_word_size;
1294
            if (fifo_rd='1' and stored_word_size>0) then
1295
              fsm_state <= TRANSFER;
1296
            end if;
1297
 
1298
          when MAKE_TAIL =>
1299
            if (bits_out_count>=DATA_OUT_W) then
1300
              fsm_state <= WRITE_LAST_DATA;
1301
              bits_out_count <= (others=>'0');
1302
            else
1303
              bits_out <= bits_out(DATA_OUT_W-2 downto 0) & '0';
1304
              bits_out_count <= bits_out_count+1;
1305
            end if;
1306
 
1307
          when WRITE_DATA =>
1308
            if (out_ack_i='1') then
1309
              fsm_state <= TRANSFER;
1310
              if (bits_in_count=0) then
1311
                fsm_state <= READ_DATA;
1312
              end if;
1313
            end if;
1314
 
1315
          when WRITE_LAST_DATA =>
1316
            if (out_ack_i='1') then
1317
              fsm_state <= TRANSFER;
1318
              if (bits_in_count=0) then
1319
                fsm_state <= READ_DATA;
1320
              end if;
1321
              buffering <= '1';
1322
            end if;
1323
 
1324
          --when others => 
1325
          --  fsm_state <= IDLE;
1326
        end case;
1327
 
1328
      end if; -- buffering='0' and fifo_empty='0'
1329
 
1330
    end if; -- sys_clk_en
1331
  end if; -- sys_clk
1332
end process;
1333
 
1334
-- Select the correct bit to transfer
1335
transfer_bit <= bits_in(to_integer(bit_sel));
1336
 
1337
-- Create FIFO read signal
1338
fifo_rd <= '1' when fsm_state=READ_DATA and fifo_empty='0' and buffering='0' else '0';
1339
 
1340
-- Assign the outputs
1341
out_last_word_o <= '1' when fsm_state=WRITE_LAST_DATA else '0';
1342
out_cyc_o <= '1' when fsm_state=WRITE_DATA or fsm_state=WRITE_LAST_DATA else '0';
1343
out_dat_o <= bits_out;
1344
 
1345
end beh;
1346
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.