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

Subversion Repositories rtftextcontroller

[/] [rtftextcontroller/] [trunk/] [rtl/] [verilog/] [rtfTextController.v] - Blame information for rev 30

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 robfinch
// ============================================================================
2 21 robfinch
//      (C) 2006-2012  Robert Finch
3 19 robfinch
//      robfinch@<remove>opencores.org
4 3 robfinch
//
5
//      rtfTextController.v
6
//              text controller
7
//
8 19 robfinch
// This source file is free software: you can redistribute it and/or modify 
9
// it under the terms of the GNU Lesser General Public License as published 
10
// by the Free Software Foundation, either version 3 of the License, or     
11
// (at your option) any later version.                                      
12
//                                                                          
13
// This source file is distributed in the hope that it will be useful,      
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
16
// GNU General Public License for more details.                             
17
//                                                                          
18
// You should have received a copy of the GNU General Public License        
19
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
20
//                                                                          
21 3 robfinch
//
22
//      Text Controller
23
//
24
//      FEATURES
25
//
26
//      This core requires an external timing generator to provide horizontal
27
//      and vertical sync signals, but otherwise can be used as a display
28
//  controller on it's own. However, this core may also be embedded within
29
//  another core such as a VGA controller.
30
//
31
//      Window positions are referenced to the rising edge of the vertical and
32
//      horizontal sync pulses.
33
//
34
//      The core includes an embedded dual port RAM to hold the screen
35
//      characters.
36
//
37
//
38 19 robfinch
//--------------------------------------------------------------------
39
// Registers
40 3 robfinch
//
41 19 robfinch
//      00 -         nnnnnnnn  number of columns (horizontal displayed number of characters)
42
//      01 -         nnnnnnnn  number of rows    (vertical displayed number of characters)
43
//      02 -       n nnnnnnnn  window left       (horizontal sync position - reference for left edge of displayed)
44
//      03 -       n nnnnnnnn  window top        (vertical sync position - reference for the top edge of displayed)
45
//      04 -         ---nnnnn  maximum scan line (char ROM max value is 7)
46
//              05 -         hhhhwwww  pixel size, hhhh=height,wwww=width
47
//      07 -         ---nnnnn  color code for transparent background
48
//      08 -         -BPnnnnn  cursor start / blink control
49
//                             BP: 00=no blink
50
//                             BP: 01=no display
51
//                             BP: 10=1/16 field rate blink
52
//                             BP: 11=1/32 field rate blink
53
//      09 -        ----nnnnn  cursor end
54
//      10 - aaaaaaaa aaaaaaaaa  start address (index into display memory)
55
//      11 - aaaaaaaa aaaaaaaaa  cursor position
56
//      12 - aaaaaaaa aaaaaaaaa  light pen position
57
//--------------------------------------------------------------------
58 3 robfinch
//
59
// ============================================================================
60
 
61 19 robfinch
module rtfTextController(
62 3 robfinch
        rst_i, clk_i,
63
        cyc_i, stb_i, ack_o, we_i, sel_i, adr_i, dat_i, dat_o,
64
        lp, curpos,
65
        vclk, eol, eof, blank, border, rgbIn, rgbOut
66
);
67 21 robfinch
parameter COLS = 12'd56;
68 3 robfinch
parameter ROWS = 12'd31;
69
 
70
// Syscon
71
input  rst_i;                   // reset
72
input  clk_i;                   // clock
73
 
74
// Slave signals
75
input  cyc_i;                   // cycle valid
76
input  stb_i;                   // data strobe
77
output ack_o;                   // transfer acknowledge
78
input  we_i;                    // write
79
input  [ 1:0] sel_i;     // byte select
80 21 robfinch
input  [63:0] adr_i;     // address
81 3 robfinch
input  [15:0] dat_i;     // data input
82
output [15:0] dat_o;     // data output
83
reg    [15:0] dat_o;
84
 
85
//
86
input lp;                               // light pen
87
input [15:0] curpos;     // cursor position
88
 
89
// Video signals
90
input vclk;                             // video dot clock
91
input eol;                              // end of scan line
92
input eof;                              // end of frame
93
input blank;                    // blanking signal
94
input border;                   // border area
95
input [24:0] rgbIn;              // input pixel stream
96
output reg [24:0] rgbOut;        // output pixel stream
97
 
98
 
99
wire [23:0] bkColor24;   // background color
100
wire [23:0] fgColor24;   // foreground color
101 19 robfinch
wire [23:0] tcColor24;   // transparent color
102 3 robfinch
 
103
wire pix;                               // pixel value from character generator 1=on,0=off
104
 
105
reg [15:0] rego;
106
reg [11:0] windowTop;
107
reg [11:0] windowLeft;
108
reg [11:0] numCols;
109
reg [11:0] numRows;
110
reg [ 1:0] mode;
111
reg [ 4:0] maxScanline;
112
reg [ 4:0] maxScanpix;
113
reg [ 4:0] cursorStart, cursorEnd;
114
reg [15:0] cursorPos;
115
reg [15:0] startAddress;
116
reg [ 2:0] rBlink;
117
reg [ 3:0] bdrColorReg;
118
reg [ 3:0] pixelWidth;   // horizontal pixel width in clock cycles
119
reg [ 3:0] pixelHeight;  // vertical pixel height in scan lines
120
 
121
wire [11:0] hctr;                // horizontal reference counter (counts clocks since hSync)
122
wire [11:0] scanline;    // scan line
123
wire [11:0] row;         // vertical reference counter (counts rows since vSync)
124
wire [11:0] col;         // horizontal column
125
reg  [ 4:0] rowscan;     // scan line within row
126
wire nxt_row;                   // when to increment the row counter
127
wire nxt_col;                   // when to increment the column counter
128
wire [ 5:0] bcnt;                // blink timing counter
129
wire blink;
130
reg  iblank;
131
 
132
wire nhp;                               // next horizontal pixel
133
wire ld_shft = nxt_col & nhp;
134
 
135
 
136
// display and timing signals
137
reg [15:0] txtAddr;              // index into memory
138
reg [15:0] penAddr;
139
wire [8:0] txtOut;               // character code
140 21 robfinch
wire [8:0] charOut;              // character ROM output
141 3 robfinch
wire [3:0] txtBkCode;    // background color code
142
wire [4:0] txtFgCode;    // foreground color code
143 19 robfinch
reg  [4:0] txtTcCode;    // transparent color code
144
reg  bgt;
145 3 robfinch
 
146
wire [8:0] tdat_o;
147
wire [8:0] cdat_o;
148 21 robfinch
wire [8:0] chdat_o;
149 3 robfinch
 
150
wire [2:0] scanindex = scanline[2:0];
151
 
152
 
153
//--------------------------------------------------------------------
154
// Address Decoding
155
// I/O range FFDx
156
//--------------------------------------------------------------------
157 21 robfinch
wire cs_text = cyc_i && stb_i && (adr_i[63:16]==48'hFFFF_FFFF_FFD0);
158
wire cs_color= cyc_i && stb_i && (adr_i[63:16]==48'hFFFF_FFFF_FFD1);
159
wire cs_rom  = cyc_i && stb_i && (adr_i[63:16]==48'hFFFF_FFFF_FFD2);
160
wire cs_reg  = cyc_i && stb_i && (adr_i[63: 8]==56'hFFFF_FFFF_FFDA_00);
161
wire cs_any = cs_text|cs_color|cs_rom|cs_reg;
162 3 robfinch
 
163 21 robfinch
// Register outputs
164
always @(posedge clk_i)
165 3 robfinch
        if (cs_text) dat_o <= tdat_o;
166
        else if (cs_color) dat_o <= cdat_o;
167
        else if (cs_rom) dat_o <= chdat_o;
168
        else if (cs_reg) dat_o <= rego;
169
        else dat_o <= 16'h0000;
170
 
171
 
172
//--------------------------------------------------------------------
173
// Video Memory
174
//--------------------------------------------------------------------
175
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
176
// Address Calculation:
177
//  - Simple: the row times the number of  cols plus the col plue the
178
//    base screen address
179
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
180 19 robfinch
 
181
wire [17:0] rowcol = row * numCols;
182 3 robfinch
always @(posedge vclk)
183
        txtAddr <= startAddress + rowcol + col;
184
 
185
// text screen RAM
186
syncRam4kx9_1rw1r textRam0
187
(
188
        .wclk(clk_i),
189 19 robfinch
        .wadr(adr_i[13:1]),
190 3 robfinch
        .i(dat_i),
191
        .wo(tdat_o),
192
        .wce(cs_text),
193
        .we(we_i),
194
        .wrst(1'b0),
195
 
196
        .rclk(vclk),
197 19 robfinch
        .radr(txtAddr[12:0]),
198 3 robfinch
        .o(txtOut),
199
        .rce(ld_shft),
200
        .rrst(1'b0)
201
);
202
 
203
// screen attribute RAM
204
syncRam4kx9_1rw1r colorRam0
205
(
206
        .wclk(clk_i),
207 19 robfinch
        .wadr(adr_i[13:1]),
208 3 robfinch
        .i(dat_i),
209
        .wo(cdat_o),
210
        .wce(cs_color),
211
        .we(we_i),
212
        .wrst(1'b0),
213
 
214
        .rclk(vclk),
215 19 robfinch
        .radr(txtAddr[12:0]),
216 3 robfinch
        .o({txtBkCode,txtFgCode}),
217
        .rce(ld_shft),
218
        .rrst(1'b0)
219
);
220
 
221
 
222
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
223
// Character bitmap ROM
224
// - room for 512 characters
225
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
226
syncRam4kx9_1rw1r charRam0
227
(
228
        .wclk(clk_i),
229
        .wadr(adr_i[11:0]),
230
        .i(dat_i),
231
        .wo(chdat_o),
232
        .wce(cs_rom),
233 21 robfinch
        .we(1'b0),//we_i),
234 3 robfinch
        .wrst(1'b0),
235
 
236
        .rclk(vclk),
237
        .radr({txtOut,rowscan[2:0]}),
238
        .o(charOut),
239
        .rce(ld_shft),
240
        .rrst(1'b0)
241
);
242
 
243
 
244
// pipeline delay - sync color with character bitmap output
245
reg [3:0] txtBkCode1;
246
reg [4:0] txtFgCode1;
247
always @(posedge vclk)
248
        if (nhp & ld_shft) txtBkCode1 <= txtBkCode;
249
always @(posedge vclk)
250
        if (nhp & ld_shft) txtFgCode1 <= txtFgCode;
251
 
252
//--------------------------------------------------------------------
253
// bus interfacing
254 21 robfinch
// - there is a two cycle latency for reads, an ack is generated
255 3 robfinch
//   after the synchronous RAM read
256
// - writes can be acknowledged right away.
257
//--------------------------------------------------------------------
258 21 robfinch
reg ramRdy,ramRdy1;
259
always @(posedge clk_i)
260
begin
261
        ramRdy1 <= cs_any & !(ramRdy1|ramRdy);
262
        ramRdy <= ramRdy1 & cs_any;
263
end
264 3 robfinch
 
265 21 robfinch
assign ack_o = (cyc_i & stb_i) ? (we_i ? cs_any : ramRdy) : 1'b0;
266 3 robfinch
 
267 19 robfinch
 
268 3 robfinch
//--------------------------------------------------------------------
269
// Registers
270
//
271
//      00 -         nnnnnnnn  number of columns (horizontal displayed number of characters)
272
//      01 -         nnnnnnnn  number of rows    (vertical displayed number of characters)
273
//      02 -       n nnnnnnnn  window left       (horizontal sync position - reference for left edge of displayed)
274
//      03 -       n nnnnnnnn  window top        (vertical sync position - reference for the top edge of displayed)
275
//      04 -         ---nnnnn  maximum scan line (char ROM max value is 7)
276
//              05 -         hhhhwwww  pixel size, hhhh=height,wwww=width
277
//      08 -         -BPnnnnn  cursor start / blink control
278
//                             BP: 00=no blink
279
//                             BP: 01=no display
280
//                             BP: 10=1/16 field rate blink
281
//                             BP: 11=1/32 field rate blink
282
//      09 -        ----nnnnn  cursor end
283
//      10 - aaaaaaaa aaaaaaaaa  start address (index into display memory)
284
//      11 - aaaaaaaa aaaaaaaaa  cursor position
285
//      12 - aaaaaaaa aaaaaaaaa  light pen position
286
//--------------------------------------------------------------------
287
 
288
//--------------------------------------------------------------------
289
// Light Pen
290
//--------------------------------------------------------------------
291
wire lpe;
292
edge_det u1 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(lp), .pe(lpe), .ne(), .ee() );
293
 
294
always @(posedge clk_i)
295
        if (rst_i)
296
                penAddr <= 32'h0000_0000;
297
        else begin
298
                if (lpe)
299
                        penAddr <= txtAddr;
300
        end
301
 
302
 
303
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
304
// Register read port
305
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
306
always @(cs_reg or cursorPos or penAddr or adr_i)
307
        if (cs_reg) begin
308 19 robfinch
                case(adr_i[4:1])
309
                4'd0:           rego <= numCols;
310
                4'd1:           rego <= numRows;
311 3 robfinch
                4'd11:          rego <= cursorPos;
312
                4'd12:          rego <= penAddr;
313
                default:        rego <= 16'h0000;
314
                endcase
315
        end
316
        else
317
                rego <= 16'h0000;
318
 
319
 
320
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
321
// Register write port
322
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
323
 
324
reg interlace;
325
always @(posedge clk_i)
326
        if (rst_i) begin
327 19 robfinch
// 104x63
328
/*
329
                windowTop    <= 12'd26;
330
                windowLeft   <= 12'd260;
331
                pixelWidth   <= 4'd0;
332
                pixelHeight  <= 4'd1;           // 525 pixels (408 with border)
333
*/
334 3 robfinch
// 52x31
335 21 robfinch
                windowTop    <= 12'd12;
336
                windowLeft   <= 12'd128;
337
                pixelWidth   <= 4'd2;
338
                pixelHeight  <= 4'd2;           // 262 pixels (248 with border)
339 19 robfinch
 
340 3 robfinch
                numCols      <= COLS;
341
                numRows      <= ROWS;
342
                maxScanline  <= 5'd7;
343
                maxScanpix   <= 5'd7;
344
                rBlink       <= 3'b111;         // 01 = non display
345
                startAddress <= 16'h0000;
346
                cursorStart  <= 5'd00;
347
                cursorEnd    <= 5'd31;
348
                cursorPos    <= 16'h0003;
349 19 robfinch
                txtTcCode    <= 5'd31;
350 3 robfinch
        end
351
        else begin
352
 
353
                if (cs_reg & we_i) begin        // register write ?
354
 
355
                        case(adr_i[4:1])
356
                        4'd00:  numCols    <= dat_i;            // horizontal displayed
357
                        4'd01:  numRows    <= dat_i;
358
                        4'd02:  windowLeft <= dat_i[11:0];
359
                        4'd03:  windowTop  <= dat_i[11:0];               // vertical sync position
360
                        4'd04:  maxScanline <= dat_i[4:0];
361
                        4'd05:  begin
362
                                        pixelHeight <= dat_i[7:4];
363
                                        pixelWidth  <= dat_i[3:0];       // horizontal pixel width
364
                                        end
365 19 robfinch
                        4'd07:  txtTcCode   <= dat_i[4:0];
366 3 robfinch
                        4'd08:  begin
367
                                        cursorStart <= dat_i[4:0];       // scan line sursor starts on
368
                                        rBlink      <= dat_i[7:5];
369
                                        end
370
                        4'd09:  cursorEnd   <= dat_i[4:0];       // scan line cursor ends on
371
                        4'd10:  startAddress <= dat_i;
372
                        4'd11:  cursorPos <= dat_i;
373
                        endcase
374
                end
375
        end
376
 
377
 
378
//--------------------------------------------------------------------
379
//--------------------------------------------------------------------
380
 
381
// "Box" cursor bitmap
382
reg [7:0] curout;
383
always @(scanindex)
384
        case(scanindex)
385
        3'd0:   curout = 8'b11111111;
386
        3'd1:   curout = 8'b10000001;
387
        3'd2:   curout = 8'b10000001;
388
        3'd3:   curout = 8'b10000001;
389
        3'd4:   curout = 8'b10000001;
390
        3'd5:   curout = 8'b10000001;
391
        3'd6:   curout = 8'b10011001;
392
        3'd7:   curout = 8'b11111111;
393
        endcase
394
 
395
 
396
//-------------------------------------------------------------
397
// Video Stuff
398
//-------------------------------------------------------------
399 21 robfinch
 
400 3 robfinch
// Horizontal counter:
401
//
402
 
403
HVCounter uhv1
404
(
405
        .rst(rst_i),
406
        .vclk(vclk),
407
        .pixcce(1'b1),
408
        .sync(eol),
409
        .cnt_offs(windowLeft),
410
        .pixsz(pixelWidth),
411
        .maxpix(maxScanpix),
412
        .nxt_pix(nhp),
413
        .pos(col),
414
        .nxt_pos(nxt_col),
415
        .ctr(hctr)
416
);
417
 
418
 
419
// Vertical counter:
420
//
421
HVCounter uhv2
422
(
423
        .rst(rst_i),
424
        .vclk(vclk),
425
        .pixcce(eol),
426
        .sync(eof),
427
        .cnt_offs(windowTop),
428
        .pixsz(pixelHeight),
429
        .maxpix(maxScanline),
430
        .nxt_pix(nvp),
431
        .pos(row),
432
        .nxt_pos(nxt_row),
433
        .ctr(scanline)
434
);
435
 
436
always @(posedge vclk)
437
        rowscan <= scanline - row * (maxScanline+1);
438
 
439
 
440
// Blink counter
441
//
442
VT163 #(6) ub1
443
(
444
        .clk(vclk),
445
        .clr_n(!rst_i),
446
        .ent(eol & eof),
447
        .enp(1'b1),
448
        .ld_n(1'b1),
449
        .d(6'd0),
450
        .q(bcnt)
451
);
452
 
453 21 robfinch
wire blink_en = (cursorPos+2==txtAddr) && (scanline[4:0] >= cursorStart) && (scanline[4:0] <= cursorEnd);
454 3 robfinch
 
455
VT151 ub2
456
(
457
        .e_n(!blink_en),
458
        .s(rBlink),
459
        .i0(1'b1), .i1(1'b0), .i2(bcnt[4]), .i3(bcnt[5]),
460
        .i4(1'b1), .i5(1'b0), .i6(bcnt[4]), .i7(bcnt[5]),
461
        .z(blink),
462
        .z_n()
463
);
464
 
465 21 robfinch
// These tables map a five bit color code to an 24 bit color value.
466 3 robfinch
rtfColorROM ucm1 (.clk(vclk), .ce(nhp & ld_shft), .code(txtBkCode1),  .color(bkColor24) );
467 19 robfinch
rtfColorROM ucm2 (.clk(vclk), .ce(nhp & ld_shft), .code(txtFgCode1),  .color(fgColor24) );
468
always @(posedge vclk)
469
        if (nhp & ld_shft)
470
                bgt <= {1'b0,txtBkCode1}==txtTcCode;
471 3 robfinch
 
472
 
473
// Convert character bitmap to pixels
474
// For convenience, the character bitmap data in the ROM is in the
475
// opposite bit order to what's needed for the display. The following
476
// just alters the order without adding any hardware.
477
//
478
wire [7:0] charRev = {
479
        charOut[0],
480
        charOut[1],
481
        charOut[2],
482
        charOut[3],
483
        charOut[4],
484
        charOut[5],
485
        charOut[6],
486
        charOut[7]
487
};
488
 
489
wire [7:0] charout1 = blink ? (charRev ^ curout) : charRev;
490
 
491
// Convert parallel to serial
492
ParallelToSerial ups1
493
(
494
        .rst(rst_i),
495
        .clk(vclk),
496
        .ce(nhp),
497
        .ld(ld_shft),
498
        .qin(1'b0),
499
        .d(charout1),
500
        .qh(pix)
501
);
502
 
503 19 robfinch
 
504
// Pipelining Effect:
505
// - character output is delayed by 3 character times relative to the video counters.
506
// - this means we must adapt the blanking signal by shifting the blanking window
507
//   three character times.
508 3 robfinch
wire bpix = hctr[1] ^ scanline[4];// ^ blink;
509
always @(posedge vclk)
510
        if (nhp)
511 21 robfinch
                iblank <= (row >= numRows) || (col >= numCols + 2) || (col < 2);
512 3 robfinch
 
513
 
514
// Choose between input RGB and controller generated RGB
515
// Select between foreground and background colours.
516
always @(posedge vclk)
517
        if (nhp) begin
518
                casex({blank,iblank,border,bpix,pix})
519
                5'b1xxxx:       rgbOut <= 25'h0000000;
520
                5'b01xxx:       rgbOut <= rgbIn;
521
                5'b0010x:       rgbOut <= 24'hBF2020;
522
                5'b0011x:       rgbOut <= 24'hDFDFDF;
523 19 robfinch
                5'b000x0:       rgbOut <= bgt ? rgbIn : bkColor24;
524 3 robfinch
                5'b000x1:       rgbOut <= fgColor24;
525
                default:        rgbOut <= rgbIn;
526
                endcase
527
        end
528
 
529
endmodule
530
 

powered by: WebSVN 2.1.0

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