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

Subversion Repositories aoocs

[/] [aoocs/] [trunk/] [rtl/] [ocs_blitter.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without modification, are
5
 * permitted provided that the following conditions are met:
6
 *
7
 *  1. Redistributions of source code must retain the above copyright notice, this list of
8
 *     conditions and the following disclaimer.
9
 *
10
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
11
 *     of conditions and the following disclaimer in the documentation and/or other materials
12
 *     provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
 
25
/*! \file
26
 * \brief OCS blitter implementation with WISHBONE master and slave interface.
27
 */
28
 
29
/*! \brief \copybrief ocs_blitter.v
30
 
31
List of blitter registers:
32
\verbatim
33
Implemented:
34
   BLTCON0     ~040  W   A       Blitter control register 0
35
   BLTCON1     ~042  W   A( E )  Blitter control register 1
36
   BLTAFWM     ~044  W   A       Blitter first word mask for source A
37
   BLTALWM     ~046  W   A       Blitter last word mask for source A
38
   BLTCPTH   + ~048  W   A       Blitter pointer to source C (high 3 bits)
39
   BLTCPTL   + ~04A  W   A       Blitter pointer to source C (low 15 bits)
40
   BLTBPTH   + ~04C  W   A       Blitter pointer to source B (high 3 bits)
41
   BLTBPTL   + ~04E  W   A       Blitter pointer to source B (low 15 bits)
42
   BLTAPTH   + ~050  W   A( E )  Blitter pointer to source A (high 3 bits)
43
   BLTAPTL   + ~052  W   A       Blitter pointer to source A (low 15 bits)
44
   BLTDPTH   + ~054  W   A       Blitter pointer to destination D (high 3 bits)
45
   BLTDPTL   + ~056  W   A       Blitter pointer to destination D (low 15 bits)
46
   BLTSIZE     ~058  W   A       Blitter start and size (window width,height)
47
   BLTCMOD     ~060  W   A       Blitter modulo for source C
48
   BLTBMOD     ~062  W   A       Blitter modulo for source B
49
   BLTAMOD     ~064  W   A       Blitter modulo for source A
50
   BLTDMOD     ~066  W   A       Blitter modulo for destination D
51
   BLTCDAT   % ~070  W   A       Blitter source C data register
52
   BLTBDAT   % ~072  W   A       Blitter source B data register
53
   BLTADAT   % ~074  W   A       Blitter source A data register
54
Not implemented:
55
   BLTDDAT   & *000  ER  A       Blitter destination early read (dummy address)
56
\endverbatim
57
*/
58
module ocs_blitter(
59
    //% \name Clock and reset
60
    //% @{
61
    input               CLK_I,
62
    input               reset_n,
63
    //% @}
64
 
65
    //% \name WISHBONE master
66
    //% @{
67
    output reg          CYC_O,
68
    output reg          STB_O,
69
    output reg          WE_O,
70
    output reg [31:2]   ADR_O,
71
    output reg [3:0]    SEL_O,
72
    output reg [31:0]   master_DAT_O,
73
    input [31:0]        master_DAT_I,
74
    input               ACK_I,
75
    //% @}
76
 
77
    //% \name WISHBONE slave
78
    //% @{
79
    input               CYC_I,
80
    input               STB_I,
81
    input               WE_I,
82
    input [8:2]         ADR_I,
83
    input [3:0]         SEL_I,
84
    input [31:0]        slave_DAT_I,
85
    output reg          ACK_O,
86
    //% @}
87
 
88
    //% \name Internal OCS ports
89
    //% @{
90
    input [10:0]        dma_con,
91
 
92
    output reg          blitter_irq,
93
    output reg          blitter_zero,
94
    output reg          blitter_busy
95
    //% @}
96
);
97
 
98
reg [15:0] a_first_word_mask;
99
reg [15:0] a_last_word_mask;
100
reg [15:0] blt_con0;
101
reg [15:0] blt_con1;
102
reg [15:0] blt_size;
103
reg [5:0] blt_width_in_words;
104
 
105
reg [63:0] a_dat;
106
reg [63:0] b_dat;
107
reg [47:0] c_dat;
108
reg [15:0] a_mod;
109
reg [15:0] b_mod;
110
reg [15:0] c_mod;
111
reg [15:0] d_mod;
112
reg [31:0] a_address;
113
reg [31:0] b_address;
114
reg [31:0] c_address;
115
reg [31:0] d_address;
116
reg [3:0] a_shift_saved;
117
reg [3:0] b_shift_saved;
118
 
119
reg [1:0] a_avail;
120
reg [1:0] b_avail;
121
reg [1:0] c_avail;
122
reg line_single;
123
reg fill_carry;
124
 
125
reg max_width;
126
 
127
reg [3:0] state;
128
parameter [3:0]
129
    S_IDLE          = 3'd0,
130
    S_CHECK_LOAD    = 3'd1,
131
    S_LOAD_A        = 3'd2,
132
    S_LOAD_B        = 3'd3,
133
    S_LOAD_C        = 3'd4,
134
    S_CHECK_SAVE    = 3'd5,
135
    S_SAVE_D        = 3'd6;
136
 
137
wire reverse;
138
// reverse: LINE=0, DESC=1
139
assign reverse = (blt_con1[0] == 1'b0 && blt_con1[1] == 1'b1);
140
 
141
// mask, even when A channel not enabled
142
wire [15:0] a_dat_mask;
143
assign a_dat_mask =
144
    (a_enabled == 1'b1)? 16'hFFFF :
145
    (blt_width_in_words[5:0] == blt_size[5:0] && blt_width_in_words[5:0] == 6'd1)? a_first_word_mask & a_last_word_mask :
146
    (blt_width_in_words[5:0] == blt_size[5:0])? a_first_word_mask :
147
    (blt_width_in_words[5:0] == 6'd1)? a_last_word_mask :
148
    16'hFFFF;
149
 
150
wire [63:0] a_dat_final;
151
assign a_dat_final = (reverse == 1'b0) ?
152
    { a_dat[63:48], a_dat[47:32] & a_dat_mask, a_dat[31:0] } :
153
    { a_dat[63:32], a_dat[31:16] & a_dat_mask, a_dat[15:0] };
154
 
155
wire [15:0] a_shifted;
156
assign a_shifted =
157
    (line_single == 1'b1 && blt_con1[0] == 1'b1 && blt_con1[1] == 1'b1) ? 16'd0 :
158
    (a_shift_saved == 4'd0) ? ((reverse == 1'b0) ? a_dat_final[47:32] : a_dat_final[31:16]) :
159
    (a_shift_saved == 4'd1) ? ((reverse == 1'b0) ? a_dat_final[48:33] : a_dat_final[30:15]) :
160
    (a_shift_saved == 4'd2) ? ((reverse == 1'b0) ? a_dat_final[49:34] : a_dat_final[29:14]) :
161
    (a_shift_saved == 4'd3) ? ((reverse == 1'b0) ? a_dat_final[50:35] : a_dat_final[28:13]) :
162
    (a_shift_saved == 4'd4) ? ((reverse == 1'b0) ? a_dat_final[51:36] : a_dat_final[27:12]) :
163
    (a_shift_saved == 4'd5) ? ((reverse == 1'b0) ? a_dat_final[52:37] : a_dat_final[26:11]) :
164
    (a_shift_saved == 4'd6) ? ((reverse == 1'b0) ? a_dat_final[53:38] : a_dat_final[25:10]) :
165
    (a_shift_saved == 4'd7) ? ((reverse == 1'b0) ? a_dat_final[54:39] : a_dat_final[24:9]) :
166
    (a_shift_saved == 4'd8) ? ((reverse == 1'b0) ? a_dat_final[55:40] : a_dat_final[23:8]) :
167
    (a_shift_saved == 4'd9) ? ((reverse == 1'b0) ? a_dat_final[56:41] : a_dat_final[22:7]) :
168
    (a_shift_saved == 4'd10) ? ((reverse == 1'b0) ? a_dat_final[57:42] : a_dat_final[21:6]) :
169
    (a_shift_saved == 4'd11) ? ((reverse == 1'b0) ? a_dat_final[58:43] : a_dat_final[20:5]) :
170
    (a_shift_saved == 4'd12) ? ((reverse == 1'b0) ? a_dat_final[59:44] : a_dat_final[19:4]) :
171
    (a_shift_saved == 4'd13) ? ((reverse == 1'b0) ? a_dat_final[60:45] : a_dat_final[18:3]) :
172
    (a_shift_saved == 4'd14) ? ((reverse == 1'b0) ? a_dat_final[61:46] : a_dat_final[17:2]) :
173
    ((reverse == 1'b0) ? a_dat_final[62:47] : a_dat_final[16:1]);
174
 
175
wire [15:0] b_shifted;
176
assign b_shifted =
177
    (b_shift_saved == 4'd0) ? ((reverse == 1'b0) ? b_dat[47:32] : b_dat[31:16]) :
178
    (b_shift_saved == 4'd1) ? ((reverse == 1'b0) ? b_dat[48:33] : b_dat[30:15]) :
179
    (b_shift_saved == 4'd2) ? ((reverse == 1'b0) ? b_dat[49:34] : b_dat[29:14]) :
180
    (b_shift_saved == 4'd3) ? ((reverse == 1'b0) ? b_dat[50:35] : b_dat[28:13]) :
181
    (b_shift_saved == 4'd4) ? ((reverse == 1'b0) ? b_dat[51:36] : b_dat[27:12]) :
182
    (b_shift_saved == 4'd5) ? ((reverse == 1'b0) ? b_dat[52:37] : b_dat[26:11]) :
183
    (b_shift_saved == 4'd6) ? ((reverse == 1'b0) ? b_dat[53:38] : b_dat[25:10]) :
184
    (b_shift_saved == 4'd7) ? ((reverse == 1'b0) ? b_dat[54:39] : b_dat[24:9]) :
185
    (b_shift_saved == 4'd8) ? ((reverse == 1'b0) ? b_dat[55:40] : b_dat[23:8]) :
186
    (b_shift_saved == 4'd9) ? ((reverse == 1'b0) ? b_dat[56:41] : b_dat[22:7]) :
187
    (b_shift_saved == 4'd10) ? ((reverse == 1'b0) ? b_dat[57:42] : b_dat[21:6]) :
188
    (b_shift_saved == 4'd11) ? ((reverse == 1'b0) ? b_dat[58:43] : b_dat[20:5]) :
189
    (b_shift_saved == 4'd12) ? ((reverse == 1'b0) ? b_dat[59:44] : b_dat[19:4]) :
190
    (b_shift_saved == 4'd13) ? ((reverse == 1'b0) ? b_dat[60:45] : b_dat[18:3]) :
191
    (b_shift_saved == 4'd14) ? ((reverse == 1'b0) ? b_dat[61:46] : b_dat[17:2]) :
192
    ((reverse == 1'b0) ? b_dat[62:47] : b_dat[16:1]);
193
 
194
wire [15:0] b_shifted_final;
195
assign b_shifted_final = (blt_con1[0] == 1'b0) ? b_shifted : ( (b_shifted[0] == 1'b0) ? 16'd0 :  16'hFFFF );
196
 
197
wire [15:0] c_selected;
198
assign c_selected = (reverse == 1'b0) ? c_dat[47:32] : c_dat[15:0];
199
 
200
wire [15:0] minterm_output;
201
assign minterm_output = {
202
    blt_con0[ {1'b0, a_shifted[15], b_shifted_final[15], c_selected[15]} ],
203
    blt_con0[ {1'b0, a_shifted[14], b_shifted_final[14], c_selected[14]} ],
204
    blt_con0[ {1'b0, a_shifted[13], b_shifted_final[13], c_selected[13]} ],
205
    blt_con0[ {1'b0, a_shifted[12], b_shifted_final[12], c_selected[12]} ],
206
    blt_con0[ {1'b0, a_shifted[11], b_shifted_final[11], c_selected[11]} ],
207
    blt_con0[ {1'b0, a_shifted[10], b_shifted_final[10], c_selected[10]} ],
208
    blt_con0[ {1'b0, a_shifted[9], b_shifted_final[9], c_selected[9]} ],
209
    blt_con0[ {1'b0, a_shifted[8], b_shifted_final[8], c_selected[8]} ],
210
    blt_con0[ {1'b0, a_shifted[7], b_shifted_final[7], c_selected[7]} ],
211
    blt_con0[ {1'b0, a_shifted[6], b_shifted_final[6], c_selected[6]} ],
212
    blt_con0[ {1'b0, a_shifted[5], b_shifted_final[5], c_selected[5]} ],
213
    blt_con0[ {1'b0, a_shifted[4], b_shifted_final[4], c_selected[4]} ],
214
    blt_con0[ {1'b0, a_shifted[3], b_shifted_final[3], c_selected[3]} ],
215
    blt_con0[ {1'b0, a_shifted[2], b_shifted_final[2], c_selected[2]} ],
216
    blt_con0[ {1'b0, a_shifted[1], b_shifted_final[1], c_selected[1]} ],
217
    blt_con0[ {1'b0, a_shifted[0], b_shifted_final[0], c_selected[0]} ]
218
};
219
wire [15:0] xor_chains;
220
assign xor_chains = {
221
    minterm_output[0] ^ minterm_output[1]  ^ minterm_output[2]  ^ minterm_output[3] ^ minterm_output[4]  ^ minterm_output[5]  ^
222
                        minterm_output[6]  ^ minterm_output[7]  ^ minterm_output[8]  ^ minterm_output[9] ^ minterm_output[10] ^ minterm_output[11] ^
223
                        minterm_output[12] ^ minterm_output[13] ^ minterm_output[14],
224
    minterm_output[0] ^ minterm_output[1]  ^ minterm_output[2]  ^ minterm_output[3] ^ minterm_output[4]  ^ minterm_output[5]  ^
225
                        minterm_output[6]  ^ minterm_output[7]  ^ minterm_output[8]  ^ minterm_output[9] ^ minterm_output[10] ^ minterm_output[11] ^
226
                        minterm_output[12] ^ minterm_output[13],
227
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4]  ^ minterm_output[5]  ^
228
                        minterm_output[6] ^ minterm_output[7] ^ minterm_output[8] ^ minterm_output[9] ^ minterm_output[10] ^ minterm_output[11] ^
229
                        minterm_output[12],
230
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4]  ^ minterm_output[5]  ^
231
                        minterm_output[6] ^ minterm_output[7] ^ minterm_output[8] ^ minterm_output[9] ^ minterm_output[10] ^ minterm_output[11],
232
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4]  ^ minterm_output[5]  ^
233
                        minterm_output[6] ^ minterm_output[7] ^ minterm_output[8] ^ minterm_output[9] ^ minterm_output[10],
234
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4] ^ minterm_output[5]   ^
235
                        minterm_output[6] ^ minterm_output[7] ^ minterm_output[8] ^ minterm_output[9],
236
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4] ^ minterm_output[5]   ^
237
                        minterm_output[6] ^ minterm_output[7] ^ minterm_output[8],
238
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4] ^ minterm_output[5]   ^
239
                        minterm_output[6] ^ minterm_output[7],
240
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4] ^ minterm_output[5]   ^
241
                        minterm_output[6],
242
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4] ^ minterm_output[5],
243
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3] ^ minterm_output[4],
244
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2] ^ minterm_output[3],
245
    minterm_output[0] ^ minterm_output[1] ^ minterm_output[2],
246
    minterm_output[0] ^ minterm_output[1],
247
    minterm_output[0],
248
    1'b0
249
};
250
wire [15:0] final_output;
251
assign final_output =
252
    (blt_con1[0] == 1'b1 || (blt_con1[3] == 1'b0 && blt_con1[4] == 1'b0)) ? minterm_output :
253
    (blt_con1[4] == 1'b1) ? {
254
        fill_carry ^ xor_chains[15] ^ minterm_output[15],
255
        fill_carry ^ xor_chains[14] ^ minterm_output[14],
256
        fill_carry ^ xor_chains[13] ^ minterm_output[13],
257
        fill_carry ^ xor_chains[12] ^ minterm_output[12],
258
        fill_carry ^ xor_chains[11] ^ minterm_output[11],
259
        fill_carry ^ xor_chains[10] ^ minterm_output[10],
260
        fill_carry ^ xor_chains[9] ^ minterm_output[9],
261
        fill_carry ^ xor_chains[8] ^ minterm_output[8],
262
        fill_carry ^ xor_chains[7] ^ minterm_output[7],
263
        fill_carry ^ xor_chains[6] ^ minterm_output[6],
264
        fill_carry ^ xor_chains[5] ^ minterm_output[5],
265
        fill_carry ^ xor_chains[4] ^ minterm_output[4],
266
        fill_carry ^ xor_chains[3] ^ minterm_output[3],
267
        fill_carry ^ xor_chains[2] ^ minterm_output[2],
268
        fill_carry ^ xor_chains[1] ^ minterm_output[1],
269
        fill_carry ^ xor_chains[0] ^ minterm_output[0]
270
   } : {
271
        (fill_carry ^ xor_chains[15]) | minterm_output[15],
272
        (fill_carry ^ xor_chains[14]) | minterm_output[14],
273
        (fill_carry ^ xor_chains[13]) | minterm_output[13],
274
        (fill_carry ^ xor_chains[12]) | minterm_output[12],
275
        (fill_carry ^ xor_chains[11]) | minterm_output[11],
276
        (fill_carry ^ xor_chains[10]) | minterm_output[10],
277
        (fill_carry ^ xor_chains[9]) | minterm_output[9],
278
        (fill_carry ^ xor_chains[8]) | minterm_output[8],
279
        (fill_carry ^ xor_chains[7]) | minterm_output[7],
280
        (fill_carry ^ xor_chains[6]) | minterm_output[6],
281
        (fill_carry ^ xor_chains[5]) | minterm_output[5],
282
        (fill_carry ^ xor_chains[4]) | minterm_output[4],
283
        (fill_carry ^ xor_chains[3]) | minterm_output[3],
284
        (fill_carry ^ xor_chains[2]) | minterm_output[2],
285
        (fill_carry ^ xor_chains[1]) | minterm_output[1],
286
        (fill_carry ^ xor_chains[0]) | minterm_output[0]
287
   };
288
 
289
// DMAEN, BLTEN, USEA, LINE=0
290
wire a_enabled;
291
assign a_enabled = (dma_con[9] == 1'b1 && dma_con[6] == 1'b1 && blt_con0[11] == 1'b1 && blt_con1[0] == 1'b0);
292
// DMAEN, BLTEN, USEB
293
wire b_enabled;
294
assign b_enabled = (dma_con[9] == 1'b1 && dma_con[6] == 1'b1 && blt_con0[10] == 1'b1);
295
// DMAEN, BLTEN, USEC
296
wire c_enabled;
297
assign c_enabled = (dma_con[9] == 1'b1 && dma_con[6] == 1'b1 && blt_con0[9] == 1'b1);
298
// DMAEN, BLTEN, USED
299
wire d_enabled;
300
assign d_enabled = (dma_con[9] == 1'b1 && dma_con[6] == 1'b1 && blt_con0[8] == 1'b1);
301
 
302
always @(posedge CLK_I or negedge reset_n) begin
303
    if(reset_n == 1'b0) begin
304
        CYC_O <= 1'b0;
305
        STB_O <= 1'b0;
306
        WE_O <= 1'b0;
307
        ADR_O <= 30'd0;
308
        SEL_O <= 4'b0000;
309
        master_DAT_O <= 32'd0;
310
        ACK_O <= 1'b0;
311
        blitter_irq <= 1'b0;
312
        blitter_zero <= 1'b0;
313
        blitter_busy <= 1'b0;
314
 
315
        a_first_word_mask <= 16'd0;
316
        a_last_word_mask <= 16'd0;
317
        blt_con0 <= 16'd0;
318
        blt_con1 <= 16'd0;
319
        blt_size <= 16'd0;
320
        blt_width_in_words <= 6'd0;
321
        a_dat <= 64'd0;
322
        b_dat <= 64'd0;
323
        c_dat <= 48'd0;
324
        a_mod <= 16'd0;
325
        b_mod <= 16'd0;
326
        c_mod <= 16'd0;
327
        d_mod <= 16'd0;
328
        a_address <= 32'd0;
329
        b_address <= 32'd0;
330
        c_address <= 32'd0;
331
        d_address <= 32'd0;
332
        a_shift_saved <= 4'd0;
333
        b_shift_saved <= 4'd0;
334
 
335
        a_avail <= 2'd0;
336
        b_avail <= 2'd0;
337
        c_avail <= 2'd0;
338
        line_single <= 1'b0;
339
        fill_carry <= 1'b0;
340
 
341
        max_width <= 1'b0;
342
 
343
        state <= S_IDLE;
344
    end
345
    else begin
346
 
347
        if(CYC_I == 1'b1 && STB_I == 1'b1 && /*WE_I == 1'b1 &&*/ ACK_O == 1'b0) ACK_O <= 1'b1;
348
        else ACK_O <= 1'b0;
349
 
350
        if(blitter_irq == 1'b1) blitter_irq <= 1'b0;
351
 
352
        // 040:     BLTCON0,    BLTCON1,
353
        // 044:     BLTAFWM,    BLTALWM,
354
        // 048:     BLTCPTH,    BLTCPTL,
355
        // 04C:     BLTBPTH,    BLTBPTL,
356
        // 050:     BLTAPTH,    BLTAPTL,
357
        // 054:     BLTDPTH,    BLTDPTL,
358
        // 058:     BLTSIZE,    not used
359
        // 060:     BLTCMOD,    BLTBMOD,
360
        // 064:     BLTAMOD,    BLTDMOD,
361
        // 070:     BLTCDAT,    BLTBDAT,
362
        // 074:     BLTADAT,    not used,
363
        if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1) begin
364
            if({ ADR_I, 2'b0 } == 9'h040 && SEL_I[0] == 1'b1)  blt_con1[7:0]   <= slave_DAT_I[7:0];
365
            if({ ADR_I, 2'b0 } == 9'h040 && SEL_I[1] == 1'b1)  blt_con1[15:8]  <= slave_DAT_I[15:8];
366
            if({ ADR_I, 2'b0 } == 9'h040 && SEL_I[2] == 1'b1)  blt_con0[7:0]   <= slave_DAT_I[23:16];
367
            if({ ADR_I, 2'b0 } == 9'h040 && SEL_I[3] == 1'b1)  blt_con0[15:8]  <= slave_DAT_I[31:24];
368
            if({ ADR_I, 2'b0 } == 9'h044 && SEL_I[0] == 1'b1)  a_last_word_mask[7:0]   <= slave_DAT_I[7:0];
369
            if({ ADR_I, 2'b0 } == 9'h044 && SEL_I[1] == 1'b1)  a_last_word_mask[15:8]  <= slave_DAT_I[15:8];
370
            if({ ADR_I, 2'b0 } == 9'h044 && SEL_I[2] == 1'b1)  a_first_word_mask[7:0]  <= slave_DAT_I[23:16];
371
            if({ ADR_I, 2'b0 } == 9'h044 && SEL_I[3] == 1'b1)  a_first_word_mask[15:8] <= slave_DAT_I[31:24];
372
            if({ ADR_I, 2'b0 } == 9'h048 && SEL_I[0] == 1'b1)  c_address[7:0]  <= slave_DAT_I[7:0];
373
            if({ ADR_I, 2'b0 } == 9'h048 && SEL_I[1] == 1'b1)  c_address[15:8] <= slave_DAT_I[15:8];
374
            if({ ADR_I, 2'b0 } == 9'h048 && SEL_I[2] == 1'b1)  c_address[23:16]<= slave_DAT_I[23:16];
375
            if({ ADR_I, 2'b0 } == 9'h048 && SEL_I[3] == 1'b1)  c_address[31:24]<= slave_DAT_I[31:24];
376
            if({ ADR_I, 2'b0 } == 9'h04C && SEL_I[0] == 1'b1)  b_address[7:0]  <= slave_DAT_I[7:0];
377
            if({ ADR_I, 2'b0 } == 9'h04C && SEL_I[1] == 1'b1)  b_address[15:8] <= slave_DAT_I[15:8];
378
            if({ ADR_I, 2'b0 } == 9'h04C && SEL_I[2] == 1'b1)  b_address[23:16]<= slave_DAT_I[23:16];
379
            if({ ADR_I, 2'b0 } == 9'h04C && SEL_I[3] == 1'b1)  b_address[31:24]<= slave_DAT_I[31:24];
380
            if({ ADR_I, 2'b0 } == 9'h050 && SEL_I[0] == 1'b1)  a_address[7:0]  <= slave_DAT_I[7:0];
381
            if({ ADR_I, 2'b0 } == 9'h050 && SEL_I[1] == 1'b1)  a_address[15:8] <= slave_DAT_I[15:8];
382
            if({ ADR_I, 2'b0 } == 9'h050 && SEL_I[2] == 1'b1)  a_address[23:16]<= slave_DAT_I[23:16];
383
            if({ ADR_I, 2'b0 } == 9'h050 && SEL_I[3] == 1'b1)  a_address[31:24]<= slave_DAT_I[31:24];
384
            if({ ADR_I, 2'b0 } == 9'h054 && SEL_I[0] == 1'b1)  d_address[7:0]  <= slave_DAT_I[7:0];
385
            if({ ADR_I, 2'b0 } == 9'h054 && SEL_I[1] == 1'b1)  d_address[15:8] <= slave_DAT_I[15:8];
386
            if({ ADR_I, 2'b0 } == 9'h054 && SEL_I[2] == 1'b1)  d_address[23:16]<= slave_DAT_I[23:16];
387
            if({ ADR_I, 2'b0 } == 9'h054 && SEL_I[3] == 1'b1)  d_address[31:24]<= slave_DAT_I[31:24];
388
            if({ ADR_I, 2'b0 } == 9'h058 && SEL_I[0] == 1'b1)  ;
389
            if({ ADR_I, 2'b0 } == 9'h058 && SEL_I[1] == 1'b1)  ;
390
            if({ ADR_I, 2'b0 } == 9'h058 && SEL_I[2] == 1'b1)  blt_size[7:0]    <= slave_DAT_I[23:16];
391
            if({ ADR_I, 2'b0 } == 9'h058 && SEL_I[3] == 1'b1)  blt_size[15:8]   <= slave_DAT_I[31:24];
392
            if({ ADR_I, 2'b0 } == 9'h060 && SEL_I[0] == 1'b1)  b_mod[7:0]       <= { slave_DAT_I[7:1], 1'b0 };
393
            if({ ADR_I, 2'b0 } == 9'h060 && SEL_I[1] == 1'b1)  b_mod[15:8]      <= slave_DAT_I[15:8];
394
            if({ ADR_I, 2'b0 } == 9'h060 && SEL_I[2] == 1'b1)  c_mod[7:0]       <= { slave_DAT_I[23:17], 1'b0 };
395
            if({ ADR_I, 2'b0 } == 9'h060 && SEL_I[3] == 1'b1)  c_mod[15:8]      <= slave_DAT_I[31:24];
396
            if({ ADR_I, 2'b0 } == 9'h064 && SEL_I[0] == 1'b1)  d_mod[7:0]       <= { slave_DAT_I[7:1], 1'b0 };
397
            if({ ADR_I, 2'b0 } == 9'h064 && SEL_I[1] == 1'b1)  d_mod[15:8]      <= slave_DAT_I[15:8];
398
            if({ ADR_I, 2'b0 } == 9'h064 && SEL_I[2] == 1'b1)  a_mod[7:0]       <= { slave_DAT_I[23:17], 1'b0 };
399
            if({ ADR_I, 2'b0 } == 9'h064 && SEL_I[3] == 1'b1)  a_mod[15:8]      <= slave_DAT_I[31:24];
400
 
401
            if({ ADR_I, 2'b0 } == 9'h070 && SEL_I[0] == 1'b1) begin
402
                b_dat[39:32]   <= slave_DAT_I[7:0];
403
                b_dat[23:16]   <= slave_DAT_I[7:0];
404
            end
405
            if({ ADR_I, 2'b0 } == 9'h070 && SEL_I[1] == 1'b1) begin
406
                b_dat[47:40]  <= slave_DAT_I[15:8];
407
                b_dat[31:24]  <= slave_DAT_I[15:8];
408
            end
409
            if({ ADR_I, 2'b0 } == 9'h070 && SEL_I[2] == 1'b1) begin
410
                c_dat[39:32]  <= slave_DAT_I[23:16];
411
                c_dat[7:0]  <= slave_DAT_I[23:16];
412
            end
413
            if({ ADR_I, 2'b0 } == 9'h070 && SEL_I[3] == 1'b1) begin
414
                c_dat[47:40] <= slave_DAT_I[31:24];
415
                c_dat[15:8] <= slave_DAT_I[31:24];
416
            end
417
            if({ ADR_I, 2'b0 } == 9'h074 && SEL_I[0] == 1'b1)  ;
418
            if({ ADR_I, 2'b0 } == 9'h074 && SEL_I[1] == 1'b1)  ;
419
 
420
            if({ ADR_I, 2'b0 } == 9'h074 && SEL_I[2] == 1'b1) begin
421
                a_dat[39:32] <= slave_DAT_I[23:16];
422
                a_dat[23:16] <= slave_DAT_I[23:16];
423
            end
424
            if({ ADR_I, 2'b0 } == 9'h074 && SEL_I[3] == 1'b1) begin
425
                a_dat[47:40] <= slave_DAT_I[31:24];
426
                a_dat[31:24] <= slave_DAT_I[31:24];
427
            end
428
 
429
            if({ ADR_I, 2'b0 } == 9'h074 && SEL_I[3:2] != 2'b00)   a_shift_saved <= blt_con0[15:12];
430
            if({ ADR_I, 2'b0 } == 9'h070 && SEL_I[1:0] != 2'b00)   b_shift_saved <= blt_con1[15:12];
431
 
432
 
433
 
434
 
435
            if(/*state == S_IDLE &&*/ { ADR_I, 2'b0 } == 9'h058 && SEL_I[3:2] == 2'b11 /*&&
436
                slave_DAT_I[21:16] != 6'd0 && slave_DAT_I[31:22] != 10'd0*/)
437
            begin
438
                CYC_O <= 1'b0;
439
                STB_O <= 1'b0;
440
 
441
                blt_width_in_words[5:0]  <= slave_DAT_I[21:16];
442
                if(slave_DAT_I[21:16] == 6'd0) max_width <= 1'b1;
443
                if(blt_con1[0] == 1'b0 && a_enabled == 1'b0) a_shift_saved <= blt_con0[15:12];
444
                if(blt_con1[0] == 1'b0 && b_enabled == 1'b0) b_shift_saved <= blt_con1[15:12];
445
 
446
                if(blt_con1[0] == 1'b1) begin
447
                    a_dat[63:48] <= 16'd0;
448
                    b_dat[63:48] <= b_dat[47:32];
449
                    a_shift_saved <= blt_con0[15:12];
450
                end
451
                else if(reverse == 1'b0) begin
452
                    a_dat[63:48] <= 16'd0;
453
                    b_dat[63:48] <= 16'd0;
454
                end
455
                else begin
456
                    a_dat[15:0] <= 16'd0;
457
                    b_dat[15:0] <= 16'd0;
458
                end
459
                blitter_zero <= 1'b1;
460
                blitter_busy <= 1'b1;
461
                a_avail <= 2'd0;
462
                b_avail <= 2'd0;
463
                c_avail <= 2'd0;
464
                master_DAT_O <= 32'd0;
465
                line_single <= 1'b0;
466
                fill_carry <= blt_con1[2];
467
 
468
                state <= S_CHECK_LOAD;
469
            end
470
        end
471
        else if(state == S_CHECK_LOAD) begin
472
 
473
            if(a_enabled == 1'b1 && a_avail < 2'd2)         state <= S_LOAD_A;
474
            else if(b_enabled == 1'b1 && b_avail < 2'd2)    state <= S_LOAD_B;
475
            else if(c_enabled &&
476
                ((blt_con1[0] == 1'b0 && c_avail < 2'd2) ||
477
                 (blt_con1[0] == 1'b1 && c_avail < 2'd1)))  state <= S_LOAD_C;
478
            else                                            state <= S_CHECK_SAVE;
479
        end
480
        // read max 48 bits
481
        else if(state == S_LOAD_A) begin
482
 
483
            if(ACK_I == 1'b1) begin
484
                CYC_O <= 1'b0;
485
                STB_O <= 1'b0;
486
/*
487
                    if(reverse == 1'b0) begin
488
                        a_address <= a_address + { {16{a_mod[15]}}, a_mod };
489
                        b_address <= b_address + { {16{b_mod[15]}}, b_mod };
490
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod };
491
                        d_address <= d_address + { {16{d_mod[15]}}, d_mod };
492
                    end
493
                    else begin
494
                        a_address <= a_address - { {16{a_mod[15]}}, a_mod };
495
                        b_address <= b_address - { {16{b_mod[15]}}, b_mod };
496
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod };
497
                        d_address <= d_address - { {16{d_mod[15]}}, d_mod };
498
                    end
499
*/
500
                a_shift_saved <= blt_con0[15:12];
501
 
502
                a_avail <= a_avail + 2'd1;
503
 
504
                if(reverse == 1'b0) begin
505
                    if(a_avail == 2'd1 && blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)    a_address <= a_address + { {16{a_mod[15]}}, a_mod };
506
                    else if(blt_size[5:0] == 6'd1)                                                  a_address <= a_address + 32'd2 + { {16{a_mod[15]}}, a_mod };
507
                    else if(a_avail == 2'd1 && blt_width_in_words == 6'd2)                          a_address <= a_address + 32'd2 + { {16{a_mod[15]}}, a_mod };
508
                    else                                                                            a_address <= a_address + 32'd2;
509
 
510
                    if(a_avail == 2'd0) begin
511
                        a_dat[47:32] <=     a_first_word_mask &
512
                                            ((blt_width_in_words == 6'd1)? a_last_word_mask : 16'hFFFF ) &
513
                                            ((a_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
514
                    end
515
                    else if(a_avail == 2'd1) begin
516
                        a_dat[31:16] <=     ((blt_width_in_words == 6'd1)? a_first_word_mask : 16'hFFFF ) &
517
                                            ((blt_width_in_words == 6'd2 || blt_size[5:0] == 6'd1)? a_last_word_mask : 16'hFFFF ) &
518
                                            ((a_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
519
                    end
520
                end
521
                else begin
522
                    if(a_avail == 2'd1 && blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)    a_address <= a_address - { {16{a_mod[15]}}, a_mod };
523
                    else if(blt_size[5:0] == 6'd1)                                                  a_address <= a_address - 32'd2 - { {16{a_mod[15]}}, a_mod };
524
                    else if(a_avail == 2'd1 && blt_width_in_words == 6'd2)                          a_address <= a_address - 32'd2 - { {16{a_mod[15]}}, a_mod };
525
                    else                                                                            a_address <= a_address - 32'd2;
526
 
527
 
528
                    if(a_avail == 2'd0) begin
529
                        a_dat[31:16] <=     a_first_word_mask &
530
                                            ((blt_width_in_words == 6'd1)? a_last_word_mask : 16'hFFFF ) &
531
                                            ((a_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
532
                    end
533
                    else if(a_avail == 2'd1) begin
534
                        a_dat[47:32] <=     ((blt_width_in_words == 6'd1)? a_first_word_mask : 16'hFFFF ) &
535
                                            ((blt_width_in_words == 6'd2 || blt_size[5:0] == 6'd1)? a_last_word_mask : 16'hFFFF ) &
536
                                            ((a_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
537
                    end
538
                end
539
 
540
                state <= S_CHECK_LOAD;
541
            end
542
            else begin
543
                CYC_O <= 1'b1;
544
                STB_O <= 1'b1;
545
                WE_O <= 1'b0;
546
                ADR_O <= { 11'b0, a_address[20:2] };
547
                SEL_O <= 4'b1111;
548
            end
549
        end
550
        // read max 48 bits
551
        else if(state == S_LOAD_B) begin
552
 
553
            if(ACK_I == 1'b1) begin
554
                CYC_O <= 1'b0;
555
                STB_O <= 1'b0;
556
 
557
                b_shift_saved <= blt_con1[15:12];
558
                b_avail <= b_avail + 2'd1;
559
 
560
                if(reverse == 1'b0) begin
561
                    if(b_avail == 2'd1 && blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)    b_address <= b_address + { {16{b_mod[15]}}, b_mod };
562
                    else if(blt_size[5:0] == 6'd1)                                                  b_address <= b_address + 32'd2 + { {16{b_mod[15]}}, b_mod };
563
                    else if(b_avail == 2'd1 && blt_width_in_words == 6'd2)                          b_address <= b_address + 32'd2 + { {16{b_mod[15]}}, b_mod };
564
                    else                                                                            b_address <= b_address + 32'd2;
565
 
566
                    if(b_avail == 2'd0) begin
567
                        b_dat[47:32] <=     ((b_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
568
                    end
569
                    else if(b_avail == 2'd1) begin
570
                        b_dat[31:16] <=     ((b_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
571
                    end
572
                end
573
                else begin
574
                    if(b_avail == 2'd1 && blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)    b_address <= b_address - { {16{b_mod[15]}}, b_mod };
575
                    else if(blt_size[5:0] == 6'd1)                                                  b_address <= b_address - 32'd2 - { {16{b_mod[15]}}, b_mod };
576
                    else if(b_avail == 2'd1 && blt_width_in_words == 6'd2)                          b_address <= b_address - 32'd2 - { {16{b_mod[15]}}, b_mod };
577
                    else                                                                            b_address <= b_address - 32'd2;
578
 
579
                    if(b_avail == 2'd0) begin
580
                        b_dat[31:16] <=     ((b_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
581
                    end
582
                    else if(b_avail == 2'd1) begin
583
                        b_dat[47:32] <=     ((b_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
584
                    end
585
                end
586
 
587
                state <= S_CHECK_LOAD;
588
            end
589
            else begin
590
                CYC_O <= 1'b1;
591
                STB_O <= 1'b1;
592
                WE_O <= 1'b0;
593
                ADR_O <= { 11'b0, b_address[20:2] };
594
                SEL_O <= 4'b1111;
595
            end
596
        end
597
        // read max 48 bits
598
        else if(state == S_LOAD_C) begin
599
 
600
            if(ACK_I == 1'b1) begin
601
                CYC_O <= 1'b0;
602
                STB_O <= 1'b0;
603
 
604
                c_avail <= c_avail + 2'd1;
605
 
606
                if(reverse == 1'b0) begin
607
                    if(blt_con1[0] == 1'b1)                                                             ;
608
                    else if(c_avail == 2'd1 && blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)   c_address <= c_address + { {16{c_mod[15]}}, c_mod };
609
                    else if(blt_size[5:0] == 6'd1)                                                      c_address <= c_address + 32'd2 + { {16{c_mod[15]}}, c_mod };
610
                    else if(c_avail == 2'd1 && blt_width_in_words == 6'd2)                              c_address <= c_address + 32'd2 + { {16{c_mod[15]}}, c_mod };
611
                    else                                                                                c_address <= c_address + 32'd2;
612
 
613
                    if(c_avail == 2'd0) begin
614
                        c_dat[47:32] <=     ((c_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
615
                    end
616
                    else if(c_avail == 2'd1) begin
617
                        c_dat[31:16] <=     ((c_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
618
                    end
619
                end
620
                else begin
621
                    if(blt_con1[0] == 1'b1)                                                             ;
622
                    else if(c_avail == 2'd1 && blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)   c_address <= c_address - { {16{c_mod[15]}}, c_mod };
623
                    else if(blt_size[5:0] == 6'd1)                                                      c_address <= c_address - 32'd2 - { {16{c_mod[15]}}, c_mod };
624
                    else if(c_avail == 2'd1 && blt_width_in_words == 6'd2)                              c_address <= c_address - 32'd2 - { {16{c_mod[15]}}, c_mod };
625
                    else                                                                                c_address <= c_address - 32'd2;
626
 
627
                    if(c_avail == 2'd0) begin
628
                        c_dat[15:0] <=     ((c_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
629
                    end
630
                    else if(c_avail == 2'd1) begin
631
                        c_dat[31:16] <=     ((c_address[1] == 1'b0)? master_DAT_I[31:16] : master_DAT_I[15:0]);
632
                    end
633
                end
634
 
635
                state <= S_CHECK_LOAD;
636
            end
637
            else begin
638
                CYC_O <= 1'b1;
639
                STB_O <= 1'b1;
640
                WE_O <= 1'b0;
641
                ADR_O <= { 11'b0, c_address[20:2] };
642
                SEL_O <= 4'b1111;
643
            end
644
        end
645
        else if(state == S_CHECK_SAVE) begin
646
 
647
            // in LINE mode
648
            if(blt_con1[0] == 1'b1) begin
649
                if((blt_width_in_words > 6'd0 || max_width == 1'b1) && (blt_size[15:6] > 10'd1 || blt_size[15:6] == 10'd0)) begin
650
 
651
                    master_DAT_O <= (d_address[1] == 1'b1) ? { 16'b0, final_output } : { final_output, 16'b0 };
652
 
653
                    if(a_address[15] == 1'b1)   a_address[31:0] <= a_address[31:0] + { {16{b_mod[15]}}, b_mod[15:0] };
654
                    else                        a_address[31:0] <= a_address[31:0] + { {16{a_mod[15]}}, a_mod[15:0] };
655
 
656
                    b_shift_saved <= b_shift_saved - 4'd1;
657
 
658
                    // octet0
659
                    if(blt_con1[4:2] == 3'd6 && a_address[15] == 1'b1 && a_shift_saved != 4'd15) begin
660
                        // no address change
661
                        a_shift_saved <= a_shift_saved + 4'd1;
662
                        c_dat[47:32] <= final_output;
663
                        if(blt_con1[1] == 1'b1) line_single <= 1'b1;
664
                        blt_size[15:6] <= blt_size[15:6] - 10'd1;
665
                    end
666
                    else if(blt_con1[4:2] == 3'd6 && a_address[15] == 1'b1 && a_shift_saved == 4'd15) begin
667
                        c_address <= c_address + 32'd2;
668
                        a_shift_saved <= a_shift_saved + 4'd1;
669
                        if(blt_con1[1] == 1'b1) line_single <= 1'b1;
670
                        state <= S_SAVE_D;
671
                    end
672
                    else if(blt_con1[4:2] == 3'd6 && a_address[15] == 1'b0 && a_shift_saved != 4'd15) begin
673
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod[15:0] };
674
                        a_shift_saved <= a_shift_saved + 4'd1;
675
                        line_single <= 1'b0;
676
                        state <= S_SAVE_D;
677
                    end
678
                    else if(blt_con1[4:2] == 3'd6 && a_address[15] == 1'b0 && a_shift_saved == 4'd15) begin
679
                        c_address <= c_address + 32'd2 - { {16{c_mod[15]}}, c_mod[15:0] };
680
                        a_shift_saved <= a_shift_saved + 4'd1;
681
                        line_single <= 1'b0;
682
                        state <= S_SAVE_D;
683
                    end
684
 
685
                    // octet1
686
                    else if(blt_con1[4:2] == 3'd1 && a_address[15] == 1'b1 && a_shift_saved != 4'd15) begin
687
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod[15:0] };
688
                        // no shift
689
                        line_single <= 1'b0;
690
                        state <= S_SAVE_D;
691
                    end
692
                    else if(blt_con1[4:2] == 3'd1 && a_address[15] == 1'b1 && a_shift_saved == 4'd15) begin
693
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod[15:0] };
694
                        // no shift
695
                        line_single <= 1'b0;
696
                        state <= S_SAVE_D;
697
                    end
698
                    else if(blt_con1[4:2] == 3'd1 && a_address[15] == 1'b0 && a_shift_saved != 4'd15) begin
699
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod[15:0] };
700
                        a_shift_saved <= a_shift_saved + 4'd1;
701
                        line_single <= 1'b0;
702
                        state <= S_SAVE_D;
703
                    end
704
                    else if(blt_con1[4:2] == 3'd1 && a_address[15] == 1'b0 && a_shift_saved == 4'd15) begin
705
                        c_address <= c_address + 32'd2 - { {16{c_mod[15]}}, c_mod[15:0] };
706
                        a_shift_saved <= a_shift_saved + 4'd1;
707
                        line_single <= 1'b0;
708
                        state <= S_SAVE_D;
709
                    end
710
 
711
                    // octet2
712
                    else if(blt_con1[4:2] == 3'd3 && a_address[15] == 1'b1 && a_shift_saved != 4'd0) begin
713
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod[15:0] };
714
                        // no shift
715
                        line_single <= 1'b0;
716
                        state <= S_SAVE_D;
717
                    end
718
                    else if(blt_con1[4:2] == 3'd3 && a_address[15] == 1'b1 && a_shift_saved == 4'd0) begin
719
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod[15:0] };
720
                        // no shift
721
                        line_single <= 1'b0;
722
                        state <= S_SAVE_D;
723
                    end
724
                    else if(blt_con1[4:2] == 3'd3 && a_address[15] == 1'b0 && a_shift_saved != 4'd0) begin
725
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod[15:0] };
726
                        a_shift_saved <= a_shift_saved - 4'd1;
727
                        line_single <= 1'b0;
728
                        state <= S_SAVE_D;
729
                    end
730
                    else if(blt_con1[4:2] == 3'd3 && a_address[15] == 1'b0 && a_shift_saved == 4'd0) begin
731
                        c_address <= c_address - 32'd2 - { {16{c_mod[15]}}, c_mod[15:0] };
732
                        a_shift_saved <= a_shift_saved - 4'd1;
733
                        line_single <= 1'b0;
734
                        state <= S_SAVE_D;
735
                    end
736
 
737
                    // octet3
738
                    else if(blt_con1[4:2] == 3'd7 && a_address[15] == 1'b1 && a_shift_saved != 4'd0) begin
739
                        // no address change
740
                        a_shift_saved <= a_shift_saved - 4'd1;
741
                        c_dat[47:32] <= final_output;
742
                        if(blt_con1[1] == 1'b1) line_single <= 1'b1;
743
                        blt_size[15:6] <= blt_size[15:6] - 10'd1;
744
                    end
745
                    else if(blt_con1[4:2] == 3'd7 && a_address[15] == 1'b1 && a_shift_saved == 4'd0) begin
746
                        c_address <= c_address - 32'd2;
747
                        a_shift_saved <= a_shift_saved - 4'd1;
748
                        if(blt_con1[1] == 1'b1) line_single <= 1'b1;
749
                        state <= S_SAVE_D;
750
                    end
751
                    else if(blt_con1[4:2] == 3'd7 && a_address[15] == 1'b0 && a_shift_saved != 4'd0) begin
752
                        c_address <= c_address - { {16{c_mod[15]}}, c_mod[15:0] };
753
                        a_shift_saved <= a_shift_saved - 4'd1;
754
                        line_single <= 1'b0;
755
                        state <= S_SAVE_D;
756
                    end
757
                    else if(blt_con1[4:2] == 3'd7 && a_address[15] == 1'b0 && a_shift_saved == 4'd0) begin
758
                        c_address <= c_address - 32'd2 - { {16{c_mod[15]}}, c_mod[15:0] };
759
                        a_shift_saved <= a_shift_saved - 4'd1;
760
                        line_single <= 1'b0;
761
                        state <= S_SAVE_D;
762
                    end
763
 
764
                    // octet4
765
                    else if(blt_con1[4:2] == 3'd5 && a_address[15] == 1'b1 && a_shift_saved != 4'd0) begin
766
                        // no address change
767
                        a_shift_saved <= a_shift_saved - 4'd1;
768
                        c_dat[47:32] <= final_output;
769
                        if(blt_con1[1] == 1'b1) line_single <= 1'b1;
770
                        blt_size[15:6] <= blt_size[15:6] - 10'd1;
771
                    end
772
                    else if(blt_con1[4:2] == 3'd5 && a_address[15] == 1'b1 && a_shift_saved == 4'd0) begin
773
                        c_address <= c_address - 32'd2;
774
                        a_shift_saved <= a_shift_saved - 4'd1;
775
                        if(blt_con1[1] == 1'b1) line_single <= 1'b1;
776
                        state <= S_SAVE_D;
777
                    end
778
                    else if(blt_con1[4:2] == 3'd5 && a_address[15] == 1'b0 && a_shift_saved != 4'd0) begin
779
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod[15:0] };
780
                        a_shift_saved <= a_shift_saved - 4'd1;
781
                        line_single <= 1'b0;
782
                        state <= S_SAVE_D;
783
                    end
784
                    else if(blt_con1[4:2] == 3'd5 && a_address[15] == 1'b0 && a_shift_saved == 4'd0) begin
785
                        c_address <= c_address - 32'd2 + { {16{c_mod[15]}}, c_mod[15:0] };
786
                        a_shift_saved <= a_shift_saved - 4'd1;
787
                        line_single <= 1'b0;
788
                        state <= S_SAVE_D;
789
                    end
790
 
791
                    // octet5
792
                    else if(blt_con1[4:2] == 3'd2 && a_address[15] == 1'b1 && a_shift_saved != 4'd0) begin
793
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod[15:0] };
794
                        // no shift
795
                        line_single <= 1'b0;
796
                        state <= S_SAVE_D;
797
                    end
798
                    else if(blt_con1[4:2] == 3'd2 && a_address[15] == 1'b1 && a_shift_saved == 4'd0) begin
799
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod[15:0] };
800
                        // no shift
801
                        line_single <= 1'b0;
802
                        state <= S_SAVE_D;
803
                    end
804
                    else if(blt_con1[4:2] == 3'd2 && a_address[15] == 1'b0 && a_shift_saved != 4'd0) begin
805
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod[15:0] };
806
                        a_shift_saved <= a_shift_saved - 4'd1;
807
                        line_single <= 1'b0;
808
                        state <= S_SAVE_D;
809
                    end
810
                    else if(blt_con1[4:2] == 3'd2 && a_address[15] == 1'b0 && a_shift_saved == 4'd0) begin
811
                        c_address <= c_address - 32'd2 + { {16{c_mod[15]}}, c_mod[15:0] };
812
                        a_shift_saved <= a_shift_saved - 4'd1;
813
                        line_single <= 1'b0;
814
                        state <= S_SAVE_D;
815
                    end
816
 
817
                    // octet6
818
                    else if(blt_con1[4:2] == 3'd0 && a_address[15] == 1'b1 && a_shift_saved != 4'd15) begin
819
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod[15:0] };
820
                        // no shift
821
                        line_single <= 1'b0;
822
                        state <= S_SAVE_D;
823
                    end
824
                    else if(blt_con1[4:2] == 3'd0 && a_address[15] == 1'b1 && a_shift_saved == 4'd15) begin
825
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod[15:0] };
826
                        // no shift
827
                        line_single <= 1'b0;
828
                        state <= S_SAVE_D;
829
                    end
830
                    else if(blt_con1[4:2] == 3'd0 && a_address[15] == 1'b0 && a_shift_saved != 4'd15) begin
831
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod[15:0] };
832
                        a_shift_saved <= a_shift_saved + 4'd1;
833
                        line_single <= 1'b0;
834
                        state <= S_SAVE_D;
835
                    end
836
                    else if(blt_con1[4:2] == 3'd0 && a_address[15] == 1'b0 && a_shift_saved == 4'd15) begin
837
                        c_address <= c_address + 32'd2 + { {16{c_mod[15]}}, c_mod[15:0] };
838
                        a_shift_saved <= a_shift_saved + 4'd1;
839
                        line_single <= 1'b0;
840
                        state <= S_SAVE_D;
841
                    end
842
 
843
                    // octet7
844
                    else if(blt_con1[4:2] == 3'd4 && a_address[15] == 1'b1 && a_shift_saved != 4'd15) begin
845
                        // no address change
846
                        a_shift_saved <= a_shift_saved + 4'd1;
847
                        c_dat[47:32] <= final_output;
848
                        if(blt_con1[1] == 1'b1) line_single <= 1'b1;
849
                        blt_size[15:6] <= blt_size[15:6] - 10'd1;
850
                    end
851
                    else if(blt_con1[4:2] == 3'd4 && a_address[15] == 1'b1 && a_shift_saved == 4'd15) begin
852
                        c_address <= c_address + 32'd2;
853
                        a_shift_saved <= a_shift_saved + 4'd1;
854
                        if(blt_con1[1] == 1'b1) line_single <= 1'b1;
855
                        state <= S_SAVE_D;
856
                    end
857
                    else if(blt_con1[4:2] == 3'd4 && a_address[15] == 1'b0 && a_shift_saved != 4'd15) begin
858
                        c_address <= c_address + { {16{c_mod[15]}}, c_mod[15:0] };
859
                        a_shift_saved <= a_shift_saved + 4'd1;
860
                        line_single <= 1'b0;
861
                        state <= S_SAVE_D;
862
                    end
863
                    else if(blt_con1[4:2] == 3'd4 && a_address[15] == 1'b0 && a_shift_saved == 4'd15) begin
864
                        c_address <= c_address + 32'd2 + { {16{c_mod[15]}}, c_mod[15:0] };
865
                        a_shift_saved <= a_shift_saved + 4'd1;
866
                        line_single <= 1'b0;
867
                        state <= S_SAVE_D;
868
                    end
869
 
870
                end
871
                else if((blt_width_in_words > 6'd0 || max_width == 1'b1) && blt_size[15:6] == 10'd1) begin
872
                    master_DAT_O <= (d_address[1] == 1'b1) ? { 16'b0, final_output } : { final_output, 16'b0 };
873
                    state <= S_SAVE_D;
874
                end
875
                // after save
876
                else if(blt_width_in_words == 6'd0 && (blt_size[15:6] > 10'd1 || blt_size[15:6] == 10'd0)) begin
877
                    blt_size[15:6] <= blt_size[15:6] - 10'd1;
878
                    blt_width_in_words  <= blt_size[5:0];
879
                    if(blt_size[5:0] == 6'd0) max_width <= 1'b1;
880
                    c_avail <= 2'd0;
881
                    d_address <= c_address;
882
                    //if(blt_con1[1] == 1'b1 && c_address == d_address) line_single <= 1'b1;
883
 
884
                    state <= S_CHECK_LOAD;
885
                end
886
                // finish
887
                else if(blt_width_in_words == 6'd0 && blt_size[15:6] == 10'd1) begin
888
                    blt_con0[15:12] <= 4'd0;
889
 
890
                    blitter_busy <= 1'b0;
891
                    blitter_irq <= 1'b1;
892
                    state <= S_IDLE;
893
                end
894
            end
895
            else begin
896
                if( (blt_width_in_words > 6'd0 || max_width == 1'b1) &&
897
                    (a_enabled == 1'b0 || a_avail > 2'd1) &&
898
                    (b_enabled == 1'b0 || b_avail > 2'd1) &&
899
                    (c_enabled == 1'b0 || c_avail > 2'd1))
900
                begin
901
                    master_DAT_O <= (d_address[1] == 1'b1) ? { 16'b0, final_output } : { final_output, 16'b0 };
902
                    fill_carry <= fill_carry ^ xor_chains[15] ^ minterm_output[15];
903
                    state <= S_SAVE_D;
904
                end
905
                else if(blt_width_in_words == 6'd0 && blt_size[15:6] == 10'd1) begin
906
                    blitter_busy <= 1'b0;
907
                    blitter_irq <= 1'b1;
908
                    state <= S_IDLE;
909
                end
910
                else if(blt_width_in_words == 6'd0 && (blt_size[15:6] > 10'd1 || blt_size[15:6] == 10'd0)) begin
911
                    blt_width_in_words  <= blt_size[5:0];
912
                    if(blt_size[5:0] == 6'd0) max_width <= 1'b1;
913
 
914
                    fill_carry <= blt_con1[2];
915
 
916
                    if(reverse == 1'b0) begin
917
                        d_address <= d_address + { {16{d_mod[15]}}, d_mod };
918
                    end
919
                    else begin
920
                        d_address <= d_address - { {16{d_mod[15]}}, d_mod };
921
                    end
922
 
923
                    blt_size[15:6] <= blt_size[15:6] - 10'd1;
924
                    state <= S_CHECK_LOAD;
925
                end
926
                else begin
927
                    state <= S_CHECK_LOAD;
928
                end
929
            end
930
        end
931
        else if(state == S_SAVE_D) begin
932
 
933
            if(ACK_I == 1'b1 || d_enabled == 1'b0) begin
934
                CYC_O <= 1'b0;
935
                STB_O <= 1'b0;
936
 
937
                if(a_enabled == 1'b0) begin
938
                    if(reverse == 1'b0)     a_dat[63:48] <= a_dat_final[47:32];
939
                    else                    a_dat[15:0] <= a_dat_final[31:16];
940
                end
941
                else if(reverse == 1'b0) begin
942
                    if(blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)   a_dat <= { a_dat[47:32], a_dat[47:32], a_dat[47:32], a_dat[47:32] };
943
                    else                                                        a_dat <= { a_dat_final[47:0], 16'b0 };
944
                    a_avail <= a_avail - 2'd1;
945
                end
946
                else if(reverse == 1'b1) begin
947
                    if(blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)   a_dat <= { a_dat[31:16], a_dat[31:16], a_dat[31:16], a_dat[31:16] };
948
                    else                                                        a_dat <= { 16'b0, a_dat_final[63:16] };
949
                    a_avail <= a_avail - 2'd1;
950
                end
951
 
952
                if(b_enabled == 1'b0) begin
953
                    if(reverse == 1'b0)     b_dat[63:48] <= b_dat[47:32];
954
                    else                    b_dat[15:0] <= b_dat[31:16];
955
                end
956
                else if(reverse == 1'b0) begin
957
                    if(blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)   b_dat <= { b_dat[47:32], b_dat[47:32], b_dat[47:32], b_dat[47:32] };
958
                    else                                                        b_dat <= { b_dat[47:0], 16'b0 };
959
                    b_avail <= b_avail - 2'd1;
960
                end
961
                else if(reverse == 1'b1) begin
962
                    if(blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)   b_dat <= { b_dat[31:16], b_dat[31:16], b_dat[31:16], b_dat[31:16] };
963
                    else                                                        b_dat <= { 16'b0, b_dat[63:16] };
964
                    b_avail <= b_avail - 2'd1;
965
                end
966
 
967
                if(c_enabled == 1'b0) begin
968
                     //; no shift
969
                end
970
                else if(reverse == 1'b0) begin
971
                    if(blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)   c_dat <= { c_dat[47:32], c_dat[47:32], c_dat[47:32] };
972
                    else                                                        c_dat <= { c_dat[31:0], 16'b0 };
973
                    c_avail <= c_avail - 2'd1;
974
                end
975
                else if(reverse == 1'b1) begin
976
                    if(blt_width_in_words == 6'd1 && blt_size[15:6] == 10'd1)   c_dat <= { c_dat[15:0], c_dat[15:0], c_dat[15:0] };
977
                    else                                                        c_dat <= { 16'b0, c_dat[47:16] };
978
                    c_avail <= c_avail - 2'd1;
979
                end
980
 
981
                if( (d_address[1] == 1'b1 && master_DAT_O[15:0] != 16'd0) ||
982
                    (d_address[1] == 1'b0 && master_DAT_O[31:16] != 16'd0) )
983
                begin
984
                    blitter_zero <= 1'b0;
985
                end
986
 
987
                // update d_address and blt_width_in_words
988
                max_width <= 1'b0;
989
                if(blt_con1[0] == 1'b1) blt_width_in_words <= 6'd0;
990
                else                    blt_width_in_words <= blt_width_in_words - 6'd1;
991
 
992
                if(blt_con1[0] == 1'b1)     ;
993
                else if(reverse == 1'b0)    d_address <= d_address + 32'd2;
994
                else                        d_address <= d_address - 32'd2;
995
 
996
                state <= S_CHECK_SAVE;
997
            end
998
            else begin
999
                CYC_O <= 1'b1;
1000
                STB_O <= 1'b1;
1001
                WE_O <= 1'b1;
1002
                ADR_O <= { 11'b0, d_address[20:2] };
1003
                SEL_O <= (d_address[1] == 1'b1) ? 4'b0011 : 4'b1100;
1004
            end
1005
        end
1006
    end
1007
end
1008
 
1009
endmodule
1010
 

powered by: WebSVN 2.1.0

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