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

Subversion Repositories rtf68ksys

[/] [rtf68ksys/] [trunk/] [rtl/] [verilog/] [rtfBitmapController.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 robfinch
// ============================================================================
2
//  Bitmap Controller (416h x 262v x 8bpp):
3
//  - Displays a bitmap from memory.
4
//  - the video mode timing to be 1680x1050
5
//
6
//
7
//      (C) 2008,2010,2011  Robert Finch
8
//      robfinch<remove>@opencores.org
9
//
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
//
25
//  The default base screen address is:
26
//              $20000 - the second 128 kb of RAM
27
//
28
//
29
//      Verilog 1995
30
//      Webpack 9.2i  xc3s1200-4fg320
31
//      64 slices / 118 LUTs / 175.009 MHz
32
//  72 ff's / 2 BRAM (2048x16)
33
//
34
// ============================================================================
35
 
36
module rtfBitmapController(
37
        rst_i, clk_i, bte_o, cti_o, cyc_o, stb_o, ack_i, we_o, sel_o, adr_o, dat_i, dat_o,
38
        vclk, eol, eof, blank, rgbo, page
39
);
40
parameter BM_BASE_ADDR1 = 44'h000_0002_0000;
41
parameter BM_BASE_ADDR2 = 44'h000_0004_0000;
42
 
43
// SYSCON
44
input rst_i;                            // system reset
45
input clk_i;                            // system bus interface clock
46
 
47
// Video Master Port
48
// Used to read memory via burst access
49
output [1:0] bte_o;
50
output [2:0] cti_o;
51
output cyc_o;                   // video burst request
52
output stb_o;
53
input  ack_i;                   // vid_acknowledge from memory
54
output we_o;
55
output [ 1:0] sel_o;
56
output [43:0] adr_o;     // address for memory access
57
input  [15:0] dat_i;     // memory data input
58
output [15:0] dat_o;
59
 
60
// Video
61
input vclk;                             // Video clock 73.529 MHz
62
input eol;                              // end of scan line
63
input eof;                              // end of frame
64
input blank;                    // blank the output
65
output [7:0] rgbo;               // 8-bit RGB output
66
reg [7:0] rgbo;
67
 
68
input page;                             // which page to display
69
 
70
 
71
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
72
// IO registers
73
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
74
reg [1:0] bte_o;
75
reg [2:0] cti_o;
76
reg cyc_o;
77
reg stb_o;
78
reg we_o;
79
reg [1:0] sel_o;
80
reg [43:0] adr_o;
81
reg [15:0] dat_o;
82
 
83
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
84
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
85
wire [11:0] hctr;                // horizontal reference counter
86
wire [11:0] vctr;                // vertical reference counter
87
wire [11:0] vctr1 = vctr + 12'd4;
88
reg [43:0] baseAddr;     // base address register
89
wire [7:0] rgbo1;
90
reg [11:0] pixelRow;
91
reg [11:0] pixelCol;
92
 
93
always @(page)
94
        baseAddr = page ? BM_BASE_ADDR2 : BM_BASE_ADDR1;
95
 
96
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
97
// Horizontal and Vertical timing reference counters
98
// - The memory fetch address is determined from these counters.
99
// - The counters are setup with negative values so that the zero
100
//   point coincides with the top left of the display.
101
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
102
 
103
counter #(12) u1 (.rst(1'b0), .clk(vclk), .ce(1'b1), .ld(eol), .d(12'hEE4), .q(hctr));
104
counter #(12) u2 (.rst(1'b0), .clk(vclk), .ce(eol),  .ld(eof), .d(12'hFDC), .q(vctr));
105
 
106
 
107
// Pixel row and column are derived from the horizontal and vertical counts.
108
 
109
always @(vctr1)
110
        pixelRow = vctr1[11:2];
111
always @(hctr)
112
        pixelCol = hctr[11:1];
113
 
114
 
115
wire vFetch = (vctr < 12'd1050) || (vctr > 12'hFF8);
116
 
117
// Video Request Block
118
// 416x262
119
// - Issue a request for access to memory every 160 clock cycles
120
// - Reset the request flag once an access has been initiated.
121
// - 128 bytes (pixels) are read per scan line
122
// - It takes about 18 clock cycles @ 25 MHz to access 32 bytes of data
123
//   through the memory contoller, or about 53 video clocks
124
//   83 video clocks with a 16 MHZ memory controller.
125
 
126
reg [2:0] vreq;
127
 
128
// Must be vclk. vid_req will be active for numerous clock cycles as
129
// a burst type fetch is used. The ftch and vFetch may only be
130
// active for a single video clock cycle. vclk must be used so these
131
// signals are not missed due to a clock domain crossing. We luck
132
// out here because of the length of time vid_req is active.
133
//
134
always @(posedge vclk)
135
begin
136
        if (vFetch) begin
137
                if (vctr1[1:0]!=2'd3) begin      // we only need 13 memory accesses
138
                        if (hctr==12'd16) vreq <= 3'b100;
139
                        if (hctr==12'd176) vreq <= 3'b101;
140
                        if (hctr==12'd336) vreq <= 3'b110;
141
                        if (hctr==12'd496) vreq <= 3'b111;
142
                end
143
                else
144
                        if (hctr==12'd16) vreq <= 3'b100;
145
        end
146
        if (cyc_o) vreq <= 3'b000;
147
end
148
 
149
// Cross the clock domain with the request signal
150
reg do_cyc;
151
always @(posedge clk_i)
152
        do_cyc <= vreq[2];
153
 
154
wire[19:0] rowOffset = pixelRow * 10'd416;
155
reg [8:0] fetchCol;
156
 
157
// - read from assigned video memory address, using burst mode reads
158
// - 32 pixels at a time are read
159
// - video data is fetched one pixel row in advance
160
//
161
reg [3:0] bcnt;
162
always @(posedge clk_i)
163
if (rst_i) begin
164
        bte_o <= 2'b00;         // linear burst
165
        cti_o <= 3'b000;        // classic cycle
166
        cyc_o <= 1'b0;
167
        stb_o <= 1'b0;
168
        sel_o <= 2'b00;
169
        we_o <= 1'b0;
170
        adr_o <= 44'h000_0000_0000;
171
        dat_o <= 16'h0000;
172
        fetchCol <= 9'd0;
173
        bcnt <= 4'd0;
174
end
175
else begin
176
        if (do_cyc & !cyc_o) begin
177
                cti_o <= 3'b010;        // incrementing burst cycle
178
                cyc_o <= 1'b1;
179
                stb_o <= 1'b1;
180
                sel_o <= 2'b11;
181
                bcnt <= 4'd0;
182
                fetchCol <= {vctr1[1:0],vreq[1:0],5'h00};
183
                // This works out to be an even multiple of 32 bytes
184
                adr_o <= baseAddr + rowOffset + 10'd416 + {vctr1[1:0],vreq[1:0],5'h00};
185
        end
186
        if (cyc_o & ack_i) begin
187
                adr_o <= adr_o + 32'd2;
188
                fetchCol <= fetchCol + 9'd2;
189
                bcnt <= bcnt + 4'd1;
190
                if (bcnt==4'd14)
191
                        cti_o <= 3'b111;        // end of burst
192
                if (bcnt==4'd15) begin
193
                        cti_o <= 3'b000;        // classic cycles again
194
                        cyc_o <= 1'b0;
195
                        stb_o <= 1'b0;
196
                        sel_o <= 2'b00;
197
                        adr_o <= 44'h000_0000_0000;
198
                end
199
        end
200
end
201
 
202
 
203
always @(posedge vclk)
204
        rgbo <= rgbo1;
205
 
206
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
207
// Video Line Buffer
208
// - gets written in bursts, but read continuously
209
// - buffer is used as two halves - one half is displayed (read) while
210
//   the other is fetched (write).
211
// - only the lower eleven bits of the address are used as an index,
212
//   these bits will match with the addresses generated by the burst
213
//   controller above.
214
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
215
 
216
// Storage for 2048x8 bit pixels (2048x8 data)
217
 
218
RAMB16_S9_S18 ram0
219
(
220
        .CLKA(vclk),
221
        .ADDRA({pixelRow[0],pixelCol[8:1],~pixelCol[0]}), // <- pixelCol[0] nonsense, we need the highest pixel first
222
        .DIA(8'hFF),
223
        .DIPA(1'b1),
224
        .DOA(rgbo1),
225
        .ENA(1'b1),
226
        .WEA(1'b0),
227
        .SSRA(blank),
228
 
229
        .CLKB(clk_i),
230
        .ADDRB({~pixelRow[0],fetchCol[8:1]}),
231
        .DIB(dat_i),
232
        .DIPB(2'b11),
233
        .DOB(),
234
        .ENB(cyc_o),
235
        .WEB(ack_i),
236
        .SSRB(1'b0)
237
);
238
 
239
endmodule

powered by: WebSVN 2.1.0

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