~ruther/jesd204b-vhdl

ref: 06ed0558b6ea9a4e6496cbcc2527622db7f02247 jesd204b-vhdl/src/data_link/ring_buffer.vhd -rw-r--r-- 3.7 KiB
06ed0558 — František Boháček feat: reset everything in ring buffer 2 years ago
                                                                                
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
library ieee;
use work.data_link_pkg.all;
use ieee.std_logic_1164.all;

entity ring_buffer is

  generic (
    CHARACTER_SIZE : integer := 8;
    BUFFER_SIZE : integer;
    READ_SIZE : integer);      -- The size of the buffer

  port (
    ci_clk             : in  std_logic;   -- The clock
    ci_reset           : in  std_logic;   -- The reset (active low)
    ci_adjust_position : in  integer range -READ_SIZE/2-1 to READ_SIZE/2+1;
    ci_read            : in  std_logic;   -- One to read in current cycle, Zero
                                        -- to stay on current reading position
    di_character       : in  std_logic_vector(CHARACTER_SIZE-1 downto 0);  -- The character to save on next clock
    co_read            : out std_logic_vector(CHARACTER_SIZE*READ_SIZE - 1 downto 0);  -- The output characters read from the buffer
    co_size            : out integer;   -- The current count of filled data
    co_read_position   : out integer;   -- The current read position inside of
                                        -- the buffer
    co_write_position  : out integer;   -- The current write position
                                        -- next character will be written to
    co_filled          : out std_logic);  -- Whether the buffer is full

end entity ring_buffer;

architecture a1 of ring_buffer is
    signal buff : std_logic_vector(CHARACTER_SIZE*BUFFER_SIZE-1 downto 0);
    signal buff_triple : std_logic_vector(3*CHARACTER_SIZE*BUFFER_SIZE-1 downto 0);
    signal next_read : std_logic_vector(CHARACTER_SIZE*BUFFER_SIZE-1 downto 0);
    signal read_position : integer := 0;
    signal adjusted_read_position : integer := 0;
    signal write_position : integer := 0;
    signal reg_size : integer := 0;
    signal size : integer := 0;
begin  -- architecture a1
    -- purpose: Adjust read position and read next character
    -- type   : sequential
    -- inputs : ci_clk, ci_reset
    -- outputs: read_position, write_position, buff
    read: process (ci_clk, ci_reset) is
    begin  -- process read
        if ci_reset = '0' then          -- asynchronous reset (active low)
            buff <= (others => '0');
            read_position <= 0;
            write_position <= 0;
            reg_size <= 0;
            co_read_position <= 0;
        elsif ci_clk'event and ci_clk = '1' then  -- rising clock edge
            if ci_read = '1' and size >= READ_SIZE + ci_adjust_position then
                read_position <= (read_position + ci_adjust_position + READ_SIZE) mod BUFFER_SIZE;
                co_read_position <= read_position + ci_adjust_position;
                reg_size <= size - READ_SIZE - ci_adjust_position + 1;
                co_read <= buff_triple(2*CHARACTER_SIZE*BUFFER_SIZE - 1 - (read_position + ci_adjust_position)*CHARACTER_SIZE downto 2*CHARACTER_SIZE*BUFFER_SIZE - (read_position + ci_adjust_position + READ_SIZE)*CHARACTER_SIZE);
            else
                reg_size <= reg_size + 1;
            end if;

            adjusted_read_position <= read_position + ci_adjust_position;
            buff(CHARACTER_SIZE*BUFFER_SIZE-1 - CHARACTER_SIZE*write_position downto CHARACTER_SIZE*BUFFER_SIZE - CHARACTER_SIZE*(write_position + 1)) <= di_character;
            write_position <= (write_position + 1) mod BUFFER_SIZE;
        end if;
    end process read;

    co_write_position <= write_position;
    co_size <= size;
    size <= BUFFER_SIZE when reg_size > BUFFER_SIZE else
               reg_size;
    buff_triple(3*CHARACTER_SIZE*BUFFER_SIZE - 1 downto 2*CHARACTER_SIZE*BUFFER_SIZE) <= buff;
    buff_triple(2*CHARACTER_SIZE*BUFFER_SIZE - 1 downto CHARACTER_SIZE*BUFFER_SIZE) <= buff;
    buff_triple(CHARACTER_SIZE*BUFFER_SIZE - 1 downto 0) <= buff;

    co_filled <=  '1' when reg_size > BUFFER_SIZE else
                  '0';

end architecture a1;
Do not follow this link