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

Subversion Repositories warp

[/] [warp/] [rtl/] [tmu_edgetrace.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_edgetrace(
20
        input sys_clk,
21
        input sys_rst,
22
 
23
        output reg busy,
24
 
25
        input pipe_stb_i,
26
        output reg pipe_ack_o,
27
        input [10:0] A_S_X,
28
        input [10:0] A_S_Y,
29
        input [10:0] A_D_X,
30
        input [10:0] A_D_Y,
31
        input [10:0] B_D_Y,
32
        input [10:0] C_D_Y,
33
 
34
        input dx1_positive,
35
        input [10:0] dx1_q,
36
        input [10:0] dx1_r,
37
        input dx2_positive,
38
        input [10:0] dx2_q,
39
        input [10:0] dx2_r,
40
        input dx3_positive,
41
        input [10:0] dx3_q,
42
        input [10:0] dx3_r,
43
 
44
        input du1_positive,
45
        input [10:0] du1_q,
46
        input [10:0] du1_r,
47
        input du2_positive,
48
        input [10:0] du2_q,
49
        input [10:0] du2_r,
50
        input du3_positive,
51
        input [10:0] du3_q,
52
        input [10:0] du3_r,
53
 
54
        input dv1_positive,
55
        input [10:0] dv1_q,
56
        input [10:0] dv1_r,
57
        input dv2_positive,
58
        input [10:0] dv2_q,
59
        input [10:0] dv2_r,
60
        input dv3_positive,
61
        input [10:0] dv3_q,
62
        input [10:0] dv3_r,
63
 
64
        input [10:0] divisor1,
65
        input [10:0] divisor2,
66
        input [10:0] divisor3,
67
 
68
        output reg pipe_stb_o,
69
        input pipe_ack_i,
70
        output reg [10:0] Y,   /* common Y coordinate */
71
        output reg [10:0] S_X, /* start point */
72
        output reg [10:0] S_U,
73
        output reg [10:0] S_V,
74
        output reg [10:0] E_X, /* end point */
75
        output reg [10:0] E_U,
76
        output reg [10:0] E_V
77
);
78
 
79
reg load;
80
 
81
/* Register some inputs */
82
reg [10:0] B_D_Y_r;
83
reg [10:0] C_D_Y_r;
84
 
85
reg dx1_positive_r;
86
reg [10:0] dx1_q_r;
87
reg [10:0] dx1_r_r;
88
reg dx2_positive_r;
89
reg [10:0] dx2_q_r;
90
reg [10:0] dx2_r_r;
91
reg dx3_positive_r;
92
reg [10:0] dx3_q_r;
93
reg [10:0] dx3_r_r;
94
reg du1_positive_r;
95
reg [10:0] du1_q_r;
96
reg [10:0] du1_r_r;
97
reg du2_positive_r;
98
reg [10:0] du2_q_r;
99
reg [10:0] du2_r_r;
100
reg du3_positive_r;
101
reg [10:0] du3_q_r;
102
reg [10:0] du3_r_r;
103
reg dv1_positive_r;
104
reg [10:0] dv1_q_r;
105
reg [10:0] dv1_r_r;
106
reg dv2_positive_r;
107
reg [10:0] dv2_q_r;
108
reg [10:0] dv2_r_r;
109
reg dv3_positive_r;
110
reg [10:0] dv3_q_r;
111
reg [10:0] dv3_r_r;
112
reg [10:0] divisor1_r;
113
reg [10:0] divisor2_r;
114
reg [10:0] divisor3_r;
115
always @(posedge sys_clk) begin
116
        if(load) begin
117
                B_D_Y_r <= B_D_Y;
118
                C_D_Y_r <= C_D_Y;
119
                dx1_positive_r <= dx1_positive;
120
                dx1_q_r <= dx1_q;
121
                dx1_r_r <= dx1_r;
122
                dx2_positive_r <= dx2_positive;
123
                dx2_q_r <= dx2_q;
124
                dx2_r_r <= dx2_r;
125
                dx3_positive_r <= dx3_positive;
126
                dx3_q_r <= dx3_q;
127
                dx3_r_r <= dx3_r;
128
                du1_positive_r <= du1_positive;
129
                du1_q_r <= du1_q;
130
                du1_r_r <= du1_r;
131
                du2_positive_r <= du2_positive;
132
                du2_q_r <= du2_q;
133
                du2_r_r <= du2_r;
134
                du3_positive_r <= du3_positive;
135
                du3_q_r <= du3_q;
136
                du3_r_r <= du3_r;
137
                dv1_positive_r <= dv1_positive;
138
                dv1_q_r <= dv1_q;
139
                dv1_r_r <= dv1_r;
140
                dv2_positive_r <= dv2_positive;
141
                dv2_q_r <= dv2_q;
142
                dv2_r_r <= dv2_r;
143
                dv3_positive_r <= dv3_positive;
144
                dv3_q_r <= dv3_q;
145
                dv3_r_r <= dv3_r;
146
                divisor1_r <= divisor1;
147
                divisor2_r <= divisor2;
148
                divisor3_r <= divisor3;
149
        end
150
end
151
 
152
/* Current points, with X's unordered */
153
reg [10:0] I_X;
154
reg [10:0] I_U;
155
reg [10:0] I_V;
156
reg [10:0] J_X;
157
reg [10:0] J_U;
158
reg [10:0] J_V;
159
 
160
/* Sort the points according to X's */
161
always @(posedge sys_clk) begin
162
        if(I_X < J_X) begin
163
                S_X <= I_X;
164
                S_U <= I_U;
165
                S_V <= I_V;
166
                E_X <= J_X;
167
                E_U <= J_U;
168
                E_V <= J_V;
169
        end else begin
170
                S_X <= J_X;
171
                S_U <= J_U;
172
                S_V <= J_V;
173
                E_X <= I_X;
174
                E_U <= I_U;
175
                E_V <= I_V;
176
        end
177
end
178
 
179
/* See scantrace.v for a simpler version of the interpolation algorithm.
180
 * Here, we only repeat it.
181
 */
182
 
183
/* Current point datapath */
184
/* control signals: */
185
reg addDX1; /* add DX1 to J */
186
reg addDX2; /* add DX2 to I */
187
reg addDX3; /* add DX3 to J */
188
 
189
/* error accumulators: */
190
reg [11:0] errIX2;
191
reg [11:0] errIU2;
192
reg [11:0] errIV2;
193
reg [11:0] errJX1;
194
reg [11:0] errJU1;
195
reg [11:0] errJV1;
196
reg [11:0] errJX3;
197
reg [11:0] errJU3;
198
reg [11:0] errJV3;
199
 
200
/* intermediate variables: */
201
reg correctJX1;
202
reg correctJU1;
203
reg correctJV1;
204
reg correctJX3;
205
reg correctJU3;
206
reg correctJV3;
207
 
208
reg correctIX2;
209
reg correctIU2;
210
reg correctIV2;
211
 
212
always @(posedge sys_clk) begin
213
        if(load) begin
214
                I_X = A_D_X;
215
                I_U = A_S_X;
216
                I_V = A_S_Y;
217
                J_X = A_D_X;
218
                J_U = A_S_X;
219
                J_V = A_S_Y;
220
 
221
                errIX2 = 12'd0;
222
                errIU2 = 12'd0;
223
                errIV2 = 12'd0;
224
                errJX1 = 12'd0;
225
                errJU1 = 12'd0;
226
                errJV1 = 12'd0;
227
                errJX3 = 12'd0;
228
                errJU3 = 12'd0;
229
                errJV3 = 12'd0;
230
        end else begin
231
                /* J */
232
                if(addDX1) begin
233
                        errJX1 = errJX1 + dx1_r_r;
234
                        correctJX1 = (errJX1[10:0] > {1'b0, divisor1_r[10:1]}) & ~errJX1[11];
235
                        if(dx1_positive_r) begin
236
                                J_X = J_X + dx1_q_r;
237
                                if(correctJX1)
238
                                        J_X = J_X + 11'd1;
239
                        end else begin
240
                                J_X = J_X - dx1_q_r;
241
                                if(correctJX1)
242
                                        J_X = J_X - 11'd1;
243
                        end
244
                        if(correctJX1)
245
                                errJX1 = errJX1 - {1'b0, divisor1_r};
246
 
247
                        errJU1 = errJU1 + du1_r_r;
248
                        correctJU1 = (errJU1[10:0] > {1'b0, divisor1_r[10:1]}) & ~errJU1[11];
249
                        if(du1_positive_r) begin
250
                                J_U = J_U + du1_q_r;
251
                                if(correctJU1)
252
                                        J_U = J_U + 11'd1;
253
                        end else begin
254
                                J_U = J_U - du1_q_r;
255
                                if(correctJU1)
256
                                        J_U = J_U - 11'd1;
257
                        end
258
                        if(correctJU1)
259
                                errJU1 = errJU1 - {1'b0, divisor1_r};
260
 
261
                        errJV1 = errJV1 + dv1_r_r;
262
                        correctJV1 = (errJV1[10:0] > {1'b0, divisor1_r[10:1]}) & ~errJV1[11];
263
                        if(dv1_positive_r) begin
264
                                J_V = J_V + dv1_q_r;
265
                                if(correctJV1)
266
                                        J_V = J_V + 11'd1;
267
                        end else begin
268
                                J_V = J_V - dv1_q_r;
269
                                if(correctJV1)
270
                                        J_V = J_V - 11'd1;
271
                        end
272
                        if(correctJV1)
273
                                errJV1 = errJV1 - {1'b0, divisor1_r};
274
                end else if(addDX3) begin
275
                        errJX3 = errJX3 + dx3_r_r;
276
                        correctJX3 = (errJX3[10:0] > {1'b0, divisor3_r[10:1]}) & ~errJX3[11];
277
                        if(dx3_positive_r) begin
278
                                J_X = J_X + dx3_q_r;
279
                                if(correctJX3)
280
                                        J_X = J_X + 11'd1;
281
                        end else begin
282
                                J_X = J_X - dx3_q_r;
283
                                if(correctJX3)
284
                                        J_X = J_X - 11'd1;
285
                        end
286
                        if(correctJX3)
287
                                errJX3 = errJX3 - {1'b0, divisor3_r};
288
 
289
                        errJU3 = errJU3 + du3_r_r;
290
                        correctJU3 = (errJU3[10:0] > {1'b0, divisor3_r[10:1]}) & ~errJU3[11];
291
                        if(du3_positive_r) begin
292
                                J_U = J_U + du3_q_r;
293
                                if(correctJU3)
294
                                        J_U = J_U + 11'd1;
295
                        end else begin
296
                                J_U = J_U - du3_q_r;
297
                                if(correctJU3)
298
                                        J_U = J_U - 11'd1;
299
                        end
300
                        if(correctJU3)
301
                                errJU3 = errJU3 - {1'b0, divisor3_r};
302
 
303
                        errJV3 = errJV3 + dv3_r_r;
304
                        correctJV3 = (errJV3[10:0] > {1'b0, divisor3_r[10:1]}) & ~errJV3[11];
305
                        if(dv3_positive_r) begin
306
                                J_V = J_V + dv3_q_r;
307
                                if(correctJV3)
308
                                        J_V = J_V + 11'd1;
309
                        end else begin
310
                                J_V = J_V - dv3_q_r;
311
                                if(correctJV3)
312
                                        J_V = J_V - 11'd1;
313
                        end
314
                        if(correctJV3)
315
                                errJV3 = errJV3 - {1'b0, divisor3_r};
316
                end
317
                /* I */
318
                if(addDX2) begin
319
                        errIX2 = errIX2 + dx2_r_r;
320
                        correctIX2 = (errIX2[10:0] > {1'b0, divisor2_r[10:1]}) & ~errIX2[11];
321
                        if(dx2_positive_r) begin
322
                                I_X = I_X + dx2_q_r;
323
                                if(correctIX2)
324
                                        I_X = I_X + 11'd1;
325
                        end else begin
326
                                I_X = I_X - dx2_q_r;
327
                                if(correctIX2)
328
                                        I_X = I_X - 11'd1;
329
                        end
330
                        if(correctIX2)
331
                                errIX2 = errIX2 - {1'b0, divisor2_r};
332
 
333
                        errIU2 = errIU2 + du2_r_r;
334
                        correctIU2 = (errIU2[10:0] > {1'b0, divisor2_r[10:1]}) & ~errIU2[11];
335
                        if(du2_positive_r) begin
336
                                I_U = I_U + du2_q_r;
337
                                if(correctIU2)
338
                                        I_U = I_U + 11'd1;
339
                        end else begin
340
                                I_U = I_U - du2_q_r;
341
                                if(correctIU2)
342
                                        I_U = I_U - 11'd1;
343
                        end
344
                        if(correctIU2)
345
                                errIU2 = errIU2 - {1'b0, divisor2_r};
346
 
347
                        errIV2 = errIV2 + dv2_r_r;
348
                        correctIV2 = (errIV2[10:0] > {1'b0, divisor2_r[10:1]}) & ~errIV2[11];
349
                        if(dv2_positive_r) begin
350
                                I_V = I_V + dv2_q_r;
351
                                if(correctIV2)
352
                                        I_V = I_V + 11'd1;
353
                        end else begin
354
                                I_V = I_V - dv2_q_r;
355
                                if(correctIV2)
356
                                        I_V = I_V - 11'd1;
357
                        end
358
                        if(correctIV2)
359
                                errIV2 = errIV2 - {1'b0, divisor2_r};
360
                end
361
        end
362
end
363
 
364
/* Y datapath */
365
reg incY;
366
always @(posedge sys_clk) begin
367
        if(load)
368
                Y <= A_D_Y;
369
        else if(incY)
370
                Y <= Y + 11'd1;
371
end
372
 
373
wire reachedB = (Y == B_D_Y_r);
374
wire reachedC = (Y == C_D_Y_r);
375
 
376
/* FSM-based controller */
377
 
378
reg [2:0] state;
379
reg [2:0] next_state;
380
 
381
parameter IDLE                  = 3'd0;
382
parameter A_NEXT                = 3'd1;
383
parameter A_PIPEOUT_WAIT        = 3'd2;
384
parameter A_PIPEOUT             = 3'd3;
385
parameter B_START               = 3'd4;
386
parameter B_NEXT                = 3'd5;
387
parameter B_PIPEOUT_WAIT        = 3'd6;
388
parameter B_PIPEOUT             = 3'd7;
389
 
390
/* Register to handle the "AB horizontal" corner case properly */
391
reg ABh;
392
reg next_ABh;
393
 
394
always @(posedge sys_clk)
395
        ABh <= next_ABh;
396
 
397
always @(posedge sys_clk) begin
398
        if(sys_rst)
399
                state <= IDLE;
400
        else
401
                state <= next_state;
402
end
403
 
404
always @(*) begin
405
        next_state = state;
406
 
407
        busy = 1'b1;
408
 
409
        pipe_ack_o = 1'b0;
410
        pipe_stb_o = 1'b0;
411
 
412
        load = 1'b0;
413
 
414
        addDX1 = 1'b0;
415
        addDX2 = 1'b0;
416
        addDX3 = 1'b0;
417
 
418
        incY = 1'b0;
419
 
420
        next_ABh = ABh;
421
 
422
        case(state)
423
                IDLE: begin
424
                        busy = 1'b0;
425
                        pipe_ack_o = 1'b1;
426
                        next_ABh = 1'b1;
427
                        if(pipe_stb_i) begin
428
                                load = 1'b1;
429
                                next_state = A_PIPEOUT_WAIT;
430
                        end
431
                end
432
                /* We start the triangle by using factors 2 and 1 */
433
                A_NEXT: begin
434
                        addDX1 = 1'b1;
435
                        addDX2 = 1'b1;
436
                        next_ABh = 1'b0;
437
                        next_state = A_PIPEOUT_WAIT;
438
                end
439
                /* There is one cycle latency because the point must be sorted by X's
440
                 * (see the beginning of this file).
441
                 */
442
                A_PIPEOUT_WAIT: next_state = A_PIPEOUT;
443
                A_PIPEOUT: begin
444
                        if(reachedB & ABh) begin
445
                                /* We reach B right from the beginning: AB is horizontal.
446
                                 * In this case, the D1 factors have been set so that J becomes B
447
                                 * in one step (we must enter state B_START with J=B).
448
                                 */
449
                                addDX1 = 1'b1;
450
                                next_state = B_START;
451
                        end else begin
452
                                pipe_stb_o = 1'b1;
453
                                if(pipe_ack_i) begin
454
                                        if(reachedB)
455
                                                next_state = B_START;
456
                                        else begin
457
                                                incY = 1'b1;
458
                                                next_state = A_NEXT;
459
                                        end
460
                                end
461
                        end
462
                end
463
 
464
                /* Once we reach B, we use factors 2 and 3 */
465
                B_START: begin
466
                        if(reachedC)
467
                                next_state = IDLE;
468
                        else
469
                                next_state = B_PIPEOUT_WAIT;
470
                end
471
                B_NEXT: begin
472
                        addDX3 = 1'b1;
473
                        addDX2 = 1'b1;
474
                        next_state = B_PIPEOUT_WAIT;
475
                end
476
                B_PIPEOUT_WAIT: next_state = B_PIPEOUT;
477
                B_PIPEOUT: begin
478
                        pipe_stb_o = 1'b1;
479
                        if(pipe_ack_i) begin
480
                                if(reachedC)
481
                                        next_state = IDLE;
482
                                else begin
483
                                        incY = 1'b1;
484
                                        next_state = B_NEXT;
485
                                end
486
                        end
487
                end
488
        endcase
489
end
490
 
491
endmodule

powered by: WebSVN 2.1.0

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