OpenCores
URL https://opencores.org/ocsvn/bluespec-h264/bluespec-h264/trunk

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [src_fpga/] [mkVgaController.bsv] - Blame information for rev 100

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 83 jamey.hick
 
2
// The MIT License
3
 
4
// Copyright (c) 2006-2007 Massachusetts Institute of Technology
5
 
6
// Permission is hereby granted, free of charge, to any person obtaining a copy
7
// of this software and associated documentation files (the "Software"), to deal
8
// in the Software without restriction, including without limitation the rights
9
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
// copies of the Software, and to permit persons to whom the Software is
11
// furnished to do so, subject to the following conditions:
12
 
13
// The above copyright notice and this permission notice shall be included in
14
// all copies or substantial portions of the Software.
15
 
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
// THE SOFTWARE.
23
 
24 3 jamey.hick
package mkVgaController;
25
 
26
import BRAM::*;
27
import RegFile::*;
28
import FIFOF::*;
29
import IVgaController::*;
30
import IMemClient::*;
31
 
32
`define COLUMNS 640
33
`define ROWS    480
34
 
35
`define   L_HSYNC_TIME 96
36
`define   L_BACK_PORCH_TIME 48
37
`define   L_DATA_TIME 640
38
`define   L_FRONT_PORCH_TIME 16
39
 
40
typedef enum
41
{
42
   L_HSYNC = 96,
43
   L_BACK_PORCH = 48,
44
   L_DATA = 640,
45
   L_FRONT_PORCH = 16
46
}
47
   LineState
48
            deriving (Eq, Bits);
49
 
50
`define   F_VSYNC_TIME  2
51
`define   F_BACK_PORCH_TIME 29
52
`define   F_DATA_TIME 480
53
`define   F_FRONT_PORCH_TIME 9
54
 
55
typedef enum
56
{
57
   F_VSYNC = 2,
58
   F_BACK_PORCH = 29,
59
   F_DATA = 480,
60
   F_FRONT_PORCH = 9
61
}
62
   FrameState
63
            deriving (Eq, Bits);
64
 
65
typedef enum
66
{
67
   U_BRAM,
68
   Y_BRAM,
69
   V_BRAM
70
}
71
   TargetBuffer
72
            deriving (Eq, Bits);
73
 
74
`define Y0_OFFSET   20'b0
75
`define U0_OFFSET   `ROWS*`COLUMNS +  20'b0
76
`define V0_OFFSET   `U0_OFFSET + `ROWS/2*`COLUMNS/2 + 20'b0
77
`define Y1_OFFSET   `V0_OFFSET + `ROWS/2*`COLUMNS/2 + 20'b0
78
`define U1_OFFSET   `Y1_OFFSET + `ROWS*`COLUMNS +  20'b0
79
`define V1_OFFSET   `U1_OFFSET + `ROWS/2*`COLUMNS/2 + 20'b0
80
`define HIGH_ADDR  `V1_OFFSET + `ROWS/2*`COLUMNS/2 - 1
81
 
82
(* always_ready, always_enabled *)
83
interface BRAMFrontend;
84
  method Action   data_input(Bit#(64) data);
85
  method Bit#(64) data_output();
86
  method Bit#(32) addr_output();
87
  method Bit#(1)  enable();
88
  method Bit#(4)  wenable();
89
  method Bit#(1)  vsync();
90
  method Bit#(1)  hsync();
91
  method Bit#(1)  blank();
92
  method Bit#(1)  sync_on_green();
93
  method Bit#(8)  red();
94
  method Bit#(8)  blue();
95
  method Bit#(8)  green();
96
endinterface
97
 
98
 
99
 
100
 
101
//(* synthesize *)
102
module mkVgaController#(IMemClient#(Bit#(18), Bit#(32)) bram_Y,
103
                        IMemClient#(Bit#(18), Bit#(32)) bram_U,
104
                        IMemClient#(Bit#(18), Bit#(32)) bram_V) (IVgaController);
105
 
106
  Reg#(Bit#(8)) red_reg <- mkReg(0);
107
  Reg#(Bit#(8)) blue_reg <- mkReg(0);
108
  Reg#(Bit#(8)) green_reg <- mkReg(0);
109
  Reg#(Bit#(1)) target_buffer <- mkReg(0);
110
  Reg#(Bit#(TLog#(`ROWS))) bram_address_row <- mkReg(0);
111
  Reg#(Bit#(TLog#(`COLUMNS))) bram_address_col <- mkReg(0);
112
  Reg#(Bit#(TLog#(`COLUMNS))) bram_resp_col <- mkReg(0);
113
  Reg#(FrameState) frame_state <- mkReg(F_VSYNC);
114
  Reg#(LineState) line_state <- mkReg(L_HSYNC);
115
  Reg#(Bit#(11)) line_counter <- mkReg(0);
116
  Reg#(Bit#(11)) tick_counter <- mkReg(0);
117
  Reg#(Bit#(1)) hsync_buffer <- mkReg(0);
118
  Reg#(Bit#(1)) vsync_buffer <- mkReg(0);
119
  Reg#(Bit#(1)) blank_buffer <- mkReg(0);
120
  Reg#(Bit#(1)) sync_on_green_buffer <- mkReg(0);
121
  Reg#(Bit#(3)) bram_line_offset <- mkReg(0);
122
  Reg#(Bool) frame_switch_seen <- mkReg(True);
123
  Reg#(Bit#(32)) counter <- mkReg(0);
124
  Reg#(Bit#(32)) y_word_buffer <- mkReg(0);
125
  Reg#(Bit#(32)) u_word_buffer <- mkReg(0);
126
  Reg#(Bit#(32)) v_word_buffer <- mkReg(0);
127
 
128
 
129
  function Bit#(8) ybyte (Bit#(32) word);
130
     return case (bram_line_offset[1:0])
131
         2'b11: word[31:24];
132
         2'b10: word[23:16];
133
         2'b01: word[15:8];
134
         2'b00: word[7:0];
135
       endcase;
136
  endfunction: ybyte
137
 
138
  function Bit#(8) uvbyte (Bit#(32) word);
139
     return case (bram_line_offset[2:1])
140
         2'b11: word[31:24];
141
         2'b10: word[23:16];
142
         2'b01: word[15:8];
143
         2'b00: word[7:0];
144
       endcase;
145
  endfunction: uvbyte
146
 
147
// Fix the stupidity here.
148
  rule black_rgb((line_state == L_DATA) && (bram_resp_col == `COLUMNS));
149
   red_reg <= 0;
150
   blue_reg <= 0;
151
   green_reg <= 0;
152
  endrule
153
 
154
  rule translate_rgb(line_state == L_DATA);
155
    Bit#(8) y_wire;
156
    Bit#(8) u_wire;
157
    Bit#(8) v_wire;
158
 
159
    counter <= counter + 1;
160
    bram_line_offset <= bram_line_offset + 1;
161
    bram_resp_col <= bram_resp_col + 1;
162
 
163
    if(bram_line_offset[1:0] == 0)
164
      begin
165
        Bit#(32) y_word;
166
        y_word <- bram_Y.read_resp();
167
        y_word_buffer <= y_word;
168
        y_wire = ybyte(y_word);
169
      end
170
    else
171
      begin
172
        y_wire = ybyte(y_word_buffer);
173
      end
174
 
175
    if(bram_line_offset[2:0] == 0)
176
      begin
177
        Bit#(32)u_word;
178
        Bit#(32)v_word;
179
        u_word <- bram_U.read_resp();
180
        u_word_buffer <= u_word;
181
        u_wire = uvbyte(u_word);
182
        v_word <- bram_V.read_resp();
183
        v_word_buffer <= v_word;
184
        v_wire = uvbyte(v_word);
185
      end
186
    else
187
      begin
188
        u_wire = uvbyte(u_word_buffer);
189
        v_wire = uvbyte(v_word_buffer);
190
      end
191
 
192
    Int#(18) y_value = unpack(zeroExtend(y_wire));
193
    Int#(18) u_value = unpack(signExtend(u_wire-128));
194
    Int#(18) v_value = unpack(signExtend(v_wire-128));
195
 
196
    //YRB
197
    Int#(18) red_reg_next = (( 298 * y_value + 409 * v_value + 128) >> 8);
198
    Int#(18) green_reg_next = (( 298 * y_value -  100 *  u_value - 209 * v_value + 128) >> 8);
199
    Int#(18) blue_reg_next = (( 298 * y_value +  516* u_value +128) >> 8);
200
 
201
    Bit#(8) test_red = (red_reg_next < 0) ? 0 : ((red_reg_next >255) ? 255 : truncate(pack(red_reg_next)));
202
    Bit#(8) test_blue = (blue_reg_next < 0) ? 0 : ((blue_reg_next >255) ? 255 : truncate(pack(blue_reg_next)));
203
    Bit#(8) test_green = (green_reg_next < 0) ? 0 : ((green_reg_next >255) ? 255 : truncate(pack(green_reg_next)));
204
 
205
    red_reg <= (red_reg_next < 0) ? 0 : ((red_reg_next >255) ? 255 : truncate(pack(red_reg_next)));
206
    blue_reg <= (blue_reg_next < 0) ? 0 : ((blue_reg_next > 255) ? 255 : truncate(pack(blue_reg_next)));
207
    green_reg <= (green_reg_next < 0) ? 0 : ((green_reg_next > 255) ? 255 : truncate(pack(green_reg_next)));
208
 
209
 
210
    $display("RGB %d %d %d", test_red, test_green, test_blue);
211
  endrule
212
 
213
  rule tick_update(tick_counter > 0);
214
    tick_counter <= tick_counter - 1;
215
  endrule
216
 
217
  rule line_update((line_counter > 0) && (tick_counter == 1) && (line_state == L_HSYNC));
218
    line_counter <= line_counter - 1;
219
  endrule
220
 
221
  rule send_req_to_bram((frame_state == F_DATA) && ((line_state == L_BACK_PORCH) || (line_state == L_DATA)) && !(bram_address_col == `COLUMNS) && !(bram_address_row == `ROWS) );
222
    Bit#(TLog#(`COLUMNS)) adjusted_col_addr = (bram_address_col == `COLUMNS) ? 0 : bram_address_col;
223
    if(target_buffer == 0)
224
      begin
225
        bram_Y.read_req(truncate((`Y0_OFFSET +  `COLUMNS*zeroExtend(bram_address_row) + zeroExtend(adjusted_col_addr))>>2));
226
       if(bram_address_col[2:0] == 0)
227
         begin
228
           bram_U.read_req(truncate((`U0_OFFSET +  (`COLUMNS/2)*zeroExtend(bram_address_row/2) + zeroExtend(adjusted_col_addr/2))>>2));
229
           bram_V.read_req(truncate((`V0_OFFSET +  (`COLUMNS/2)*zeroExtend(bram_address_row/2) + zeroExtend(adjusted_col_addr/2))>>2));
230
         end
231
      end
232
    else
233
      begin
234
        bram_Y.read_req(truncate((`Y1_OFFSET +  `COLUMNS*zeroExtend(bram_address_row) + zeroExtend(adjusted_col_addr))>>2));
235
       if(bram_address_col[2:0] == 0)
236
         begin
237
           bram_U.read_req(truncate((`U1_OFFSET +  (`COLUMNS/2)*zeroExtend(bram_address_row/2) + zeroExtend(adjusted_col_addr/2))>>2));
238
           bram_V.read_req(truncate((`V1_OFFSET +  (`COLUMNS/2)*zeroExtend(bram_address_row/2) + zeroExtend(adjusted_col_addr/2))>>2));
239
         end
240
      end
241
    bram_address_col <= bram_address_col + 4;
242
  endrule
243
 
244
  rule line_HSYNC_to_BP ((tick_counter == 0) && (line_state == L_HSYNC));
245
    tick_counter <= `L_BACK_PORCH_TIME;
246
    line_state <= L_BACK_PORCH;
247
    //$display("Back Porch\n");
248
  endrule
249
 
250
  rule line_BP_to_DATA ((tick_counter == 0) && (line_state == L_BACK_PORCH));
251
    tick_counter <= `L_DATA_TIME;
252
    line_state <= L_DATA;
253
    //$display("Data\n");
254
    // Need to do something with addressing here
255
  endrule
256
 
257
  rule line_data_to_FP ((tick_counter == 0) && (line_state == L_DATA));
258
    tick_counter <= `L_FRONT_PORCH_TIME;
259
    line_state <= L_FRONT_PORCH;
260
    //$display("Front Porch\n");
261
  endrule
262
 
263
  rule line_FP_to_HSYNC_no_deq ((tick_counter == 0) && (line_state == L_FRONT_PORCH));
264
    if(frame_state == F_DATA && (bram_address_row < `ROWS))
265
      begin
266
        bram_address_row <=  bram_address_row + 1;
267
      end
268
    else if (frame_state==F_BACK_PORCH)
269
      begin
270
        bram_address_row <=  0;
271
      end
272
    else
273
      begin
274
        bram_address_row <=  bram_address_row;
275
      end
276
    bram_resp_col <= 0;
277
    bram_address_col <= 0;
278
    bram_line_offset <=0;
279
    tick_counter <= `L_HSYNC_TIME;
280
    line_state <= L_HSYNC;
281
    //$display("HSYNC\n");
282
  endrule
283
 
284
  rule frame_HSYNC_to_BP ((line_counter == 0) && (frame_state == F_VSYNC));
285
    line_counter <= `F_BACK_PORCH_TIME;
286
    frame_state <= F_BACK_PORCH;
287
  endrule
288
 
289
  rule frame_BP_to_DATA ((line_counter == 0) && (frame_state == F_BACK_PORCH));
290
    line_counter <= `F_DATA_TIME;
291
    frame_state <= F_DATA;
292
  endrule
293
 
294
  rule frame_data_to_FP ((line_counter == 0) && (frame_state == F_DATA));
295
    frame_switch_seen <= False;
296
    $display("bufferswitch: setdown");
297
    line_counter <= `F_FRONT_PORCH_TIME;
298
    frame_state <= F_FRONT_PORCH;
299
  endrule
300
 
301
  rule frame_FP_to_VSYNC ((line_counter == 0) && (frame_state == F_FRONT_PORCH));
302
    line_counter <= `F_VSYNC_TIME;
303
    frame_state <= F_VSYNC;
304
  endrule
305
 
306
  // hsync and vsync are asserted low.
307
  rule hsync_delay;
308
    hsync_buffer <= (line_state == L_HSYNC)? 1 : 0;
309
  endrule
310
 
311
  rule vsync_delay;
312
    vsync_buffer <= (frame_state == F_VSYNC)? 1 : 0;
313
  endrule
314
 
315
  rule blank_delay;
316
    blank_buffer <= ((frame_state == F_DATA) && (line_state == L_DATA))? 1 : 0;
317
  endrule
318
 
319
  method  red;
320
    return red_reg;
321
  endmethod
322
 
323
  method  blue;
324
    return blue_reg;
325
  endmethod
326
 
327
  method  green;
328
    return green_reg;
329
  endmethod
330
 
331
 
332
  method  sync_on_green;
333
    return ((hsync_buffer == 0) || (vsync_buffer == 0))? 0 : 1;
334
  endmethod
335
 
336
  // hsync and vsync are asserted low.
337
  method  hsync;
338
    return hsync_buffer;
339
  endmethod
340
 
341
  method  vsync;
342
    return vsync_buffer;
343
  endmethod
344
 
345
  method blank;
346
   return blank_buffer;
347
  endmethod
348
 
349
   method Action  switch_buffer(Bit#(1) buffer) if((frame_state != F_DATA) && (!frame_switch_seen));
350
    frame_switch_seen <= True;
351
    $display("bufferswitch: %d", buffer);
352
    target_buffer <= buffer;
353
  endmethod
354
 
355
endmodule
356
 
357
endpackage
358
 

powered by: WebSVN 2.1.0

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