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

Subversion Repositories bw_tiff_compression

[/] [bw_tiff_compression/] [trunk/] [byte_segmentation_v5.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 amulder
----------------------------------------------------------------------------------
2
-- Company:        
3
-- Engineer:             Aart Mulder
4
-- 
5
-- Create Date:    22:07:42 04/06/2012 
6
-- Design Name: 
7
-- Module Name:  byte_segmentation - Behavioral 
8
-- Project Name:         CCITT4
9
--
10
-- Revision: 
11
-- Revision 0.01 - File Created
12
--                           The size of d_width_i and index has a width of 5 bits which 
13
--                           should be sufficient for most situations. With 5 bits a 
14
--                           maximum index of 31 can made, which gives a maximum d_i size
15
--                 of 31 - 8 = 23 bits.
16
--
17
-- Revision 0.02 - Input width increased from 13 to 45 bit and the output to 32 
18
--                 bit. Probably 24 bit output width is sufficient enough but
19
--                 for safety 32 is used for now.
20
--
21
-- Revision 0.03 - A little brainstorm session: 
22
--                 In worst case we get another huffman code
23
--                 on every second pclk_i which is 12bit long. The longest huffman
24
--                 code we can get is 45 bit followed by a 12bit code every other
25
--                 pclk_i or a 16bit code on the next pclk_i event one time at a line 
26
--                 end.
27
--                 Let say the maximum buffer size is 45 bit, then at least 2
28
--                 8bit buffer read operations are needed before the next pclk_i
29
--                 event.
30
--                 When using both the rising and falling edge, a clk_i frequency
31
--                 of at least 2x pclk_i is needed because we can not read an write
32
--                 to the buffer at the same time.
33
--
34
-- Revision 0.04 - byte_segmentation_v3 is made to be used in the capture_manager.
35
--
36
-- Note: byte_segmentation_v4 is omitted to match the revision numbers here with
37
-- the file numbers
38
--
39
-- Revision 0.05 - This is version 1 (byte_segmentation) with a changed output
40
--                 port. Instead of one 8bit it has four 8bit ports which will
41
--                 be used when needed. I.e. when more than 7 bits of data is
42
--                 available the first one is used, the second one when more
43
--                 than 15 bits are available and the third and fourth when
44
--                 more than 23 respectively 31 bits are available in the shift
45
--                 register.
46
--                 Furthermore, a FIFO is added to buffer the input in case more
47
--                 data is coming in than can be processed. Theoretically, in
48
--                 CCITT4 situations can appear where a 28 bit tiff-run is followed
49
--                 up by a 16 bit tiff-run with 2 clk_i periods in between.
50
--                 
51
--                 NOTE: the huffman and fax4 modules has have been modified to
52
--                 output the black or white run as soon as it is finished, i.e.
53
--                 separately in time which decreases the maximum code length
54
--                 to 28. This results in a shift register width of 28+7=35 bit.
55
--                 
56
----------------------------------------------------------------------------------
57
library IEEE;
58
use IEEE.STD_LOGIC_1164.ALL;
59
use IEEE.NUMERIC_STD.ALL;
60
 
61
entity byte_segmentation_v5 is
62
        Generic (
63
                INPUT_WIDTH_G : integer := 28;
64
                INDEX_WIDTH_G : integer := 5;
65
                OUTPUT_WIDTH_G : integer := 8
66
        );
67
        Port (
68
                reset_i :   in  STD_LOGIC;
69
                clk_i :                 in  STD_LOGIC;
70
                pclk_i :        in  STD_LOGIC;
71
                d_i :                   in  STD_LOGIC_VECTOR (INPUT_WIDTH_G-1 downto 0);
72
                d_width_i : in  STD_LOGIC_VECTOR (INDEX_WIDTH_G-1 downto 0);
73
                d_rdy_i :       in  STD_LOGIC;
74
                frame_finished_i :in  STD_LOGIC;
75
                frame_finished_o :out STD_LOGIC;
76
                d1_o :          out  STD_LOGIC_VECTOR (OUTPUT_WIDTH_G-1 downto 0);
77
                d_rdy1_o :      out  STD_LOGIC;
78
                d2_o :          out  STD_LOGIC_VECTOR (OUTPUT_WIDTH_G-1 downto 0);
79
                d_rdy2_o :      out  STD_LOGIC;
80
                d3_o :          out  STD_LOGIC_VECTOR (OUTPUT_WIDTH_G-1 downto 0);
81
                d_rdy3_o :      out  STD_LOGIC;
82
                d4_o :          out  STD_LOGIC_VECTOR (OUTPUT_WIDTH_G-1 downto 0);
83
                d_rdy4_o :      out  STD_LOGIC
84
        );
85
end byte_segmentation_v5;
86
 
87
architecture Behavioral of byte_segmentation_v5 is
88
        constant SHIFT_REG_SIZE_C : integer := (INPUT_WIDTH_G+OUTPUT_WIDTH_G)-1;
89
        constant SHIFT_REG_INDEX_WIDTH_C : integer := INDEX_WIDTH_G+1;
90
 
91
        signal shift_reg : std_logic_vector(SHIFT_REG_SIZE_C-1 downto 0) := (others => '1');
92
        signal index : unsigned (SHIFT_REG_INDEX_WIDTH_C-1 downto 0) := (others => '0');
93
        signal finish_frame : std_logic := '0';
94
        signal frame_finished_prev : std_logic := '0';
95
        signal reset_finish_frame : std_logic := '0';
96
        signal index2 : std_logic_vector (5 downto 0) := (others => '0');
97
 
98
        --FIFO signals
99
        signal FIFO_din, FIFO_dout : std_logic_vector((INPUT_WIDTH_G+INDEX_WIDTH_G)-1 downto 0) := (others => '1');
100
        signal FIFO_rd, FIFO_empty, FIFO_valid : std_logic := '0';
101
        signal in_data : std_logic_vector(INPUT_WIDTH_G-1 downto 0);
102
        signal in_data_width : std_logic_vector(SHIFT_REG_INDEX_WIDTH_C-1 downto 0);
103
        signal FIFO_used : unsigned(3 downto 0);
104
 
105
begin
106
        DualClkFIFO_ins : entity work.DualClkFIFO
107
        GENERIC MAP (
108
                DATA_WIDTH_G => INPUT_WIDTH_G+INDEX_WIDTH_G,
109
                MEMORY_SIZE_G  => 16,
110
                MEMORY_ADDRESS_WIDTH_G => 4
111
        )
112
        PORT MAP (
113
                rst_i => reset_i,
114
                wr_clk_i => pclk_i,
115
                rd_clk_i => clk_i,
116
                empty_o => FIFO_empty,
117
                full_o => open,
118
                pull_i => FIFO_rd,
119
                valid_o=> FIFO_valid,
120
                push_i => d_rdy_i,
121
                used_o => FIFO_used,
122
                d_i => FIFO_din,
123
                d_o => FIFO_dout
124
        );
125
 
126
        FIFO_din <= d_width_i & d_i;
127
        in_data_width <= '0' & FIFO_dout((INPUT_WIDTH_G+INDEX_WIDTH_G)-1 downto INPUT_WIDTH_G);
128
        in_data <= FIFO_dout(INPUT_WIDTH_G-1 downto 0);
129
 
130
        index2 <= std_logic_vector(index);
131
 
132
        --This process controls the read pin of the FIFO.
133
        FIFO_rd_process : process(clk_i)
134
        begin
135
                if clk_i'event and clk_i = '0' then
136
                        if FIFO_empty = '0' then
137
                                if (FIFO_valid = '0' and index < to_unsigned(OUTPUT_WIDTH_G, SHIFT_REG_INDEX_WIDTH_C))
138
                                                or (FIFO_rd = '1' and (index + unsigned(in_data_width)) < to_unsigned(8, SHIFT_REG_INDEX_WIDTH_C)) then
139
                                        FIFO_rd <= '1';
140
                                else
141
                                        FIFO_rd <= '0';
142
                                end if;
143
                        else
144
                                FIFO_rd <= '0';
145
                        end if;
146
                end if;
147
        end process FIFO_rd_process;
148
 
149
        process(clk_i)
150
                variable ind1, ind2, ind3, ind4 : integer range 0 to SHIFT_REG_SIZE_C := 0;
151
        begin
152
                if clk_i'event and clk_i = '1' then
153
                        reset_finish_frame <= '0';
154
 
155
                        if FIFO_valid = '1' and index < to_unsigned(OUTPUT_WIDTH_G, SHIFT_REG_INDEX_WIDTH_C) then
156
                                --
157
                                --The synthesiser complains that shift_reg(0) is equal to shift_reg(1) to shift_reg(6). When
158
                                --verifying by hand the following situations can apear:
159
                                --  SHIFT_REG_SIZE_C = 45+8-1=52
160
                                --  index = 0
161
                                --  d_width_i = 45
162
                                --  Gives: shift_reg(51 downto 7) <= input data
163
                                --
164
                                --  index = 7
165
                                --  d_width_i = 45
166
                                --  Gives: shift_reg(44 downto 0) <= input data
167
                                --
168
                                --So theoretically the warning is not correct.
169
                                --  
170
                                d_rdy1_o <= '0';
171
                                d_rdy2_o <= '0';
172
                                d_rdy3_o <= '0';
173
                                d_rdy4_o <= '0';
174
                                ind3 := to_integer(unsigned(in_data_width))-1;
175
                                case index2 is
176
                                        when std_logic_vector(to_unsigned(0, 6)) =>
177
                                                ind2 := (SHIFT_REG_SIZE_C-0)-to_integer(unsigned(in_data_width));
178
                                                shift_reg((SHIFT_REG_SIZE_C-1)-0 downto ind2) <= in_data(ind3 downto 0);
179
                                        when std_logic_vector(to_unsigned(1, 6)) =>
180
                                                ind2 := (SHIFT_REG_SIZE_C-1)-to_integer(unsigned(in_data_width));
181
                                                shift_reg((SHIFT_REG_SIZE_C-1)-1 downto ind2) <= in_data(ind3 downto 0);
182
                                        when std_logic_vector(to_unsigned(2, 6)) =>
183
                                                ind2 := (SHIFT_REG_SIZE_C-2)-to_integer(unsigned(in_data_width));
184
                                                shift_reg((SHIFT_REG_SIZE_C-1)-2 downto ind2) <= in_data(ind3 downto 0);
185
                                        when std_logic_vector(to_unsigned(3, 6)) =>
186
                                                ind2 := (SHIFT_REG_SIZE_C-3)-to_integer(unsigned(in_data_width));
187
                                                shift_reg((SHIFT_REG_SIZE_C-1)-3 downto ind2) <= in_data(ind3 downto 0);
188
                                        when std_logic_vector(to_unsigned(4, 6)) =>
189
                                                ind2 := (SHIFT_REG_SIZE_C-4)-to_integer(unsigned(in_data_width));
190
                                                shift_reg((SHIFT_REG_SIZE_C-1)-4 downto ind2) <= in_data(ind3 downto 0);
191
                                        when std_logic_vector(to_unsigned(5, 6)) =>
192
                                                ind2 := (SHIFT_REG_SIZE_C-5)-to_integer(unsigned(in_data_width));
193
                                                shift_reg((SHIFT_REG_SIZE_C-1)-5 downto ind2) <= in_data(ind3 downto 0);
194
                                        when std_logic_vector(to_unsigned(6, 6)) =>
195
                                                ind2 := (SHIFT_REG_SIZE_C-6)-to_integer(unsigned(in_data_width));
196
                                                shift_reg((SHIFT_REG_SIZE_C-1)-6 downto ind2) <= in_data(ind3 downto 0);
197
                                        when std_logic_vector(to_unsigned(7, 6)) =>
198
                                                ind2 := (SHIFT_REG_SIZE_C-7)-to_integer(unsigned(in_data_width));
199
                                                shift_reg((SHIFT_REG_SIZE_C-1)-7 downto ind2) <= in_data(ind3 downto 0);
200
                                        when others =>
201
                                                shift_reg <= (others => '0');
202
                                end case;
203
                                index <= index + unsigned(in_data_width);
204
                        elsif index >= to_unsigned(OUTPUT_WIDTH_G*1, SHIFT_REG_INDEX_WIDTH_C) and index < to_unsigned(OUTPUT_WIDTH_G*2, SHIFT_REG_INDEX_WIDTH_C) then
205
                                --Move the highest OUTPUT_WIDTH_G bits to the output
206
                                d1_o <= shift_reg(SHIFT_REG_SIZE_C-1 downto SHIFT_REG_SIZE_C-OUTPUT_WIDTH_G);
207
                                d_rdy1_o <= '1';
208
                                d_rdy2_o <= '0';
209
                                d_rdy3_o <= '0';
210
                                d_rdy4_o <= '0';
211
                                --Shift the left over bits(all except OUTPUT_WIDTH_G highest) OUTPUT_WIDTH_G positions up/left
212
                                shift_reg(SHIFT_REG_SIZE_C-1 downto OUTPUT_WIDTH_G) <= shift_reg((SHIFT_REG_SIZE_C-1)-OUTPUT_WIDTH_G downto 0);
213
                                --Decrement the index with 8
214
                                index <= index - to_unsigned(OUTPUT_WIDTH_G, SHIFT_REG_INDEX_WIDTH_C);
215
                        elsif index >= to_unsigned(OUTPUT_WIDTH_G*2, SHIFT_REG_INDEX_WIDTH_C) and index < to_unsigned(OUTPUT_WIDTH_G*3, SHIFT_REG_INDEX_WIDTH_C) then
216
                                --Move the highest OUTPUT_WIDTH_G*2 bits to the output
217
                                d1_o <= shift_reg(SHIFT_REG_SIZE_C-1 downto SHIFT_REG_SIZE_C-OUTPUT_WIDTH_G);
218
                                d_rdy1_o <= '1';
219
                                d2_o <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*1) downto SHIFT_REG_SIZE_C-(OUTPUT_WIDTH_G*2));
220
                                d_rdy2_o <= '1';
221
                                d_rdy3_o <= '0';
222
                                d_rdy4_o <= '0';
223
                                --Shift the left over bits(all except OUTPUT_WIDTH_G*2 highest) OUTPUT_WIDTH_G*2 positions up/left
224
                                shift_reg(SHIFT_REG_SIZE_C-1 downto (OUTPUT_WIDTH_G*2)) <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*2) downto 0);
225
                                --Decrement the index with 16
226
                                index <= index - to_unsigned(OUTPUT_WIDTH_G*2, SHIFT_REG_INDEX_WIDTH_C);
227
                        elsif index >= to_unsigned(OUTPUT_WIDTH_G*3, SHIFT_REG_INDEX_WIDTH_C) and index < to_unsigned(OUTPUT_WIDTH_G*4, SHIFT_REG_INDEX_WIDTH_C) then
228
                                --Move the highest OUTPUT_WIDTH_G*3 bits to the output
229
                                d1_o <= shift_reg(SHIFT_REG_SIZE_C-1 downto SHIFT_REG_SIZE_C-OUTPUT_WIDTH_G);
230
                                d_rdy1_o <= '1';
231
                                d2_o <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*1) downto SHIFT_REG_SIZE_C-(OUTPUT_WIDTH_G*2));
232
                                d_rdy2_o <= '1';
233
                                d3_o <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*2) downto SHIFT_REG_SIZE_C-(OUTPUT_WIDTH_G*3));
234
                                d_rdy3_o <= '1';
235
                                d_rdy4_o <= '0';
236
                                --Shift the left over bits(all except OUTPUT_WIDTH_G*3 highest) OUTPUT_WIDTH_G*3 positions up/left
237
                                shift_reg(SHIFT_REG_SIZE_C-1 downto (OUTPUT_WIDTH_G*3)) <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*3) downto 0);
238
                                --Decrement the index with 24
239
                                index <= index - to_unsigned(OUTPUT_WIDTH_G*3, SHIFT_REG_INDEX_WIDTH_C);
240
                        elsif index >= to_unsigned(OUTPUT_WIDTH_G*4, SHIFT_REG_INDEX_WIDTH_C) then
241
                                --Move the highest OUTPUT_WIDTH_G*4 bits to the output
242
                                d1_o <= shift_reg(SHIFT_REG_SIZE_C-1 downto SHIFT_REG_SIZE_C-OUTPUT_WIDTH_G);
243
                                d_rdy1_o <= '1';
244
                                d2_o <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*1) downto SHIFT_REG_SIZE_C-(OUTPUT_WIDTH_G*2));
245
                                d_rdy2_o <= '1';
246
                                d3_o <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*2) downto SHIFT_REG_SIZE_C-(OUTPUT_WIDTH_G*3));
247
                                d_rdy3_o <= '1';
248
                                d4_o <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*3) downto SHIFT_REG_SIZE_C-(OUTPUT_WIDTH_G*4));
249
                                d_rdy4_o <= '1';
250
                                --Shift the left over bits(all except OUTPUT_WIDTH_G*4 highest) OUTPUT_WIDTH_G*4 positions up/left
251
                                shift_reg(SHIFT_REG_SIZE_C-1 downto (OUTPUT_WIDTH_G*4)) <= shift_reg((SHIFT_REG_SIZE_C-1)-(OUTPUT_WIDTH_G*4) downto 0);
252
                                --Decrement the index with 32
253
                                index <= index - to_unsigned(OUTPUT_WIDTH_G*4, SHIFT_REG_INDEX_WIDTH_C);
254
                        elsif finish_frame = '1' and FIFO_used = "0000" then
255
                                reset_finish_frame <= '1';
256
 
257
                                d1_o <= (others => '0');
258
                                if index > to_unsigned(0, SHIFT_REG_INDEX_WIDTH_C) then
259
                                        d1_o(OUTPUT_WIDTH_G-1 downto OUTPUT_WIDTH_G-to_integer(index)) <= shift_reg(SHIFT_REG_SIZE_C-1 downto SHIFT_REG_SIZE_C-to_integer(index));
260
                                        d_rdy1_o <= '1';
261
                                else
262
                                        d_rdy1_o <= '0';
263
                                end if;
264
                                d_rdy2_o <= '0';
265
                                d_rdy3_o <= '0';
266
                                d_rdy4_o <= '0';
267
 
268
                                index <= (others => '0');
269
                                shift_reg <= (others => '0');
270
                        else
271
                                d_rdy1_o <= '0';
272
                                d_rdy2_o <= '0';
273
                                d_rdy3_o <= '0';
274
                                d_rdy4_o <= '0';
275
                        end if;
276
                end if;
277
        end process;
278
 
279
        process(clk_i)
280
        begin
281
                if clk_i'event and clk_i = '1' then
282
                        frame_finished_prev <= frame_finished_i;
283
 
284
                        if frame_finished_i = '0' and frame_finished_prev = '1' then
285
                                finish_frame <= '1';
286
                        elsif reset_finish_frame = '1' then
287
                                finish_frame <= '0';
288
                        end if;
289
                end if;
290
        end process;
291
 
292
        frame_finished_o <= reset_finish_frame;
293
 
294
end Behavioral;

powered by: WebSVN 2.1.0

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