aboutsummaryrefslogtreecommitdiffstats
path: root/display.v
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2016-10-31 19:58:24 -0700
committerH. Peter Anvin <hpa@zytor.com>2016-10-31 20:01:17 -0700
commitc1d00c83383834613ec98b2af435a81ac9e673d5 (patch)
tree92ec48a304ac89b2133d8788b7ffc45babd099fb /display.v
parent03edc2bbe9e27949d9d8ba336d5eb71fadc00a3f (diff)
downloadabc80-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.v50
1 files changed, 28 insertions, 22 deletions
diff --git a/display.v b/display.v
index 68c5be0..8e539d4 100644
--- a/display.v
+++ b/display.v
@@ -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 )