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

Subversion Repositories orsoc_graphics_accelerator

[/] [orsoc_graphics_accelerator/] [trunk/] [rtl/] [verilog/] [gfx/] [gfx_interp.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 Orka
/*
2
ORSoC GFX accelerator core
3
Copyright 2012, ORSoC, Per Lenander, Anton Fosselius.
4
 
5
INTERPOLATION MODULE - DIVIDER
6
 
7
 This file is part of orgfx.
8
 
9
 orgfx is free software: you can redistribute it and/or modify
10
 it under the terms of the GNU Lesser General Public License as published by
11
 the Free Software Foundation, either version 3 of the License, or
12
 (at your option) any later version.
13
 
14
 orgfx is distributed in the hope that it will be useful,
15
 but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 GNU Lesser General Public License for more details.
18
 
19
 You should have received a copy of the GNU Lesser General Public License
20
 along with orgfx.  If not, see <http://www.gnu.org/licenses/>.
21
 
22
*/
23
 
24
/*
25
This module interpolates by using div_uu division units
26
 
27
One division takes exactly point_width+1 ticks to complete, but many divisions can be pipelined at the same time.
28
*/
29
module gfx_interp(clk_i, rst_i,
30
  ack_i, ack_o,
31
  write_i,
32
  // Variables needed for interpolation
33
  edge0_i, edge1_i, area_i,
34
  // Raster position
35
  x_i, y_i, x_o, y_o,
36
 
37
  factor0_o, factor1_o,
38
  write_o
39
  );
40
 
41
parameter point_width  = 16;
42
parameter delay_width  = 5;
43
parameter div_delay    = point_width+1;
44
parameter result_width = 4;
45
 
46
input      clk_i;
47
input      rst_i;
48
 
49
input      ack_i;
50
output reg ack_o;
51
 
52
input      write_i;
53
 
54
input  [2*point_width-1:0] edge0_i;
55
input  [2*point_width-1:0] edge1_i;
56
input  [2*point_width-1:0] area_i;
57
 
58
input  [point_width-1:0] x_i;
59
input  [point_width-1:0] y_i;
60
output [point_width-1:0] x_o;
61
output [point_width-1:0] y_o;
62
 
63
// Generated pixel coordinates
64
output [point_width-1:0] factor0_o;
65
output [point_width-1:0] factor1_o;
66
// Write pixel output signal
67
output                   write_o;
68
 
69
// calculates factor0
70
wire   [point_width-1:0] interp0_quotient; // result
71
wire   [point_width-1:0] interp0_reminder;
72
wire                     interp0_div_by_zero;
73
wire                     interp0_overflow;
74
// calculates factor1
75
wire   [point_width-1:0] interp1_quotient; // result
76
wire   [point_width-1:0] interp1_reminder;
77
wire                     interp1_div_by_zero;
78
wire                     interp1_overflow;
79
 
80
reg  [delay_width-1:0] phase_counter;
81
 
82
wire                   division_enable;
83
 
84
always @(posedge clk_i or posedge rst_i)
85
if(rst_i)
86
  phase_counter <= 1'b0;
87
else if(division_enable)
88
  phase_counter <= (phase_counter + 1'b1 == div_delay) ? 1'b0 : phase_counter + 1'b1;
89
 
90
// State machine
91
reg state;
92
parameter wait_state   = 1'b0,
93
          write_state  = 1'b1;
94
 
95
// Manage states
96
always @(posedge clk_i or posedge rst_i)
97
if(rst_i)
98
  state <= wait_state;
99
else
100
  case (state)
101
 
102
    wait_state:
103
      if(write_o)
104
        state <= write_state;
105
 
106
    write_state:
107
      if(ack_i)
108
        state <= wait_state;
109
 
110
  endcase
111
 
112
always @(posedge clk_i or posedge rst_i)
113
begin
114
  // Reset
115
  if(rst_i)
116
    ack_o       <= 1'b0;
117
  else
118
    case (state)
119
 
120
      wait_state:
121
        ack_o   <= 1'b0;
122
 
123
      write_state:
124
        if(ack_i)
125
          ack_o <= 1'b1;
126
 
127
    endcase
128
 
129
end
130
 
131
wire [point_width-1:0] zeroes = 1'b0;
132
 
133
// division unit 0
134
        div_uu #(2*point_width) dut0 (
135
                .clk  (clk_i),
136
                .ena  (division_enable),
137
                .z    ({edge0_i[point_width-1:0], zeroes}),
138
                .d    (area_i[point_width-1:0]),
139
                .q    (interp0_quotient),
140
                .s    (interp0_reminder),
141
                .div0 (interp0_div_by_zero),
142
                .ovf  (interp0_overflow)
143
        );
144
// division unit 1
145
        div_uu #(2*point_width) dut1 (
146
                .clk  (clk_i),
147
                .ena  (division_enable),
148
                .z    ({edge1_i[point_width-1:0], zeroes}),
149
                .d    (area_i[point_width-1:0]),
150
                .q    (interp1_quotient),
151
                .s    (interp1_reminder),
152
                .div0 (interp1_div_by_zero),
153
                .ovf  (interp1_overflow)
154
        );
155
 
156
wire                  result_full;
157
wire                  result_valid;
158
wire [result_width:0] result_count;
159
wire                  result_deque = result_valid & (state == wait_state);
160
 
161
assign write_o = result_deque;
162
 
163
assign division_enable = ~result_full;
164
 
165
wire                   delay_valid;
166
wire [delay_width-1:0] delay_phase_counter;
167
wire                   division_complete = division_enable & delay_valid & (phase_counter == delay_phase_counter);
168
 
169
wire [point_width-1:0] delay_x, delay_y;
170
 
171
// Fifo for finished results
172
basic_fifo result_fifo(
173
  .clk_i     ( clk_i ),
174
  .rst_i     ( rst_i ),
175
 
176
  .data_i    ( {interp0_quotient, interp1_quotient, delay_x, delay_y} ),
177
  .enq_i     ( division_complete ),
178
  .full_o    ( result_full ), // TODO: use?
179
  .count_o   ( result_count ),
180
 
181
  .data_o    ( {factor0_o, factor1_o, x_o, y_o} ),
182
  .valid_o   ( result_valid ),
183
  .deq_i     ( result_deque )
184
);
185
 
186
defparam result_fifo.fifo_width     = 4*point_width;
187
defparam result_fifo.fifo_bit_depth = result_width;
188
 
189
// Another Fifo for current calculations
190
basic_fifo queue_fifo(
191
  .clk_i     ( clk_i ),
192
  .rst_i     ( rst_i ),
193
 
194
  .data_i    ( {phase_counter, x_i, y_i} ),
195
  .enq_i     ( write_i ),
196
  .full_o    ( ), // TODO: use?
197
  .count_o   ( ),
198
 
199
  .data_o    ( {delay_phase_counter, delay_x, delay_y} ),
200
  .valid_o   ( delay_valid ),
201
  .deq_i     ( division_complete )
202
);
203
 
204
defparam queue_fifo.fifo_width     = delay_width + 2*point_width;
205
defparam queue_fifo.fifo_bit_depth = delay_width;
206
 
207
endmodule
208
 

powered by: WebSVN 2.1.0

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