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

Subversion Repositories warp

[/] [warp/] [rtl/] [tmu_meshgen.v] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 lekernel
/*
2
 * Milkymist VJ SoC
3
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
4
 *
5
 * This program is free and excepted software; you can use it, redistribute it
6
 * and/or modify it under the terms of the Exception General Public License as
7
 * published by the Exception License Foundation; either version 2 of the
8
 * License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful, but WITHOUT
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
 * FOR A PARTICULAR PURPOSE. See the Exception General Public License for more
13
 * details.
14
 *
15
 * You should have received a copy of the Exception General Public License along
16
 * with this project; if not, write to the Exception License Foundation.
17
 */
18
 
19
module tmu_meshgen(
20
        input sys_clk,
21
        input sys_rst,
22
 
23
        output reg [31:0] wbm_adr_o,
24
        output [2:0] wbm_cti_o,
25
        output wbm_cyc_o,
26
        output reg wbm_stb_o,
27
        input wbm_ack_i,
28
        input [31:0] wbm_dat_i,
29
 
30
        input start,
31
        output reg busy,
32
 
33
        input [29:0] mesh_base, /* in 32-bit words */
34
        input [6:0] hmesh_count,
35
        input [6:0] hmesh_size,
36
        input [6:0] vmesh_count,
37
        input [6:0] vmesh_size,
38
 
39
        output reg pipe_stb,
40
        input pipe_ack,
41
        output reg [10:0] A_S_X,
42
        output reg [10:0] A_S_Y,
43
        output reg [10:0] B_S_X,
44
        output reg [10:0] B_S_Y,
45
        output reg [10:0] C_S_X,
46
        output reg [10:0] C_S_Y,
47
        output reg [10:0] A_D_X,
48
        output reg [10:0] A_D_Y,
49
        output reg [10:0] B_D_X,
50
        output reg [10:0] B_D_Y,
51
        output reg [10:0] C_D_X,
52
        output reg [10:0] C_D_Y
53
);
54
 
55
/* Burst support for later */
56
assign wbm_cti_o = 3'b000;
57
 
58
assign wbm_cyc_o = wbm_stb_o;
59
 
60
/* DATAPATH: Logo-like graphics in Verilog. */
61
 
62
/* move turtle to the origin */
63
reg move_origin;
64
/* move turtle to the beginning of the line */
65
reg move_linestart;
66
/* move turtle to the right */
67
reg move_right;
68
/* move turtle down */
69
reg move_down;
70
/* move turtle diagonally to the left and down */
71
reg move_leftdown;
72
/* move turtle diagonally to the right and up */
73
reg move_rightup;
74
 
75
/* position of the turtle expressed in mesh coordinates */
76
reg [6:0] turtle_ix;
77
reg [6:0] turtle_iy;
78
/* position of the turtle expressed in source image coordinates
79
 * At all times :
80
 * turtle_x = turtle_ix*hmesh_size
81
 * turtle_y = turtle_iy*vmesh_size
82
 * We generate them concurrently to avoid using a multiplier.
83
 */
84
reg [10:0] turtle_x;
85
reg [10:0] turtle_y;
86
 
87
/* Register the control signals as they tend to be in the critical
88
 * path because of the delay in the ack signal of the bus.
89
 */
90
reg move_origin_r;
91
reg move_linestart_r;
92
reg move_right_r;
93
reg move_down_r;
94
reg move_leftdown_r;
95
reg move_rightup_r;
96
 
97
always @(posedge sys_clk) begin
98
        move_origin_r <= move_origin;
99
        move_linestart_r <= move_linestart;
100
        move_right_r <= move_right;
101
        move_down_r <= move_down;
102
        move_leftdown_r <= move_leftdown;
103
        move_rightup_r <= move_rightup;
104
end
105
 
106
always @(posedge sys_clk) begin
107
        case({move_origin_r, move_linestart_r, move_right_r, move_down_r, move_leftdown_r, move_rightup_r})
108
                6'b100000: begin /* move_origin */
109
                        turtle_ix <= 7'd0;
110
                        turtle_x <= 11'd0;
111
                        turtle_iy <= 7'd0;
112
                        turtle_y <= 11'd0;
113
                end
114
                6'b010000: begin /* move_linestart */
115
                        turtle_ix <= 7'd0;
116
                        turtle_x <= 11'd0;
117
                end
118
                6'b001000: begin /* move_right */
119
                        turtle_ix <= turtle_ix + 7'd1;
120
                        turtle_x <= turtle_x + hmesh_size;
121
                end
122
                6'b000100: begin /* move_down */
123
                        turtle_iy <= turtle_iy + 7'd1;
124
                        turtle_y <= turtle_y + vmesh_size;
125
                end
126
                6'b000010: begin /* move_leftdown */
127
                        turtle_ix <= turtle_ix - 7'd1;
128
                        turtle_x <= turtle_x - hmesh_size;
129
                        turtle_iy <= turtle_iy + 7'd1;
130
                        turtle_y <= turtle_y + vmesh_size;
131
                end
132
                6'b000001: begin /* move_rightup */
133
                        turtle_ix <= turtle_ix + 7'd1;
134
                        turtle_x <= turtle_x + hmesh_size;
135
                        turtle_iy <= turtle_iy - 7'd1;
136
                        turtle_y <= turtle_y - vmesh_size;
137
                end
138
                default:;
139
        endcase
140
end
141
 
142
/* Detect mesh boundaries */
143
wire hlast = turtle_ix == hmesh_count;
144
wire vlast = turtle_iy == vmesh_count;
145
 
146
/* DATAPATH: registered computation of the WB mesh address */
147
wire [31:0] mesh_base32 = {mesh_base, 2'b00};
148
always @(posedge sys_clk)
149
        wbm_adr_o <= mesh_base32 + {turtle_iy, turtle_ix, 2'b00};
150
 
151
reg loadA;
152
reg loadB;
153
reg loadC;
154
always @(posedge sys_clk) begin
155
        if(loadA) begin
156
                A_S_X = turtle_x;
157
                A_S_Y = turtle_y;
158
                A_D_X = wbm_dat_i[10:0];
159
                A_D_Y = wbm_dat_i[26:16];
160
        end
161
        if(loadB) begin
162
                B_S_X = turtle_x;
163
                B_S_Y = turtle_y;
164
                B_D_X = wbm_dat_i[10:0];
165
                B_D_Y = wbm_dat_i[26:16];
166
        end
167
        if(loadC) begin
168
                C_S_X = turtle_x;
169
                C_S_Y = turtle_y;
170
                C_D_X = wbm_dat_i[10:0];
171
                C_D_Y = wbm_dat_i[26:16];
172
        end
173
end
174
 
175
/* THE FSM FROM HELL */
176
 
177
parameter IDLE                  = 6'd0;
178
 
179
parameter LS_WAIT_AADR          = 6'd1;
180
parameter LS_WAIT2_AADR         = 6'd2;
181
parameter LS_LOAD_A             = 6'd3;
182
parameter LS_WAIT_BADR          = 6'd4;
183
parameter LS_WAIT2_BADR         = 6'd5;
184
parameter LS_LOAD_B             = 6'd6;
185
parameter LS_WAIT_CADR          = 6'd7;
186
parameter LS_WAIT2_CADR         = 6'd8;
187
parameter LS_LOAD_C             = 6'd9;
188
 
189
parameter IL1T_WAIT_BADR        = 6'd10;
190
parameter IL1T_WAIT2_BADR       = 6'd11;
191
parameter IL1T_LOAD_B           = 6'd12;
192
parameter IL1T_PIPEOUT          = 6'd13;
193
 
194
parameter IL1B_WAIT_AADR        = 6'd14;
195
parameter IL1B_WAIT2_AADR       = 6'd15;
196
parameter IL1B_LOAD_A           = 6'd16;
197
parameter IL1B_PIPEOUT          = 6'd17;
198
 
199
parameter IL2T_WAIT_CADR        = 6'd18;
200
parameter IL2T_WAIT2_CADR       = 6'd19;
201
parameter IL2T_LOAD_C           = 6'd20;
202
parameter IL2T_PIPEOUT          = 6'd21;
203
 
204
parameter IL2B_WAIT_BADR        = 6'd22;
205
parameter IL2B_WAIT2_BADR       = 6'd23;
206
parameter IL2B_LOAD_B           = 6'd24;
207
parameter IL2B_PIPEOUT          = 6'd25;
208
 
209
parameter IL3T_WAIT_AADR        = 6'd26;
210
parameter IL3T_WAIT2_AADR       = 6'd27;
211
parameter IL3T_LOAD_A           = 6'd28;
212
parameter IL3T_PIPEOUT          = 6'd29;
213
 
214
parameter IL3B_WAIT_CADR        = 6'd30;
215
parameter IL3B_WAIT2_CADR       = 6'd31;
216
parameter IL3B_LOAD_C           = 6'd32;
217
parameter IL3B_PIPEOUT          = 6'd33;
218
 
219
reg [5:0] state;
220
reg [5:0] next_state;
221
 
222
always @(posedge sys_clk) begin
223
        if(sys_rst)
224
                state <= IDLE;
225
        else
226
                state <= next_state;
227
end
228
 
229
always @(*) begin
230
        next_state = state;
231
 
232
        move_origin = 1'b0;
233
        move_linestart = 1'b0;
234
        move_right = 1'b0;
235
        move_down = 1'b0;
236
        move_leftdown = 1'b0;
237
        move_rightup = 1'b0;
238
 
239
        loadA = 1'b0;
240
        loadB = 1'b0;
241
        loadC = 1'b0;
242
 
243
        wbm_stb_o = 1'b0;
244
        busy = 1'b1;
245
 
246
        pipe_stb = 1'b0;
247
 
248
        case(state)
249
                IDLE: begin
250
                        busy = 1'b0;
251
                        move_origin = 1'b1;
252
                        if(start)
253
                                next_state = LS_WAIT_AADR;
254
                end
255
 
256
                /* Line Start */
257
                /* wait for the registered computation of WB address to complete */
258
                LS_WAIT_AADR: next_state = LS_WAIT2_AADR;
259
                LS_WAIT2_AADR: next_state = LS_LOAD_A;
260
                LS_LOAD_A: begin
261
                        wbm_stb_o = 1'b1;
262
                        loadA = 1'b1;
263
                        if(wbm_ack_i) begin
264
                                move_right = 1'b1;
265
                                next_state = LS_WAIT_BADR;
266
                        end
267
                end
268
                LS_WAIT_BADR: next_state = LS_WAIT2_BADR;
269
                LS_WAIT2_BADR: next_state = LS_LOAD_B;
270
                LS_LOAD_B: begin
271
                        wbm_stb_o = 1'b1;
272
                        loadB = 1'b1;
273
                        if(wbm_ack_i) begin
274
                                move_leftdown = 1'b1;
275
                                next_state = LS_WAIT_CADR;
276
                        end
277
                end
278
                LS_WAIT_CADR: next_state = LS_WAIT2_CADR;
279
                LS_WAIT2_CADR: next_state = LS_LOAD_C;
280
                LS_LOAD_C: begin
281
                        wbm_stb_o = 1'b1;
282
                        loadC = 1'b1;
283
                        if(wbm_ack_i)
284
                                next_state = IL1T_PIPEOUT;
285
                end
286
 
287
                /* In Line */
288
                /* Configuration 1, Top triangle */
289
 
290
                /* Enter this state by moving RIGHT-UP to fetch B,
291
                 * after checking for end-of-line and end-of-picture
292
                 */
293
                IL1T_WAIT_BADR: next_state = IL1T_WAIT2_BADR;
294
                IL1T_WAIT2_BADR: next_state = IL1T_LOAD_B;
295
                IL1T_LOAD_B: begin
296
                        wbm_stb_o = 1'b1;
297
                        loadB = 1'b1;
298
                        if(wbm_ack_i) begin
299
                                move_leftdown = 1'b1; /* Go to C not to break the cycle */
300
                                next_state = IL1T_PIPEOUT;
301
                        end
302
                end
303
                IL1T_PIPEOUT: begin
304
                        pipe_stb = 1'b1;
305
                        if(pipe_ack) begin
306
                                move_right = 1'b1;
307
                                next_state = IL1B_WAIT_AADR;
308
                        end
309
                end
310
 
311
                /* Configuration 1, Bottom triangle */
312
 
313
                /* Enter this state by moving RIGHT to fetch A */
314
                IL1B_WAIT_AADR: next_state = IL1B_WAIT2_AADR;
315
                IL1B_WAIT2_AADR: next_state = IL1B_LOAD_A;
316
                IL1B_LOAD_A: begin
317
                        wbm_stb_o = 1'b1;
318
                        loadA = 1'b1;
319
                        if(wbm_ack_i)
320
                                next_state = IL1B_PIPEOUT;
321
                end
322
                IL1B_PIPEOUT: begin
323
                        pipe_stb = 1'b1;
324
                        if(pipe_ack) begin
325
                                if(hlast) begin
326
                                        move_linestart = 1'b1;
327
                                        if(vlast)
328
                                                next_state = IDLE;
329
                                        else
330
                                                next_state = LS_WAIT_AADR;
331
                                end else begin
332
                                        move_rightup = 1'b1;
333
                                        next_state = IL2T_WAIT_CADR;
334
                                end
335
                        end
336
                end
337
 
338
                /* Configuration 2, Top triangle */
339
 
340
                /* Enter this state by moving RIGHT-UP to fetch C */
341
                IL2T_WAIT_CADR: next_state = IL2T_WAIT2_CADR;
342
                IL2T_WAIT2_CADR: next_state = IL2T_LOAD_C;
343
                IL2T_LOAD_C: begin
344
                        wbm_stb_o = 1'b1;
345
                        loadC = 1'b1;
346
                        if(wbm_ack_i)
347
                                next_state = IL2T_PIPEOUT;
348
                end
349
                IL2T_PIPEOUT: begin
350
                        pipe_stb = 1'b1;
351
                        if(pipe_ack) begin
352
                                move_down = 1'b1;
353
                                next_state = IL2B_WAIT_BADR;
354
                        end
355
                end
356
 
357
                /* Configuration 2, Bottom triangle */
358
 
359
                /* Enter this state by moving DOWN to fetch B */
360
                IL2B_WAIT_BADR: next_state = IL2B_WAIT2_BADR;
361
                IL2B_WAIT2_BADR: next_state = IL2B_LOAD_B;
362
                IL2B_LOAD_B: begin
363
                        wbm_stb_o = 1'b1;
364
                        loadB = 1'b1;
365
                        if(wbm_ack_i)
366
                                next_state = IL2B_PIPEOUT;
367
                end
368
                IL2B_PIPEOUT: begin
369
                        pipe_stb = 1'b1;
370
                        if(pipe_ack) begin
371
                                if(hlast) begin
372
                                        move_linestart = 1'b1;
373
                                        if(vlast)
374
                                                next_state = IDLE;
375
                                        else
376
                                                next_state = LS_WAIT_AADR;
377
                                end else begin
378
                                        move_rightup = 1'b1;
379
                                        next_state = IL3T_WAIT_AADR;
380
                                end
381
                        end
382
                end
383
 
384
                /* Configuration 3, Top triangle */
385
 
386
                /* Enter this state by moving RIGHT UP to fetch A */
387
                IL3T_WAIT_AADR: next_state = IL3T_WAIT2_AADR;
388
                IL3T_WAIT2_AADR: next_state = IL3T_LOAD_A;
389
                IL3T_LOAD_A: begin
390
                        wbm_stb_o = 1'b1;
391
                        loadA = 1'b1;
392
                        if(wbm_ack_i)
393
                                next_state = IL3T_PIPEOUT;
394
                end
395
                IL3T_PIPEOUT: begin
396
                        pipe_stb = 1'b1;
397
                        if(pipe_ack) begin
398
                                move_down = 1'b1;
399
                                next_state = IL3B_WAIT_CADR;
400
                        end
401
                end
402
 
403
                /* Configuration 3, Bottom triangle */
404
 
405
                /* Enter this state by moving DOWN to fetch C */
406
                IL3B_WAIT_CADR: next_state = IL3B_WAIT2_CADR;
407
                IL3B_WAIT2_CADR: next_state = IL3B_LOAD_C;
408
                IL3B_LOAD_C: begin
409
                        wbm_stb_o = 1'b1;
410
                        loadC = 1'b1;
411
                        if(wbm_ack_i)
412
                                next_state = IL3B_PIPEOUT;
413
                end
414
                IL3B_PIPEOUT: begin
415
                        pipe_stb = 1'b1;
416
                        if(pipe_ack) begin
417
                                if(hlast) begin
418
                                        move_linestart = 1'b1;
419
                                        if(vlast)
420
                                                next_state = IDLE;
421
                                        else
422
                                                next_state = LS_WAIT_AADR;
423
                                end else begin
424
                                        move_rightup = 1'b1;
425
                                        next_state = IL1T_WAIT_BADR;
426
                                end
427
                        end
428
                end
429
        endcase
430
end
431
 
432
endmodule

powered by: WebSVN 2.1.0

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