1 | LIBRARY ieee;
|
2 | USE ieee.std_logic_1164.ALL;
|
3 | USE ieee.numeric_std.ALL;
|
4 | ENTITY test IS
|
5 | GENERIC (
|
6 | DATA_WIDTH : NATURAL := 256
|
7 | );
|
8 | PORT (
|
9 | -- clk,reset
|
10 | aclk : IN std_ulogic;
|
11 | aresetn : IN std_ulogic;
|
12 |
|
13 | -- input
|
14 | data_valid_i : IN std_ulogic;
|
15 | data_i : IN std_ulogic_vector(DATA_WIDTH - 1 DOWNTO 0);
|
16 | valid_bytes_i : IN std_ulogic_vector(DATA_WIDTH/8 - 1 DOWNTO 0);
|
17 |
|
18 | -- output
|
19 | data_valid_o : OUT std_ulogic;
|
20 | data_o : OUT std_ulogic_vector(DATA_WIDTH - 1 DOWNTO 0);
|
21 | valid_bytes_o : OUT std_ulogic_vector(DATA_WIDTH/8 - 1 DOWNTO 0)
|
22 | );
|
23 | END ENTITY test;
|
24 |
|
25 | ARCHITECTURE rtl OF test IS
|
26 |
|
27 | TYPE data_t IS ARRAY (0 TO DATA_WIDTH/8 - 1) OF std_ulogic_vector(DATA_WIDTH - 1 DOWNTO 0);
|
28 | TYPE valid_bytes_t IS ARRAY (0 TO DATA_WIDTH/8 - 1) OF std_ulogic_vector(DATA_WIDTH/8 - 1 DOWNTO 0);
|
29 | TYPE array_pos_t IS ARRAY (0 TO DATA_WIDTH/8 - 1) OF INTEGER RANGE 0 TO DATA_WIDTH - 8;
|
30 | SIGNAL data_array : data_t := (OTHERS => (OTHERS => '0'));
|
31 | SIGNAL valid_bytes_array : valid_bytes_t := (OTHERS => (OTHERS => '0'));
|
32 | SIGNAL array_pos : array_pos_t;
|
33 | SIGNAL cnt_valid_bytes : INTEGER RANGE 0 TO DATA_WIDTH/8 := 0;
|
34 | SIGNAL sr_array_pos : INTEGER RANGE 0 TO DATA_WIDTH * 2 := 0;
|
35 | SIGNAL data_sr : std_ulogic_vector(DATA_WIDTH * 2 - 1 DOWNTO 0) := (OTHERS => '0');
|
36 |
|
37 | BEGIN
|
38 | start_stage : PROCESS (aclk)
|
39 | BEGIN
|
40 | IF rising_edge(aclk) THEN
|
41 | data_array(0) <= data_i;
|
42 | valid_bytes_array(0) <= valid_bytes_i;
|
43 | array_pos(0) <= 0;
|
44 | IF (data_valid_i = '1') THEN
|
45 | IF (valid_bytes_i(0) = '1') THEN
|
46 | array_pos(0) <= 8;
|
47 | END IF;
|
48 | END IF;
|
49 | END IF;
|
50 | END PROCESS;
|
51 |
|
52 | gen_stages : FOR index IN 0 TO DATA_WIDTH/8 - 3 GENERATE
|
53 | stages : PROCESS (aclk)
|
54 | BEGIN
|
55 | IF rising_edge(aclk) THEN
|
56 | valid_bytes_array(index + 1) <= valid_bytes_array(index);
|
57 | data_array(index + 1) <= data_array(index);
|
58 | array_pos(index + 1) <= array_pos(index);
|
59 | IF (valid_bytes_array(index)(index + 1) = '1') THEN
|
60 | data_array(index + 1)(array_pos(index) + 7 DOWNTO array_pos(index)) <= data_array(index)(15 + index * 8 DOWNTO 8 + index * 8);
|
61 | array_pos(index + 1) <= array_pos(index) + 8;
|
62 | END IF;
|
63 | END IF;
|
64 | END PROCESS;
|
65 | END GENERATE gen_stages;
|
66 |
|
67 | end_stage : PROCESS (aclk)
|
68 | VARIABLE cnt : unsigned (DATA_WIDTH/8 - 1 DOWNTO 0);
|
69 | BEGIN
|
70 | IF rising_edge(aclk) THEN
|
71 | data_array(DATA_WIDTH/8 - 1) <= (OTHERS => '0');
|
72 | array_pos(DATA_WIDTH/8 - 1) <= array_pos(DATA_WIDTH/8 - 2);
|
73 |
|
74 | IF (valid_bytes_array(DATA_WIDTH/8 - 2)(DATA_WIDTH/8 - 1) = '1') THEN
|
75 | data_array(DATA_WIDTH/8 - 1)(array_pos(DATA_WIDTH/8 - 2) + 7 DOWNTO array_pos(DATA_WIDTH/8 - 2)) <= data_array(DATA_WIDTH/8 - 2)(DATA_WIDTH - 1 DOWNTO DATA_WIDTH - 8);
|
76 | END IF;
|
77 |
|
78 | IF (array_pos(DATA_WIDTH/8 - 2) /= 0) THEN
|
79 | data_array(DATA_WIDTH/8 - 1)(array_pos(DATA_WIDTH/8 - 2) - 1 DOWNTO 0) <= data_array(DATA_WIDTH/8 - 2)(array_pos(DATA_WIDTH/8 - 2) - 1 DOWNTO 0);
|
80 | END IF;
|
81 |
|
82 | cnt := (OTHERS => '0');
|
83 | FOR i IN 0 TO DATA_WIDTH/8 - 1 LOOP
|
84 | cnt := cnt + unsigned'("0" & valid_bytes_array(DATA_WIDTH/8 - 2)(i));
|
85 | END LOOP;
|
86 | cnt_valid_bytes <= to_integer(cnt);
|
87 | END IF;
|
88 | END PROCESS;
|
89 |
|
90 | output_stage : PROCESS (aclk)
|
91 |
|
92 | BEGIN
|
93 | IF rising_edge(aclk) THEN
|
94 | data_valid_o <= '0';
|
95 | valid_bytes_o <= (OTHERS => '0');
|
96 | data_o <= (OTHERS => '0');
|
97 | IF (sr_array_pos >= DATA_WIDTH) THEN
|
98 | data_valid_o <= '1';
|
99 | data_o <= data_sr(DATA_WIDTH - 1 DOWNTO 0);
|
100 | valid_bytes_o <= (OTHERS => '1');
|
101 | data_sr(sr_array_pos - 1 DOWNTO 0) <= data_array(DATA_WIDTH/8 - 1) & data_sr(sr_array_pos - 1 DOWNTO DATA_WIDTH);
|
102 | sr_array_pos <= sr_array_pos - DATA_WIDTH + cnt_valid_bytes * 8;
|
103 | ELSE
|
104 | data_sr(sr_array_pos + DATA_WIDTH - 1 DOWNTO sr_array_pos) <= data_array(DATA_WIDTH/8 - 1);
|
105 | sr_array_pos <= sr_array_pos + cnt_valid_bytes * 8;
|
106 | END IF;
|
107 | END IF;
|
108 | END PROCESS;
|
109 |
|
110 |
|
111 | END ARCHITECTURE rtl;
|