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

Subversion Repositories rtfbitmapcontroller

[/] [rtfbitmapcontroller/] [trunk/] [rtl/] [verilog/] [rfFrameBuffer_fta64.sv] - Blame information for rev 25

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2008-2023  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch@finitron.ca
7
//       ||
8
//
9
// rfFrameBuffer_fta64.sv
10
//  - Displays a bitmap from memory.
11
//
12
//
13
// BSD 3-Clause License
14
// Redistribution and use in source and binary forms, with or without
15
// modification, are permitted provided that the following conditions are met:
16
//
17
// 1. Redistributions of source code must retain the above copyright notice, this
18
//    list of conditions and the following disclaimer.
19
//
20
// 2. Redistributions in binary form must reproduce the above copyright notice,
21
//    this list of conditions and the following disclaimer in the documentation
22
//    and/or other materials provided with the distribution.
23
//
24
// 3. Neither the name of the copyright holder nor the names of its
25
//    contributors may be used to endorse or promote products derived from
26
//    this software without specific prior written permission.
27
//
28
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
32
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
//
39
//
40
//  The default base screen address is:
41
//              $0200000 - the third meg of RAM
42
//
43
// ============================================================================
44
 
45
//`define USE_CLOCK_GATE        1'b1
46
`define INTERNAL_SYNC_GEN       1'b1
47
`define WXGA800x600             1'b1
48
//`define WXGA1366x768  1'b1
49
`define FBC_ADDR                32'hFD0400001
50
 
51
import const_pkg::*;
52
`define ABITS   31:0
53
 
54
import fta_bus_pkg::*;
55
import gfx_pkg::*;
56
 
57
module rfFrameBuffer_fta64(
58
        rst_i,
59
        irq_o,
60
        cs_config_i,
61
        cs_io_i,
62
        s_clk_i, s_req, s_resp,
63
        m_clk_i, m_fst_o,
64
//      m_cyc_o, m_stb_o, m_ack_i, m_we_o, m_sel_o, m_adr_o, m_dat_i, m_dat_o,
65
        m_req, m_resp,
66
        dot_clk_i, rgb_i, rgb_o, xonoff_i, xal_o
67
`ifdef INTERNAL_SYNC_GEN
68
        , hsync_o, vsync_o, blank_o, border_o, hctr_o, vctr_o, fctr_o, vblank_o
69
`else
70
        , hsync_i, vsync_i, blank_i
71
`endif
72
);
73
parameter BUSWID = 64;
74
 
75
parameter FBC_ADDR = 32'hFED70001;
76
parameter FBC_ADDR_MASK = 32'h00FF0000;
77
 
78
parameter CFG_BUS = 8'd0;
79
parameter CFG_DEVICE = 5'd0;
80
parameter CFG_FUNC = 3'd0;
81
parameter CFG_VENDOR_ID =       16'h0;
82
parameter CFG_DEVICE_ID =       16'h0;
83
parameter CFG_SUBSYSTEM_VENDOR_ID       = 16'h0;
84
parameter CFG_SUBSYSTEM_ID = 16'h0;
85
parameter CFG_ROM_ADDR = 32'hFFFFFFF0;
86
 
87
parameter CFG_REVISION_ID = 8'd0;
88
parameter CFG_PROGIF = 8'd1;
89
parameter CFG_SUBCLASS = 8'h80;                                 // 80 = Other
90
parameter CFG_CLASS = 8'h03;                                            // 03 = display controller
91
parameter CFG_CACHE_LINE_SIZE = 8'd8;           // 32-bit units
92
parameter CFG_MIN_GRANT = 8'h00;
93
parameter CFG_MAX_LATENCY = 8'h00;
94
parameter CFG_IRQ_LINE = 8'd6;
95
 
96
localparam CFG_HEADER_TYPE = 8'h00;                     // 00 = a general device
97
 
98
parameter MSIX = 1'b0;
99
parameter IRQ_MSGADR = 64'h0FD0900C1;
100
parameter IRQ_MSGDAT = 64'h1;
101
 
102
parameter PHYS_ADDR_BITS = 32;
103
localparam BITS_IN_ADDR_MAP = PHYS_ADDR_BITS - 16;
104
 
105
parameter MDW = 128;            // Bus master data width
106
parameter MAP = 12'd0;
107
parameter BM_BASE_ADDR1 = 32'h00000000;
108
parameter BM_BASE_ADDR2 = 32'h00100000;
109
parameter REG_CTRL = 11'd0;
110
parameter REG_REFDELAY = 11'd1;
111
parameter REG_PAGE1ADDR = 11'd2;
112
parameter REG_PAGE2ADDR = 11'd3;
113
parameter REG_PXYZ = 11'd4;
114
parameter REG_PCOLCMD = 11'd5;
115
parameter REG_TOTAL = 11'd8;
116
parameter REG_SYNC_ONOFF = 11'd9;
117
parameter REG_BLANK_ONOFF = 11'd10;
118
parameter REG_BORDER_ONOFF = 11'd11;
119
parameter REG_RASTCMP = 11'd12;
120
parameter REG_BMPSIZE = 11'd13;
121
parameter REG_OOB_COLOR = 11'd14;
122
parameter REG_WINDOW = 11'd15;
123
parameter REG_IRQ_MSGADR = 11'd16;
124
parameter REG_IRQ_MSGDAT = 11'd17;
125
parameter REG_TRANS_COLOR = 11'd18;
126
 
127
parameter OPBLACK = 4'd0;
128
parameter OPCOPY = 4'd1;
129
parameter OPINV = 4'd2;
130
parameter OPAND = 4'd4;
131
parameter OPOR = 4'd5;
132
parameter OPXOR = 4'd6;
133
parameter OPANDN = 4'd7;
134
parameter OPNAND = 4'd8;
135
parameter OPNOR = 4'd9;
136
parameter OPXNOR = 4'd10;
137
parameter OPORN = 4'd11;
138
parameter OPWHITE = 4'd15;
139
 
140
// Sync Generator defaults: 800x600 60Hz
141
// Driven by a 40MHz clock
142
`ifdef WXGA800x600
143
parameter phSyncOn  = 40;               //   40 front porch
144
parameter phSyncOff = 168;              //  128 sync
145
parameter phBlankOff = 252;     //256   //   88 back porch
146
//parameter phBorderOff = 336;  //   80 border
147
parameter phBorderOff = 256;    //   80 border
148
//parameter phBorderOn = 976;           //  640 display
149
parameter phBorderOn = 1056;            //  800 display
150
parameter phBlankOn = 1052;             //   4 border
151
parameter phTotal = 1056;               // 1056 total clocks
152
parameter pvSyncOn  = 1;                //    1 front porch
153
parameter pvSyncOff = 5;                //    4 vertical sync
154
parameter pvBlankOff = 28;              //   23 back porch
155
parameter pvBorderOff = 28;             //   44 border  0
156
//parameter pvBorderOff = 72;           //   44 border  0
157
parameter pvBorderOn = 628;             //  600 display
158
//parameter pvBorderOn = 584;           //  512 display
159
parameter pvBlankOn = 628;      //   44 border  0
160
parameter pvTotal = 628;                //  628 total scan lines
161
`endif
162
`ifdef WXGA1366x768
163
// Driven by an 85.86MHz clock
164
parameter phSyncOn  = 72;               //   72 front porch
165
parameter phSyncOff = 216;              //  144 sync
166
parameter phBlankOff = 434;             //  212 back porch
167
parameter phBorderOff = 434;    //    0 border
168
parameter phBorderOn = 1800;    // 1366 display
169
parameter phBlankOn = 1800;             //    0 border
170
parameter phTotal = 1800;               // 1800 total clocks
171
// 47.7 = 60 * 795 kHz
172
parameter pvSyncOn  = 2;                //    1 front porch
173
parameter pvSyncOff = 5;                //    3 vertical sync
174
parameter pvBlankOff = 27;              //   23 back porch
175
parameter pvBorderOff = 27;             //    2 border  0
176
parameter pvBorderOn = 795;             //  768 display
177
parameter pvBlankOn = 795;      //    1 border  0
178
parameter pvTotal = 795;                //  795 total scan lines
179
`endif
180
 
181
// SYSCON
182
input rst_i;                            // system reset
183
output reg [31:0] irq_o;
184
 
185
input cs_config_i;
186
input cs_io_i;
187
 
188
// Peripheral IO slave port
189
input s_clk_i;
190
input fta_cmd_request64_t s_req;
191
output fta_cmd_response64_t s_resp;
192
 
193
// Video Memory Master Port
194
// Used to read memory via burst access
195
input m_clk_i;                          // system bus interface clock
196
output reg m_fst_o;             // first access on scanline
197
output fta_cmd_request128_t m_req;
198
input fta_cmd_response128_t m_resp;
199
 
200
// Video
201
input dot_clk_i;                // Video clock 80 MHz
202
`ifdef INTERNAL_SYNC_GEN
203
output hsync_o;
204
output vsync_o;
205
output blank_o;
206
output vblank_o;
207
output border_o;
208
output [11:0] hctr_o;
209
output [11:0] vctr_o;
210
output [5:0] fctr_o;
211
`else
212
input hsync_i;                  // start/end of scan line
213
input vsync_i;                  // start/end of frame
214
input blank_i;                  // blank the output
215
`endif
216
input [31:0] rgb_i;
217
output [31:0] rgb_o;            // 32-bit RGB output
218
reg [31:0] rgb_o;
219
 
220
input xonoff_i;
221
output reg xal_o;               // external access line (sprite access)
222
 
223
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
224
// IO registers
225
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
226
reg irq;
227
reg rst_irq,rst_irq2;
228
 
229
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
230
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
231
wire vclk;
232
reg cs,cs2;
233
reg cs_config;
234
reg cs_map;
235
reg cs_reg;
236
wire cs_edge;
237
reg we;
238
reg [7:0] sel;
239
reg [31:0] adri;
240
reg [63:0] dat;
241
wire irq_en;
242
reg [63:0] s_dat_o;
243
wire ack;
244
 
245
always_ff @(posedge s_clk_i)
246
        cs <= s_req.cyc & s_req.stb & cs_io_i;
247
always_ff @(posedge s_clk_i)
248
        we <= s_req.we;
249
always_ff @(posedge s_clk_i)
250
        sel <= s_req.sel;
251
always_ff @(posedge s_clk_i)
252
        adri <= s_req.padr;
253
always_ff @(posedge s_clk_i)
254
        dat <= s_req.dat;
255
 
256
always_ff @(posedge s_clk_i)
257
        cs_config <= s_req.cyc & s_req.stb & cs_config_i && adri[27:20]==CFG_BUS && adri[19:15]==CFG_DEVICE && adri[14:12]==CFG_FUNC;
258
wire cs_fbc;
259
always_comb
260
        cs_map = cs && cs_fbc && adri[15:14]==3'd1;
261
always_comb
262
        cs_reg = cs && cs_fbc && adri[15:14]==3'd0;
263
 
264
assign s_resp.next = 1'b0;
265
assign s_resp.stall = 1'b0;
266
assign s_resp.err = 1'b0;
267
assign s_resp.rty = 1'b0;
268
assign s_resp.pri = 4'd7;
269
assign s_resp.dat = s_dat_o;
270
 
271
vtdl #(.WID(1), .DEP(16)) urdyd1 (.clk(s_clk_i), .ce(1'b1), .a(4'd3), .d(cs_map|cs_reg|cs_config), .q(ack));
272
vtdl #(.WID(1), .DEP(16)) urdyd2 (.clk(s_clk_i), .ce(1'b1), .a(4'd4), .d(cs_map|cs_reg|cs_config), .q(s_resp.ack));
273
vtdl #(.WID(4), .DEP(16)) urdyd3 (.clk(s_clk_i), .ce(1'b1), .a(4'd5), .d(s_req.cid), .q(s_resp.cid));
274
vtdl #(.WID($bits(fta_tranid_t)), .DEP(16)) urdyd4 (.clk(s_clk_i), .ce(1'b1), .a(4'd5), .d(s_req.tid), .q(s_resp.tid));
275
vtdl #(.WID(32), .DEP(16)) urdyd5 (.clk(s_clk_i), .ce(1'b1), .a(4'd5), .d(s_req.padr), .q(s_resp.adr));
276
 
277
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
278
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
279
integer n, n1;
280
reg [31:0] fbc_addr;
281
reg [11:0] rastcmp;
282
reg [`ABITS] bm_base_addr1,bm_base_addr2;
283
color_depth_t color_depth, color_depth2;
284
wire [7:0] fifo_cnt;
285
reg onoff;
286
reg [2:0] hres,vres;
287
reg greyscale;
288
reg page;
289
reg [3:0] pals;                         // palette select
290
reg [15:0] hrefdelay;
291
reg [15:0] vrefdelay;
292
reg [15:0] windowLeft;
293
reg [15:0] windowTop;
294
reg [11:0] windowWidth,windowHeight;
295
reg [11:0] map;     // memory access period
296
reg [11:0] mapctr;
297
reg [15:0] bmpWidth;            // scan line increment (pixels)
298
reg [15:0] bmpHeight;
299
reg [`ABITS] baseAddr;  // base address register
300
wire [MDW-1:0] rgbo1, rgbo1e, rgbo1o, rgbo1m;
301
reg [15:0] pixelRow;
302
reg [15:0] pixelCol;
303
wire [63:0] pal_wo;
304
wire [31:0] pal_o;
305
reg [15:0] px;
306
reg [15:0] py;
307
reg [7:0] pz;
308
reg [1:0] pcmd,pcmd_o;
309
reg [3:0] raster_op;
310
reg [31:0] zrgb;
311
reg [31:0] oob_color;           // out-of-bounds color
312
reg [31:0] trans_color; // transparent color
313
reg [31:0] color;
314
reg [31:0] color_o;
315
reg rstcmd,rstcmd1;
316
reg [11:0] hTotal = phTotal;
317
reg [11:0] vTotal = pvTotal;
318
reg [11:0] hSyncOn = phSyncOn, hSyncOff = phSyncOff;
319
reg [11:0] vSyncOn = pvSyncOn, vSyncOff = pvSyncOff;
320
reg [11:0] hBlankOn = phBlankOn, hBlankOff = phBlankOff;
321
reg [11:0] vBlankOn = pvBlankOn, vBlankOff = pvBlankOff;
322
reg [11:0] hBorderOn = phBorderOn, hBorderOff = phBorderOff;
323
reg [11:0] vBorderOn = pvBorderOn, vBorderOff = pvBorderOff;
324
reg sgLock;
325
wire pe_hsync, pe_hsync2;
326
wire pe_vsync;
327
reg [11:0] tocnt;               // bus timeout counter
328
reg vm_cyc_o;
329
reg [31:0] vm_adr_o;
330
 
331
// config
332
reg [63:0] irq_msgadr = IRQ_MSGADR;
333
reg [63:0] irq_msgdat = IRQ_MSGDAT;
334
 
335
wire [BUSWID-1:0] cfg_out;
336
generate begin : gConfigSpace
337
        if (BUSWID==32) begin
338
                pci32_config #(
339
                        .CFG_BUS(CFG_BUS),
340
                        .CFG_DEVICE(CFG_DEVICE),
341
                        .CFG_FUNC(CFG_FUNC),
342
                        .CFG_VENDOR_ID(CFG_VENDOR_ID),
343
                        .CFG_DEVICE_ID(CFG_DEVICE_ID),
344
                        .CFG_BAR0(FBC_ADDR),
345
                        .CFG_BAR0_MASK(FBC_ADDR_MASK),
346
                        .CFG_SUBSYSTEM_VENDOR_ID(CFG_SUBSYSTEM_VENDOR_ID),
347
                        .CFG_SUBSYSTEM_ID(CFG_SUBSYSTEM_ID),
348
                        .CFG_ROM_ADDR(CFG_ROM_ADDR),
349
                        .CFG_REVISION_ID(CFG_REVISION_ID),
350
                        .CFG_PROGIF(CFG_PROGIF),
351
                        .CFG_SUBCLASS(CFG_SUBCLASS),
352
                        .CFG_CLASS(CFG_CLASS),
353
                        .CFG_CACHE_LINE_SIZE(CFG_CACHE_LINE_SIZE),
354
                        .CFG_MIN_GRANT(CFG_MIN_GRANT),
355
                        .CFG_MAX_LATENCY(CFG_MAX_LATENCY),
356
                        .CFG_IRQ_LINE(CFG_IRQ_LINE)
357
                )
358
                ucfg1
359
                (
360
                        .rst_i(rst_i),
361
                        .clk_i(s_clk_i),
362
                        .irq_i(irq),
363
                        .irq_o(irq_o),
364
                        .cs_config_i(cs_config),
365
                        .we_i(we),
366
                        .sel_i(sel),
367
                        .adr_i(adri),
368
                        .dat_i(dat),
369
                        .dat_o(cfg_out),
370
                        .cs_bar0_o(cs_fbc),
371
                        .cs_bar1_o(),
372
                        .cs_bar2_o(),
373
                        .irq_en_o(irq_en)
374
                );
375
        end
376
        else if (BUSWID==64) begin
377
                pci64_config #(
378
                        .CFG_BUS(CFG_BUS),
379
                        .CFG_DEVICE(CFG_DEVICE),
380
                        .CFG_FUNC(CFG_FUNC),
381
                        .CFG_VENDOR_ID(CFG_VENDOR_ID),
382
                        .CFG_DEVICE_ID(CFG_DEVICE_ID),
383
                        .CFG_BAR0(FBC_ADDR),
384
                        .CFG_BAR0_MASK(FBC_ADDR_MASK),
385
                        .CFG_SUBSYSTEM_VENDOR_ID(CFG_SUBSYSTEM_VENDOR_ID),
386
                        .CFG_SUBSYSTEM_ID(CFG_SUBSYSTEM_ID),
387
                        .CFG_ROM_ADDR(CFG_ROM_ADDR),
388
                        .CFG_REVISION_ID(CFG_REVISION_ID),
389
                        .CFG_PROGIF(CFG_PROGIF),
390
                        .CFG_SUBCLASS(CFG_SUBCLASS),
391
                        .CFG_CLASS(CFG_CLASS),
392
                        .CFG_CACHE_LINE_SIZE(CFG_CACHE_LINE_SIZE),
393
                        .CFG_MIN_GRANT(CFG_MIN_GRANT),
394
                        .CFG_MAX_LATENCY(CFG_MAX_LATENCY),
395
                        .CFG_IRQ_LINE(CFG_IRQ_LINE)
396
                )
397
                ucfg1
398
                (
399
                        .rst_i(rst_i),
400
                        .clk_i(s_clk_i),
401
                        .irq_i(irq),
402
                        .irq_o(irq_o),
403
                        .cs_config_i(cs_config),
404
                        .we_i(we),
405
                        .sel_i(sel),
406
                        .adr_i(adri),
407
                        .dat_i(dat),
408
                        .dat_o(cfg_out),
409
                        .cs_bar0_o(cs_fbc),
410
                        .cs_bar1_o(),
411
                        .cs_bar2_o(),
412
                        .irq_en_o(irq_en)
413
                );
414
        end
415
end
416
endgenerate
417
 
418
wire [15:0] map_page;
419
wire [15:0] map_out;
420
 
421
   // xpm_memory_tdpram: True Dual Port RAM
422
   // Xilinx Parameterized Macro, version 2022.2
423
 
424
   xpm_memory_tdpram #(
425
      .ADDR_WIDTH_A(11),               // DECIMAL
426
      .ADDR_WIDTH_B(11),               // DECIMAL
427
      .AUTO_SLEEP_TIME(0),             // DECIMAL
428
      .BYTE_WRITE_WIDTH_A(BITS_IN_ADDR_MAP),
429
      .BYTE_WRITE_WIDTH_B(BITS_IN_ADDR_MAP),
430
      .CASCADE_HEIGHT(0),             // DECIMAL
431
      .CLOCKING_MODE("independent_clock"), // String
432
      .ECC_MODE("no_ecc"),            // String
433
      .MEMORY_INIT_FILE("fb_map.mem"),      // String
434
      .MEMORY_INIT_PARAM(""),        // String
435
      .MEMORY_OPTIMIZATION("true"),   // String
436
      .MEMORY_PRIMITIVE("auto"),      // String
437
      .MEMORY_SIZE(2048*BITS_IN_ADDR_MAP),
438
      .MESSAGE_CONTROL(0),            // DECIMAL
439
      .READ_DATA_WIDTH_A(BITS_IN_ADDR_MAP),
440
      .READ_DATA_WIDTH_B(BITS_IN_ADDR_MAP),
441
      .READ_LATENCY_A(2),             // DECIMAL
442
      .READ_LATENCY_B(2),             // DECIMAL
443
      .READ_RESET_VALUE_A("0"),       // String
444
      .READ_RESET_VALUE_B("0"),       // String
445
      .RST_MODE_A("SYNC"),            // String
446
      .RST_MODE_B("SYNC"),            // String
447
      .SIM_ASSERT_CHK(0),             // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
448
      .USE_EMBEDDED_CONSTRAINT(0),    // DECIMAL
449
      .USE_MEM_INIT(1),               // DECIMAL
450
      .USE_MEM_INIT_MMI(0),           // DECIMAL
451
      .WAKEUP_TIME("disable_sleep"),  // String
452
      .WRITE_DATA_WIDTH_A(16),        // DECIMAL
453
      .WRITE_DATA_WIDTH_B(16),        // DECIMAL
454
      .WRITE_MODE_A("no_change"),     // String
455
      .WRITE_MODE_B("no_change"),     // String
456
      .WRITE_PROTECT(1)               // DECIMAL
457
   )
458
   umap (
459
      .dbiterra(),             // 1-bit output: Status signal to indicate double bit error occurrence
460
                                       // on the data output of port A.
461
 
462
      .dbiterrb(),             // 1-bit output: Status signal to indicate double bit error occurrence
463
                                       // on the data output of port A.
464
 
465
      .douta(map_out),                       // READ_DATA_WIDTH_A-bit output: Data output for port A read operations.
466
      .doutb(map_page),      // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
467
      .sbiterra(),             // 1-bit output: Status signal to indicate single bit error occurrence
468
                                       // on the data output of port A.
469
 
470
      .sbiterrb(),             // 1-bit output: Status signal to indicate single bit error occurrence
471
                                       // on the data output of port B.
472
 
473
      .addra(adri[13:3]),              // ADDR_WIDTH_A-bit input: Address for port A write and read operations.
474
      .addrb(vm_adr_o[26:16]),         // ADDR_WIDTH_B-bit input: Address for port B write and read operations.
475
      .clka(s_clk_i),                  // 1-bit input: Clock signal for port A. Also clocks port B when
476
                                       // parameter CLOCKING_MODE is "common_clock".
477
 
478
      .clkb(m_clk_i),                  // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is
479
                                       // "independent_clock". Unused when parameter CLOCKING_MODE is
480
                                       // "common_clock".
481
 
482
      .dina(dat[15:0]),                // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
483
      .dinb(16'd0),                    // WRITE_DATA_WIDTH_B-bit input: Data input for port B write operations.
484
      .ena(cs_map),                    // 1-bit input: Memory enable signal for port A. Must be high on clock
485
                                       // cycles when read or write operations are initiated. Pipelined
486
                                       // internally.
487
 
488
      .enb(onoff),                     // 1-bit input: Memory enable signal for port B. Must be high on clock
489
                                       // cycles when read or write operations are initiated. Pipelined
490
                                       // internally.
491
 
492
      .injectdbiterra(1'b0), // 1-bit input: Controls double bit error injection on input data when
493
                                       // ECC enabled (Error injection capability is not available in
494
                                       // "decode_only" mode).
495
 
496
      .injectdbiterrb(1'b0), // 1-bit input: Controls double bit error injection on input data when
497
                                       // ECC enabled (Error injection capability is not available in
498
                                       // "decode_only" mode).
499
 
500
      .injectsbiterra(1'b0), // 1-bit input: Controls single bit error injection on input data when
501
                                       // ECC enabled (Error injection capability is not available in
502
                                       // "decode_only" mode).
503
 
504
      .injectsbiterrb(1'b0), // 1-bit input: Controls single bit error injection on input data when
505
                                       // ECC enabled (Error injection capability is not available in
506
                                       // "decode_only" mode).
507
 
508
      .regcea(1'b1),                 // 1-bit input: Clock Enable for the last register stage on the output
509
                                       // data path.
510
 
511
      .regceb(onoff),                 // 1-bit input: Clock Enable for the last register stage on the output
512
                                       // data path.
513
 
514
      .rsta(1'b0),                     // 1-bit input: Reset signal for the final port A output register stage.
515
                                       // Synchronously resets output port douta to the value specified by
516
                                       // parameter READ_RESET_VALUE_A.
517
 
518
      .rstb(1'b0),                     // 1-bit input: Reset signal for the final port B output register stage.
519
                                       // Synchronously resets output port doutb to the value specified by
520
                                       // parameter READ_RESET_VALUE_B.
521
 
522
      .sleep(~onoff),                  // 1-bit input: sleep signal to enable the dynamic power saving feature.
523
      .wea(we),                        // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector
524
                                       // for port A input data port dina. 1 bit wide when word-wide writes are
525
                                       // used. In byte-wide write configurations, each bit controls the
526
                                       // writing one byte of dina to address addra. For example, to
527
                                       // synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
528
                                       // is 32, wea would be 4'b0010.
529
 
530
      .web(1'b0)                       // WRITE_DATA_WIDTH_B/BYTE_WRITE_WIDTH_B-bit input: Write enable vector
531
                                       // for port B input data port dinb. 1 bit wide when word-wide writes are
532
                                       // used. In byte-wide write configurations, each bit controls the
533
                                       // writing one byte of dinb to address addrb. For example, to
534
                                       // synchronously write only bits [15-8] of dinb when WRITE_DATA_WIDTH_B
535
                                       // is 32, web would be 4'b0010.
536
 
537
   );
538
 
539
always_comb
540
        m_req.padr <= {map_page,vm_adr_o[15:0]};
541
 
542
   // End of xpm_memory_tdpram_inst instantiation
543
 
544
delay3 #(1) udly1 (.clk(m_clk_i), .ce(1'b1), .i(vm_cyc_o), .o(m_req.cyc));
545
 
546
`ifdef INTERNAL_SYNC_GEN
547
wire hsync_i, vsync_i, blank_i;
548
 
549
VGASyncGen usg1
550
(
551
        .rst(rst_i),
552
        .clk(vclk),
553
        .eol(),
554
        .eof(),
555
        .hSync(hsync_o),
556
        .vSync(vsync_o),
557
        .hCtr(hctr_o),
558
        .vCtr(vctr_o),
559
  .blank(blank_o),
560
  .vblank(vblank),
561
  .vbl_int(),
562
  .border(border_o),
563
  .hTotal_i(hTotal),
564
  .vTotal_i(vTotal),
565
  .hSyncOn_i(hSyncOn),
566
  .hSyncOff_i(hSyncOff),
567
  .vSyncOn_i(vSyncOn),
568
  .vSyncOff_i(vSyncOff),
569
  .hBlankOn_i(hBlankOn),
570
  .hBlankOff_i(hBlankOff),
571
  .vBlankOn_i(vBlankOn),
572
  .vBlankOff_i(vBlankOff),
573
  .hBorderOn_i(hBorderOn),
574
  .hBorderOff_i(hBorderOff),
575
  .vBorderOn_i(vBorderOn),
576
  .vBorderOff_i(vBorderOff)
577
);
578
assign hsync_i = hsync_o;
579
assign vsync_i = vsync_o;
580
assign blank_i = blank_o;
581
assign vblank_o = vblank;
582
`endif
583
 
584
edge_det edcs1
585
(
586
        .rst(rst_i),
587
        .clk(s_clk_i),
588
        .ce(1'b1),
589
        .i(cs_reg),
590
        .pe(cs_edge),
591
        .ne(),
592
        .ee()
593
);
594
 
595
// Frame counter
596
//
597
VT163 #(6) ub1
598
(
599
        .clk(vclk),
600
        .clr_n(!rst_i),
601
        .ent(pe_vsync),
602
        .enp(1'b1),
603
        .ld_n(1'b1),
604
        .d(6'd0),
605
        .q(fctr_o),
606
        .rco()
607
);
608
 
609
always_ff @(posedge vclk)
610
if (rst_i)
611
        irq <= LOW;
612
else begin
613
        if (hctr_o==12'd02 && rastcmp==vctr_o)
614
                irq <= HIGH;
615
        else if (rst_irq|rst_irq2)
616
                irq <= LOW;
617
end
618
 
619
always_comb
620
        baseAddr = page ? bm_base_addr2 : bm_base_addr1;
621
 
622
// Color palette RAM for 8bpp modes
623
// 64x1024 A side, 32x2048 B side
624
// 3 cycle latency
625
fb_palram upal1 // Actually 1024x64
626
(
627
  .clka(s_clk_i),    // input wire clka
628
  .ena(cs & adri[13]),      // input wire ena
629
  .wea({8{we}}&sel),      // input wire [3 : 0] wea
630
  .addra(adri[12:3]),  // input wire [8 : 0] addra
631
  .dina(dat),                           // input wire [31 : 0] dina
632
  .douta(pal_wo),  // output wire [31 : 0] douta
633
  .clkb(vclk),    // input wire clkb
634
  .enb(1'b1),      // input wire enb
635
  .web(1'b0),      // input wire [3 : 0] web
636
  .addrb({pals,rgbo4[5:0]}),  // input wire [8 : 0] addrb
637
  .dinb(32'h0),    // input wire [31 : 0] dinb
638
  .doutb(pal_o)  // output wire [31 : 0] doutb
639
);
640
 
641
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
642
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
643
always_ff @(posedge s_clk_i)
644
if (rst_i) begin
645
        page <= 1'b0;
646
        pals <= 4'h0;
647
        hres <= 3'd1;
648
        vres <= 3'd1;
649
        windowWidth <= 12'd800;
650
        windowHeight <= 12'd600;
651
        onoff <= 1'b1;
652
        color_depth <= BPP16;
653
        color_depth2 <= BPP16;
654
        greyscale <= 1'b0;
655
        bm_base_addr1 <= BM_BASE_ADDR1;
656
        bm_base_addr2 <= BM_BASE_ADDR2;
657
        hrefdelay <= 16'hFF39;//16'd3964;//16'hFF99;//12'd103;
658
        vrefdelay <= 16'hFFEA;//16'hFFF3;12'd13;
659
        windowLeft <= 16'h0;
660
        windowTop <= 16'h0;
661
        windowWidth <= 16'd800;
662
        windowHeight <= 16'd600;
663
        bmpWidth <= 16'd800;
664
        bmpHeight <= 16'd600;
665
        map <= MAP;
666
        pcmd <= 2'b00;
667
        rstcmd1 <= 1'b0;
668
        rst_irq <= 1'b0;
669
        rastcmp <= 12'hFFF;
670
        oob_color <= 32'h00003C00;
671
        irq_msgadr <= IRQ_MSGADR;
672
        irq_msgdat <= IRQ_MSGDAT;
673
end
674
else begin
675
        color_depth2 <= color_depth;
676
        rstcmd1 <= rstcmd;
677
        rst_irq <= 1'b0;
678
  if (rstcmd & ~rstcmd1)
679
    pcmd <= 2'b00;
680
        if (cs_edge) begin
681
                if (we) begin
682
                        casez(adri[13:3])
683
                        REG_CTRL:
684
                                begin
685
                                        if (sel[0]) onoff <= dat[0];
686
                                        if (sel[1]) begin
687
                                        color_depth <= color_depth_t'(dat[9:8]);
688
                                        greyscale <= dat[12];
689
                                        end
690
                                        if (sel[2]) begin
691
                                        hres <= dat[18:16];
692
                                        vres <= dat[22:20];
693
                                        end
694
                                        if (sel[3]) begin
695
                                        page <= dat[24];
696
                                        pals <= dat[28:25];
697
                                        end
698
                                        if (|sel[7:6]) map <= dat[59:48];
699
                                end
700
                        REG_REFDELAY:
701
                                begin
702
                                        if (|sel[1:0])  hrefdelay <= dat[15:0];
703
                                        if (|sel[3:2])  vrefdelay <= dat[31:16];
704
                                end
705
                        REG_PAGE1ADDR:  bm_base_addr1 <= dat;
706
                        REG_PAGE2ADDR:  bm_base_addr2 <= dat;
707
                        REG_PXYZ:
708
                                begin
709
                                        if (|sel[1:0])  px <= dat[15:0];
710
                                        if (|sel[3:2])  py <= dat[31:16];
711
                                        if (|sel[  4])  pz <= dat[39:32];
712
                                end
713
                        REG_PCOLCMD:
714
                                begin
715
                                        if (sel[0]) pcmd <= dat[1:0];
716
                            if (sel[1]) raster_op <= dat[11:8];
717
                            if (|sel[7:2]) color <= dat[63:16];
718
                          end
719
                        REG_RASTCMP:
720
                                begin
721
                                        if (sel[0]) rastcmp[7:0] <= dat[7:0];
722
                                        if (sel[1]) rastcmp[11:8] <= dat[11:8];
723
                                        if (sel[7]) rst_irq <= dat[63];
724
                                end
725
                        REG_BMPSIZE:
726
                                begin
727
                                        if (|sel[1:0]) bmpWidth <= dat[15:0];
728
                                        if (|sel[5:4]) bmpHeight <= dat[47:32];
729
                                end
730
                        REG_OOB_COLOR:
731
                                begin
732
                                        if (|sel[3:0]) oob_color[31:0] <= dat[31:0];
733
                                end
734
                        REG_WINDOW:
735
                                begin
736
                                        if (|sel[1:0])  windowWidth <= dat[11:0];
737
                                        if (|sel[3:2])  windowHeight <= dat[27:16];
738
                                        if (|sel[5:4])  windowLeft <= dat[47:32];
739
                                        if (|sel[7:6])  windowTop <= dat[63:48];
740
                                end
741
                        REG_IRQ_MSGADR:
742
                                begin
743
                                        if (sel[0]) irq_msgadr <= dat[7:0];
744
                                        if (sel[1]) irq_msgadr <= dat[15:8];
745
                                        if (sel[2]) irq_msgadr <= dat[23:16];
746
                                        if (sel[3]) irq_msgadr <= dat[31:24];
747
                                        if (sel[4]) irq_msgadr <= dat[39:32];
748
                                        if (sel[5]) irq_msgadr <= dat[47:40];
749
                                        if (sel[6]) irq_msgadr <= dat[55:48];
750
                                        if (sel[7]) irq_msgadr <= dat[63:56];
751
                                end
752
                        REG_IRQ_MSGDAT:
753
                                begin
754
                                        if (sel[0]) irq_msgdat <= dat[7:0];
755
                                        if (sel[1]) irq_msgdat <= dat[15:8];
756
                                        if (sel[2]) irq_msgdat <= dat[23:16];
757
                                        if (sel[3]) irq_msgdat <= dat[31:24];
758
                                        if (sel[4]) irq_msgdat <= dat[39:32];
759
                                        if (sel[5]) irq_msgdat <= dat[47:40];
760
                                        if (sel[6]) irq_msgdat <= dat[55:48];
761
                                        if (sel[7]) irq_msgdat <= dat[63:56];
762
                                end
763
 
764
`ifdef INTERNAL_SYNC_GEN
765
                        REG_TOTAL:
766
                                begin
767
                                        if (!sgLock) begin
768
                                                if (|sel[1:0]) hTotal <= dat[11:0];
769
                                                if (|sel[3:2]) vTotal <= dat[27:16];
770
                                        end
771
                                        if (|sel[7:4]) begin
772
                                                if (dat[63:32]==32'hA1234567)
773
                                                        sgLock <= 1'b0;
774
                                                else if (dat[63:32]==32'h7654321A)
775
                                                        sgLock <= 1'b1;
776
                                        end
777
                                end
778
                        REG_SYNC_ONOFF:
779
                                if (!sgLock) begin
780
                                        if (|sel[1:0]) hSyncOff <= dat[11:0];
781
                                        if (|sel[3:2]) hSyncOn <= dat[27:16];
782
                                        if (|sel[5:4]) vSyncOff <= dat[43:32];
783
                                        if (|sel[7:6]) vSyncOn <= dat[59:48];
784
                                end
785
                        REG_BLANK_ONOFF:
786
                                if (!sgLock) begin
787
                                        if (|sel[1:0]) hBlankOff <= dat[11:0];
788
                                        if (|sel[3:2]) hBlankOn <= dat[27:16];
789
                                        if (|sel[5:4]) vBlankOff <= dat[43:32];
790
                                        if (|sel[7:6]) vBlankOn <= dat[59:48];
791
                                end
792
                        REG_BORDER_ONOFF:
793
                                begin
794
                                        if (|sel[1:0]) hBorderOff <= dat[11:0];
795
                                        if (|sel[3:2]) hBorderOn <= dat[27:16];
796
                                        if (|sel[5:4]) vBorderOff <= dat[43:32];
797
                                        if (|sel[7:6]) vBorderOn <= dat[59:48];
798
                                end
799
`endif
800
      default:  ;
801
                        endcase
802
                end
803
        end
804
        if (cs_reg) begin
805
                if (BUSWID==64)
806
                  casez(adri[13:3])
807
                  REG_CTRL:
808
                      begin
809
                          s_dat_o[0] <= onoff;
810
                          s_dat_o[11:8] <= color_depth2;
811
                          s_dat_o[12] <= greyscale;
812
                          s_dat_o[18:16] <= hres;
813
                          s_dat_o[22:20] <= vres;
814
                          s_dat_o[24] <= page;
815
                          s_dat_o[28:25] <= pals;
816
                          s_dat_o[47:32] <= bmpWidth;
817
                          s_dat_o[59:48] <= map;
818
                      end
819
                  REG_REFDELAY:         s_dat_o <= {32'h0,vrefdelay,hrefdelay};
820
                  REG_PAGE1ADDR:        s_dat_o <= bm_base_addr1;
821
                  REG_PAGE2ADDR:        s_dat_o <= bm_base_addr2;
822
                  REG_PXYZ:                 s_dat_o <= {20'h0,pz,py,px};
823
                  REG_PCOLCMD:    s_dat_o <= {color_o,12'd0,raster_op,14'd0,pcmd};
824
                  REG_OOB_COLOR:        s_dat_o <= {32'h0,oob_color};
825
                  REG_WINDOW:                   s_dat_o <= {windowTop,windowLeft,4'h0,windowHeight,4'h0,windowWidth};
826
                  REG_IRQ_MSGADR:       s_dat_o <= irq_msgadr;
827
                  REG_IRQ_MSGDAT:       s_dat_o <= irq_msgdat;
828
                  11'b1?_????_????_?:   s_dat_o <= pal_wo;
829
                  default:        s_dat_o <= 'd0;
830
                  endcase
831
                else
832
                  casez(adri[13:2])
833
                  {REG_CTRL,1'b0}:
834
                      begin
835
                          s_dat_o[0] <= onoff;
836
                          s_dat_o[11:8] <= color_depth2;
837
                          s_dat_o[12] <= greyscale;
838
                          s_dat_o[18:16] <= hres;
839
                          s_dat_o[22:20] <= vres;
840
                          s_dat_o[24] <= page;
841
                          s_dat_o[28:25] <= pals;
842
                      end
843
                  {REG_CTRL,1'b1}:
844
                      begin
845
                          s_dat_o[15: 0] <= bmpWidth;
846
                          s_dat_o[27:16] <= map;
847
                      end
848
                  {REG_REFDELAY,1'b0}:  s_dat_o <= {vrefdelay,hrefdelay};
849
                  {REG_PAGE1ADDR,1'b0}: s_dat_o <= bm_base_addr1;
850
                  {REG_PAGE2ADDR,1'b0}: s_dat_o <= bm_base_addr2;
851
                  {REG_PXYZ,1'b0}:                s_dat_o <= {py,px};
852
                  {REG_PXYZ,1'b1}:                s_dat_o <= {16'h0,pz};
853
                  {REG_PCOLCMD,1'b0}:   s_dat_o <= {12'd0,raster_op,14'd0,pcmd};
854
                  {REG_PCOLCMD,1'b1}:   s_dat_o <= color_o;
855
                  {REG_OOB_COLOR,1'b0}: s_dat_o <= oob_color;
856
                  {REG_WINDOW,1'b0}:            s_dat_o <= {4'h0,windowHeight,4'h0,windowWidth};
857
                  {REG_WINDOW,1'b1}:            s_dat_o <= {windowTop,windowLeft};
858
                  {REG_IRQ_MSGADR,1'b0}:        s_dat_o <= irq_msgadr[31:0];
859
                  {REG_IRQ_MSGADR,1'b1}:        s_dat_o <= irq_msgadr[63:32];
860
                  {REG_IRQ_MSGDAT,1'b0}:        s_dat_o <= irq_msgdat[31:0];
861
                  {REG_IRQ_MSGDAT,1'b1}:        s_dat_o <= irq_msgdat[63:32];
862
                  12'b1?_????_????_?0:  s_dat_o <= pal_wo;
863
                  default:        s_dat_o <= 'd0;
864
                  endcase
865
        end
866
        else if (cs_map)
867
                s_dat_o <= {40'h0,map_out};
868
        else if (cs_config)
869
                s_dat_o <= cfg_out;
870
        else
871
                s_dat_o <= 'h0;
872
end
873
 
874
//`ifdef USE_CLOCK_GATE
875
//BUFHCE ucb1
876
//(
877
//      .I(dot_clk_i),
878
//      .CE(onoff),
879
//      .O(vclk)
880
//);
881
//`else
882
assign vclk = dot_clk_i;
883
//`endif
884
 
885
 
886
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
887
// Horizontal and Vertical timing reference counters
888
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
889
 
890
reg lef;        // load even fifo
891
reg lof;        // load odd fifo
892
 
893
edge_det edh1
894
(
895
        .rst(rst_i),
896
        .clk(vclk),
897
        .ce(1'b1),
898
        .i(hsync_i),
899
        .pe(pe_hsync),
900
        .ne(),
901
        .ee()
902
);
903
 
904
edge_det edh2
905
(
906
        .rst(rst_i),
907
        .clk(m_clk_i),
908
        .ce(1'b1),
909
        .i(hsync_i),
910
        .pe(pe_hsync2),
911
        .ne(),
912
        .ee()
913
);
914
 
915
edge_det edv1
916
(
917
        .rst(rst_i),
918
        .clk(vclk),
919
        .ce(1'b1),
920
        .i(vsync_i),
921
        .pe(pe_vsync),
922
        .ne(),
923
        .ee()
924
);
925
 
926
wire [2:0] hc;
927
wire [2:0] vc;
928
 
929
pixelCounter upxc1
930
(
931
        .rst(pe_hsync),
932
        .clk(vclk),
933
        .ce(1'b1),
934
        .res(hres),
935
        .d(hrefdelay),
936
        .q(pixelCol),
937
        .mq(hc)
938
);
939
 
940
pixelCounter upxr1
941
(
942
        .rst(pe_vsync),
943
        .clk(vclk),
944
        .ce(pe_hsync),
945
        .res(vres),
946
        .d(vrefdelay),
947
        .q(pixelRow),
948
        .mq(vc)
949
);
950
 
951
always_comb
952
        lef = ~pixelRow[0];
953
always_comb
954
        lof =  pixelRow[0];
955
 
956
always_ff @(posedge vclk)
957
        xal_o <= vc != 4'd1;
958
 
959
// Bits per pixel minus one.
960
reg [4:0] bpp;
961
always_comb
962
case(color_depth2)
963
BPP8:   bpp = 7;
964
BPP16:  bpp = 15;
965
BPP24:  bpp = 23;
966
BPP32:  bpp = 31;
967
default:        bpp = 15;
968
endcase
969
 
970
reg [5:0] shifts;
971
always_comb
972
case(MDW)
973
128:
974
        case(color_depth2)
975
        BPP8:   shifts = 6'd16;
976
        BPP16:  shifts = 6'd8;
977
        BPP24:  shifts = 6'd5;
978
        BPP32:  shifts = 6'd4;
979
        default:  shifts = 6'd8;
980
        endcase
981
64:
982
        case(color_depth2)
983
        BPP8:   shifts = 6'd8;
984
        BPP16:  shifts = 6'd4;
985
        BPP24:  shifts = 6'd2;
986
        BPP32:  shifts = 6'd2;
987
        default:  shifts = 6'd4;
988
        endcase
989
32:
990
        case(color_depth2)
991
        BPP8:   shifts = 6'd4;
992
        BPP16:  shifts = 6'd2;
993
        BPP24:  shifts = 6'd1;
994
        BPP32:  shifts = 6'd1;
995
        default:  shifts = 6'd2;
996
        endcase
997
default:
998
        begin
999
        $display("rfFramBuffer_fta64: Bad master bus width");
1000
        $finish;
1001
        end
1002
endcase
1003
 
1004
wire vFetch = !vblank;//pixelRow < windowHeight;
1005
reg fifo_rrst;
1006
reg fifo_wrst;
1007
always_comb fifo_rrst = pixelCol==16'hFFFF;
1008
always_comb fifo_wrst = pe_hsync2 && vc==4'd1;
1009
 
1010
wire[31:0] grAddr,xyAddr;
1011
reg [11:0] fetchCol;
1012
localparam CMS = MDW==128 ? 6 : MDW==64 ? 5 : 4;
1013
wire [CMS:0] mb,me,ce;
1014
reg [MDW-1:0] mem_strip;
1015
wire [MDW-1:0] mem_strip_o;
1016
 
1017
// Compute fetch address
1018
gfx_calc_address #(.SW(MDW)) u1
1019
(
1020
  .clk(m_clk_i),
1021
        .base_address_i(baseAddr),
1022
        .color_depth_i(color_depth2),
1023
        .bmp_width_i(bmpWidth),
1024
        .x_coord_i(windowLeft),
1025
        .y_coord_i(windowTop + pixelRow),
1026
        .address_o(grAddr),
1027
        .mb_o(),
1028
        .me_o(),
1029
        .ce_o()
1030
);
1031
 
1032
// Compute address for get/set pixel
1033
gfx_calc_address #(.SW(MDW)) u2
1034
(
1035
  .clk(m_clk_i),
1036
        .base_address_i(baseAddr),
1037
        .color_depth_i(color_depth2),
1038
        .bmp_width_i(bmpWidth),
1039
        .x_coord_i(px),
1040
        .y_coord_i(py),
1041
        .address_o(xyAddr),
1042
        .mb_o(mb),
1043
        .me_o(me),
1044
        .ce_o(ce)
1045
);
1046
 
1047
always_ff @(posedge m_clk_i)
1048
if (pe_hsync2)
1049
  mapctr <= 12'hFFE;
1050
else begin
1051
  if (mapctr == map)
1052
    mapctr <= 12'd0;
1053
  else
1054
    mapctr <= mapctr + 12'd1;
1055
end
1056
wire memreq = mapctr==12'd0 && vc==4'd1;
1057
 
1058
// The following bypasses loading the fifo when all the pixels from a scanline
1059
// are buffered in the fifo and the pixel row doesn't change. Since the fifo
1060
// pointers are reset at the beginning of a scanline, the fifo can be used like
1061
// a cache.
1062
wire blankEdge;
1063
edge_det ed2(.rst(rst_i), .clk(m_clk_i), .ce(1'b1), .i(blank_i), .pe(blankEdge), .ne(), .ee() );
1064
reg do_loads;
1065
reg load_fifo = 1'b0;
1066
always_ff @(posedge m_clk_i)
1067
        //load_fifo <= fifo_cnt < 10'd1000 && vFetch && onoff && xonoff && !m_cyc_o && do_loads;
1068
        load_fifo <= /*fifo_cnt < 8'd224 &&*/ vFetch && onoff && xonoff_i && (fetchCol < windowWidth) && memreq;
1069
// The following table indicates the number of pixel that will fit into the
1070
// video fifo.
1071
reg [11:0] hCmp;
1072
always_comb
1073
case(color_depth2)
1074
BPP8:   hCmp = 12'd2048;
1075
BPP16:  hCmp = 12'd1024;
1076
BPP24:  hCmp = 12'd640;
1077
BPP32:  hCmp = 12'd512;
1078
default:        hCmp = 12'd1024;
1079
endcase
1080
/*
1081
always @(posedge m_clk_i)
1082
        // if windowWidth > hCmp we always load because the fifo isn't large enough to act as a cache.
1083
        if (!(windowWidth < hCmp))
1084
                do_loads <= 1'b1;
1085
        // otherwise load the fifo only when the row changes to conserve memory bandwidth
1086
        else if (vc==4'd1)//pixelRow != opixelRow)
1087
                do_loads <= 1'b1;
1088
        else if (blankEdge)
1089
                do_loads <= 1'b0;
1090
*/
1091
always_comb m_req.bte = fta_bus_pkg::LINEAR;
1092
always_comb m_req.cti = fta_bus_pkg::CLASSIC;
1093
always_comb m_req.blen = 6'd63;
1094
always_comb m_req.stb = m_req.cyc;
1095
always_comb m_req.cid = 'd0;
1096
always_comb m_req.tid = 15'h1234;
1097
 
1098
reg [31:0] adr;
1099
typedef enum logic [3:0] {
1100
        IDLE = 4'd0,
1101
        LOADCOLOR = 4'd2,
1102
        LOADSTRIP = 4'd3,
1103
        STORESTRIP = 4'd4,
1104
        ACKSTRIP = 4'd5,
1105
        WAITLOAD = 4'd6,
1106
        WAITRST = 4'd7,
1107
        ICOLOR1 = 4'd8,
1108
        ICOLOR2 = 4'd9,
1109
        ICOLOR3 = 4'd10,
1110
        ICOLOR4 = 4'd11,
1111
        LOAD_OOB = 4'd12
1112
} state_t;
1113
state_t state;
1114
reg [127:0] icolor1;
1115
 
1116
function rastop;
1117
input [3:0] op;
1118
input a;
1119
input b;
1120
case(op)
1121
OPBLACK: rastop = 1'b0;
1122
OPCOPY:  rastop = b;
1123
OPINV:   rastop = ~a;
1124
OPAND:   rastop = a & b;
1125
OPOR:    rastop = a | b;
1126
OPXOR:   rastop = a ^ b;
1127
OPANDN:  rastop = a & ~b;
1128
OPNAND:  rastop = ~(a & b);
1129
OPNOR:   rastop = ~(a | b);
1130
OPXNOR:  rastop = ~(a ^ b);
1131
OPORN:   rastop = a | ~b;
1132
OPWHITE: rastop = 1'b1;
1133
default:        rastop = 1'b0;
1134
endcase
1135
endfunction
1136
 
1137
always_ff @(posedge m_clk_i)
1138
        if (fifo_wrst)
1139
                adr <= grAddr;
1140
  else begin
1141
    if ((state==WAITLOAD && (m_resp.ack|tocnt[10])) || state==LOAD_OOB)
1142
        case(MDW)
1143
        32:             adr <= adr + 32'd4;
1144
        64:             adr <= adr + 32'd8;
1145
        default:        adr <= adr + 32'd16;
1146
        endcase
1147
  end
1148
 
1149
always_ff @(posedge m_clk_i)
1150
        if (fifo_wrst)
1151
                fetchCol <= 12'd0;
1152
  else begin
1153
    if ((state==WAITLOAD && (m_resp.ack|tocnt[10])) || state==LOAD_OOB)
1154
      fetchCol <= fetchCol + shifts;
1155
  end
1156
 
1157
// Check for legal (positive) coordinates
1158
// Illegal coordinates result in a red display
1159
wire [15:0] xcol = fetchCol;
1160
reg legal_x, legal_y;
1161
always_comb legal_x = ~&xcol[15:12] && xcol < bmpWidth;
1162
always_comb legal_y = ~&pixelRow[15:12] && pixelRow < bmpHeight;
1163
 
1164
reg modd;
1165
always_comb
1166
        case(MDW)
1167
        32:     modd <= m_req.padr[5:2]==4'hF;
1168
        64:     modd <= m_req.padr[5:3]==3'h7;
1169
        default:        modd <= m_req.padr[5:4]==2'h3;
1170
        endcase
1171
 
1172
always_ff @(posedge m_clk_i)
1173
if (rst_i)
1174
        tocnt <= 'd0;
1175
else begin
1176
        if (m_req.cyc)
1177
                tocnt <= tocnt + 2'd1;
1178
        else
1179
                tocnt <= 'd0;
1180
end
1181
 
1182
always_ff @(posedge m_clk_i, posedge rst_i)
1183
if (rst_i) begin
1184
        vm_cyc_o <= LOW;
1185
        m_req.we <= LOW;
1186
        m_req.sel <= 'd0;
1187
        vm_adr_o <= 'd0;
1188
  rstcmd <= 1'b0;
1189
  state <= IDLE;
1190
  rst_irq2 <= 1'b0;
1191
end
1192
else begin
1193
  wb_nack();
1194
  rst_irq2 <= 1'b0;
1195
        if (fifo_wrst)
1196
                m_fst_o <= HIGH;
1197
        case(state)
1198
  WAITRST:
1199
    if (pcmd==2'b00 && ~m_resp.ack) begin
1200
      rstcmd <= 1'b0;
1201
      state <= IDLE;
1202
    end
1203
    else
1204
      rstcmd <= 1'b1;
1205
  IDLE:
1206
        if (load_fifo && !(legal_x && legal_y))
1207
                        state <= LOAD_OOB;
1208
    else if (load_fifo & ~m_resp.ack) begin
1209
      vm_cyc_o <= HIGH;
1210
      vm_adr_o <= adr;
1211
      m_req.sel <= 16'hFFFF;
1212
      state <= WAITLOAD;
1213
    end
1214
    // Send an IRQ message if needed.
1215
    else if (irq & ~m_resp.ack & MSIX) begin
1216
        vm_cyc_o <= HIGH;
1217
        vm_adr_o <= irq_msgadr;
1218
        m_req.we <= HIGH;
1219
        m_req.sel <= irq_msgadr[3] ? 16'hFF00 : 16'h00FF;
1220
        m_req.data1 <= {2{irq_msgdat}};
1221
        rst_irq2 <= 1'b1;
1222
    end
1223
    // The adr_o[5:3]==3'b111 causes the controller to wait until all eight
1224
    // 64 bit strips from the memory controller have been processed. Otherwise
1225
    // there would be cache thrashing in the memory controller and the memory
1226
    // bandwidth available would be greatly reduced. However fetches are also
1227
    // allowed when loads are not active or all strips for the current scan-
1228
    // line have been fetched.
1229
    else if (pcmd!=2'b00 && (modd || !(vFetch && onoff && xonoff_i && fetchCol < windowWidth))) begin
1230
      vm_cyc_o <= HIGH;
1231
      vm_adr_o <= xyAddr;
1232
      m_req.sel <= 16'hFFFF;
1233
      state <= LOADSTRIP;
1234
    end
1235
  LOADSTRIP:
1236
    if (m_resp.ack|tocnt[10]) begin
1237
      wb_nack();
1238
      mem_strip <= m_resp.dat;
1239
      icolor1 <= {96'b0,color} << mb;
1240
      rstcmd <= 1'b1;
1241
      if (pcmd==2'b01)
1242
        state <= ICOLOR3;
1243
      else if (pcmd==2'b10)
1244
        state <= ICOLOR2;
1245
      else begin
1246
        state <= WAITRST;
1247
      end
1248
    end
1249
  // Registered inline mem2color
1250
  ICOLOR3:
1251
    begin
1252
      color_o <= mem_strip >> mb;
1253
      state <= ICOLOR4;
1254
    end
1255
  ICOLOR4:
1256
    begin
1257
      for (n = 0; n < 32; n = n + 1)
1258
        color_o[n] <= (n <= bpp) ? color_o[n] : 1'b0;
1259
      state <= pcmd == 2'b0 ? (~m_resp.ack ? IDLE : WAITRST) : WAITRST;
1260
      if (pcmd==2'b00)
1261
        rstcmd <= 1'b0;
1262
    end
1263
  // Registered inline color2mem
1264
  ICOLOR2:
1265
    begin
1266
      for (n = 0; n < MDW; n = n + 1)
1267
        m_req.data1[n] <= (n >= mb && n <= me)
1268
                ? ((n <= ce) ?  rastop(raster_op, mem_strip[n], icolor1[n]) : icolor1[n])
1269
                : mem_strip[n];
1270
      state <= STORESTRIP;
1271
    end
1272
  STORESTRIP:
1273
    if (~m_resp.ack) begin
1274
      vm_cyc_o <= HIGH;
1275
      m_req.we <= HIGH;
1276
      m_req.sel <= 16'hFFFF;
1277
      vm_adr_o <= xyAddr;
1278
      state <= ACKSTRIP;
1279
    end
1280
  ACKSTRIP:
1281
    if (m_resp.ack|tocnt[10]) begin
1282
      wb_nack();
1283
      state <= pcmd == 2'b0 ? IDLE : WAITRST;
1284
      if (pcmd==2'b00)
1285
        rstcmd <= 1'b0;
1286
    end
1287
  WAITLOAD:
1288
    if (m_resp.ack|tocnt[10]) begin
1289
      wb_nack();
1290
      state <= IDLE;
1291
    end
1292
  LOAD_OOB:
1293
        state <= IDLE;
1294
  default:      state <= IDLE;
1295
  endcase
1296
end
1297
 
1298
task wb_nack;
1299
begin
1300
        m_fst_o <= LOW;
1301
        vm_cyc_o <= LOW;
1302
        m_req.we <= LOW;
1303
        m_req.sel <= 16'h0000;
1304
end
1305
endtask
1306
 
1307
reg [31:0] rgbo2,rgbo4;
1308
reg [MDW-1:0] rgbo3;
1309
always_ff @(posedge vclk)
1310
case(color_depth2)
1311
BPP8:   rgbo4 <= {24'h0,rgbo3[7:0]};            // feeds into palette
1312
BPP16:  rgbo4 <= {rgbo3[15:10],5'b0,rgbo3[9:5],5'b0,rgbo3[4:0],5'b0};
1313
BPP24:  rgbo4 <= {rgbo3[23:16],2'b0,rgbo3[15:8],2'b0,rgbo3[7:0],2'b0};
1314
BPP32:  rgbo4 <= {rgbo3[29:20],rgbo3[19:10],rgbo3[9:0]};
1315
default:        rgbo4 <= {rgbo3[15:10],5'b0,rgbo3[9:5],5'b0,rgbo3[4:0],5'b0};
1316
endcase
1317
 
1318
reg rd_fifo,rd_fifo1,rd_fifo2;
1319
/*
1320
reg de;
1321
always_ff @(posedge vclk)
1322
        if (rd_fifo1)
1323
                de <= ~blank_i;
1324
*/
1325
 
1326
always_ff @(posedge vclk)
1327
        if (onoff && xonoff_i && !blank_i) begin
1328
                if (color_depth2==BPP8) begin
1329
                        if (!greyscale)
1330
                                zrgb <= pal_o;
1331
                        else
1332
                                zrgb <= {pal_o[31:30],pal_o[9:0],pal_o[9:0],pal_o[9:0]};
1333
                end
1334
                else
1335
                        zrgb <= rgbo4;
1336
        end
1337
        else
1338
                zrgb <= 32'h00000000;
1339
always_ff @(posedge vclk)
1340
        if (zrgb==trans_color)
1341
                rgb_o <= rgb_i;
1342
        else
1343
                rgb_o <= zrgb;
1344
 
1345
// Before the hrefdelay expires, pixelCol will be negative, which is greater
1346
// than windowWidth as the value is unsigned. That means that fifo reading is
1347
// active only during the display area 0 to windowWidth.
1348
reg shift1;
1349
always_comb shift1 = hc==hres;
1350
reg [5:0] shift_cnt;
1351
always_ff @(posedge vclk)
1352
if (pe_hsync)
1353
        shift_cnt <= 5'd1;
1354
else begin
1355
        if (shift1) begin
1356
                if (pixelCol==16'hFFFF)
1357
                        shift_cnt <= shifts;
1358
                else if (!pixelCol[15]) begin
1359
                        shift_cnt <= shift_cnt + 5'd1;
1360
                        if (shift_cnt==shifts)
1361
                                shift_cnt <= 5'd1;
1362
                end
1363
                else
1364
                        shift_cnt <= 5'd1;
1365
        end
1366
end
1367
 
1368
reg next_strip;
1369
always_comb next_strip = (shift_cnt==shifts) && (hc==hres);
1370
 
1371
wire vrd;
1372
reg shift,shift2;
1373
always_ff @(posedge vclk) shift2 <= shift1;
1374
always_ff @(posedge vclk) shift <= shift2;
1375
always_ff @(posedge vclk) rd_fifo2 <= next_strip;
1376
always_ff @(posedge vclk) rd_fifo <= rd_fifo2;
1377
always_ff @(posedge vclk)
1378
        if (rd_fifo)
1379
                rgbo3 <= lef ? rgbo1o : rgbo1e;
1380
        else if (shift) begin
1381
                case(color_depth2)
1382
                BPP8:   rgbo3 <= {8'h0,rgbo3[MDW-1:8]};
1383
                BPP16:  rgbo3 <= {16'h0,rgbo3[MDW-1:16]};
1384
                BPP24:  rgbo3 <= {24'h0,rgbo3[MDW-1:24]};
1385
                BPP32:  rgbo3 <= {32'h0,rgbo3[MDW-1:32]};
1386
                default: rgbo3 <= {16'h0,rgbo3[MDW-1:16]};
1387
                endcase
1388
        end
1389
 
1390
 
1391
/* Debugging
1392
wire [127:0] dat;
1393
assign dat[11:0] = pixelRow[0] ? 12'hEA4 : 12'h000;
1394
assign dat[23:12] = pixelRow[1] ? 12'hEA4 : 12'h000;
1395
assign dat[35:24] = pixelRow[2] ? 12'hEA4 : 12'h000;
1396
assign dat[47:36] = pixelRow[3] ? 12'hEA4 : 12'h000;
1397
assign dat[59:48] = pixelRow[4] ? 12'hEA4 : 12'h000;
1398
assign dat[71:60] = pixelRow[5] ? 12'hEA4 : 12'h000;
1399
assign dat[83:72] = pixelRow[6] ? 12'hEA4 : 12'h000;
1400
assign dat[95:84] = pixelRow[7] ? 12'hEA4 : 12'h000;
1401
assign dat[107:96] = pixelRow[8] ? 12'hEA4 : 12'h000;
1402
assign dat[119:108] = pixelRow[9] ? 12'hEA4 : 12'h000;
1403
*/
1404
 
1405
reg [MDW-1:0] oob_dat;
1406
always_comb
1407
case(color_depth2)
1408
BPP8:   oob_dat <= {MDW/8{oob_color[7:0]}};
1409
BPP16:  oob_dat <= {MDW/16{oob_color[15:0]}};
1410
BPP24:  oob_dat <= {MDW/24{oob_color[23:0]}};
1411
BPP32:  oob_dat <= {MDW/32{oob_color[31:0]}};
1412
default:        oob_dat <= {MDW/16{oob_color[15:0]}};
1413
endcase
1414
 
1415
rfVideoFifo #(MDW) uf1
1416
(
1417
        .wrst(fifo_wrst),
1418
        .wclk(m_clk_i),
1419
        .wr((((m_resp.ack|tocnt[10]) && state==WAITLOAD) || state==LOAD_OOB) && lef),
1420
        .di((state==LOAD_OOB) ? oob_dat : m_resp.dat),
1421
        .rrst(fifo_rrst),
1422
        .rclk(vclk),
1423
        .rd(rd_fifo & lof),
1424
        .dout(rgbo1e),
1425
        .cnt()
1426
);
1427
 
1428
rfVideoFifo #(MDW) uf2
1429
(
1430
        .wrst(fifo_wrst),
1431
        .wclk(m_clk_i),
1432
        .wr((((m_resp.ack|tocnt[10]) && state==WAITLOAD) || state==LOAD_OOB) && lof),
1433
        .di((state==LOAD_OOB) ? oob_dat : m_resp.dat),
1434
        .rrst(fifo_rrst),
1435
        .rclk(vclk),
1436
        .rd(rd_fifo & lef),
1437
        .dout(rgbo1o),
1438
        .cnt()
1439
);
1440
 
1441
endmodule
1442
 
1443
// Horizontal or vertical pixel counter.
1444
// If the count is negative, step by one keeps the meaning of the refdelay value
1445
// consistent between different resolutions.
1446
 
1447
module pixelCounter(rst, clk, ce, res, d, q, mq);
1448
input rst;
1449
input clk;
1450
input ce;
1451
input [2:0] res;
1452
input [15:0] d;
1453
output reg [15:0] q;
1454
output reg [2:0] mq;            // modulo count
1455
 
1456
always_ff @(posedge clk)
1457
if (rst) begin
1458
        mq <= 3'd1;
1459
        q <= d;
1460
end
1461
else begin
1462
        if (ce) begin
1463
                if (&q[15:12]) begin
1464
                        q <= q + 16'd1;
1465
                        mq <= 3'd1;
1466
                end
1467
                else if (mq==res) begin
1468
                        mq <= 3'd1;
1469
                        q <= q + 16'd1;
1470
                end
1471
                else
1472
                        mq <= mq + 3'd1;
1473
        end
1474
end
1475
 
1476
endmodule

powered by: WebSVN 2.1.0

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