diff options
author | H. Peter Anvin <hpa@zytor.com> | 2016-10-31 19:58:24 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2016-10-31 20:01:17 -0700 |
commit | c1d00c83383834613ec98b2af435a81ac9e673d5 (patch) | |
tree | 92ec48a304ac89b2133d8788b7ffc45babd099fb /display.v | |
parent | 03edc2bbe9e27949d9d8ba336d5eb71fadc00a3f (diff) | |
download | abc80-c1d00c83383834613ec98b2af435a81ac9e673d5.tar.gz abc80-c1d00c83383834613ec98b2af435a81ac9e673d5.tar.xz abc80-c1d00c83383834613ec98b2af435a81ac9e673d5.zip |
WIP: adjust SRAM timing to be able to share with another device
Infrastructure for changing the SRAM timing to add another shared
device (intended to be the Neopixel driver.) This means upping the
SRAM state machine clock to 200 MHz; move video_clk to pll2 to be able
to generate that output. It actually gets closer to proper VGA
timing, but at the expense of needing a synchronizing FIFO for the fg
unit.
This also clears a lot of timing warnings.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'display.v')
-rw-r--r-- | display.v | 50 |
1 files changed, 28 insertions, 22 deletions
@@ -1,12 +1,11 @@ module display ( - input clk, // 18.75 MHz + input clk, // 18.78 MHz input width, input reverse, input noblink, input testpattern, input reveal, - output reg [10:0] a, input [7:0] d, output [10:0] ga, @@ -19,16 +18,15 @@ module display ( output hsync, input [7:0] fg_ctl, - input [7:0] fg_data, + input [1:0] fg_data, output fg_ack, - output fg_xrst, - output fg_yrst + output fg_rst ); // We use the standard VGA 640x480 monitor timings mode, htime = 31.77 // us (31.47 kHz), vtime = 16.68 ms (60 Hz) The standard VGA uses a -// pixel clock of 25.175 MHz, we use 18.75 MHz, which is 25*3/4 for -// 480 horizontal pixels; the error is about 0.8%, which is far, far +// pixel clock of 25.175 MHz, we use 18.783 MHz, which is 25*3/4 for +// 480 horizontal pixels; the error is about 0.6%, which is far, far // less than the margin of error in real systems. // // This gives us the following timings: @@ -74,6 +72,8 @@ module display ( parameter hsync_minus = 1'b1; // -hsync parameter vsync_minus = 1'b1; // -vsync + wire v_width; // Synchronized width + reg hsync_q; // Horizontal sync active reg vsync_q; // Vertical sync active @@ -97,8 +97,9 @@ module display ( reg prefetch; // True for the prefetch character position // Fine Graphics control + wire [7:0] v_fgctl; // Synchronized version of fg_ctl reg [7:0] fgctl_q; // Latched version of fg_ctl - reg [7:0] fgpixels; // One byte of fg pixels + reg [1:0] fgpixels; // One fg pixel from FIFO // Block graphics data reg [5:0] block_rgb; // Current block graphics pixel @@ -137,10 +138,18 @@ module display ( wire do_flsh = wasdble ? wasflsh : isflsh; wire do_hide = wasdble ? washide : ishide; + // Synchronize width input + synchronize + width_sync (.reset(1'b0), .clk(clk), .d(width), .q(v_width)); + + // Synchronize fg_ctl input + synchronize #(.width(8)) + fg_ctl_sync (.reset(1'b0), .clk(clk), .d(fg_ctl), .q(v_fgctl)); + // Should we advance the character pixel? // We need to always advance at full speed during prefetch, or // we would have to start the prefetch earlier in 40-character mode. - wire advance = width | x[0] | prefetch; + wire advance = v_width | x[0] | prefetch; // Address mapping for 40 and 80 characters assign a80[3:0] = xchr[3:0]; @@ -168,7 +177,7 @@ module display ( // Note: We read the current char between pixels 0 and 1, // and the char above between pixels 2 and 3; hence the use of xpxl[1]. always @(*) - case ( { width, xpxl[1] } ) + case ( { v_width, xpxl[1] } ) 2'b00: a = a40; 2'b01: @@ -177,7 +186,7 @@ module display ( a = a80; 2'b11: a = a80u; - endcase // case( { width, xchr[1] } ) + endcase // case( { v_width, xchr[1] } ) // Block graphics address mapping assign bga[3:0] = block_x[3:0]; @@ -196,8 +205,9 @@ module display ( assign xvideo = ( x < x_blank ); assign yvideo = ( y < y_blank ); - assign hsync = hsync_q ^ hsync_minus; - assign vsync = vsync_q ^ vsync_minus; + assign hsync = hsync_q ^ hsync_minus; + assign vsync = vsync_q ^ vsync_minus; + assign fg_rst = vsync; // Flashing wire flash_on = scan_counter[4]; @@ -210,24 +220,20 @@ module display ( // // Fine graphics // - assign fg_ack = xvideo & yvideo & (x[2:0] == 3'b000); - assign fg_xrst = yvideo & hsync_q; - assign fg_yrst = vsync_q; + assign fg_ack = xvideo & yvideo & ~x[0]; wire [3:0] fg_argb; always @(posedge clk) if ( ~yvideo ) // Only change mode during vertical blank - fgctl_q <= fg_ctl; + fgctl_q <= v_fgctl; always @(posedge clk) - if (x[2:0] == 3'b100) + if (~x[0]) fgpixels <= fg_data; - else if (~x[0]) - fgpixels <= { fgpixels[5:0], 2'bxx }; fgcolrom fgcolrom ( - .address ( { fgctl_q[6:0], fgpixels[7:6] } ), + .address ( { fgctl_q[6:0], fgpixels } ), .clock ( clk ), .q ( fg_argb ) ); @@ -262,7 +268,7 @@ module display ( if ( advance ) pixrow <= { pixrow[4:0], pixrow[5] }; - // This code is run 6 times per character; regardless of width + // This code is run 6 times per character; regardless of v_width if ( advance ) begin case ( xpxl ) |