gateware

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit df5a81c80e88fe49c3d7bada90c93c9d5f14fd2c
parent 04fd1dc2ee9722f0bb38817b560ae5286049e324
Author: Brian Swetland <swetland@frotz.net>
Date:   Wed, 21 Nov 2018 19:20:23 -0800

vga: rework most of this

Less embarrassing now and works with Yosys+ArachnePNR as well as
Verilator and iceCube2+Synplify.  Vivado is not pleased.

Diffstat:
Mhdl/vga/chardata.v | 190+++++++++++++++++++++++++++----------------------------------------------------
Mhdl/vga/vga.v | 58++++++++++++++++++++++++----------------------------------
Mhdl/vga/vga40x30x2.v | 2++
Mhdl/vga/videoram.v | 3++-
4 files changed, 92 insertions(+), 161 deletions(-)

diff --git a/hdl/vga/chardata.v b/hdl/vga/chardata.v @@ -1,11 +1,11 @@ -// Copyright 2012, Brian Swetland +// Copyright 2018, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. // -// Pixel Data Reader / Character Data Reader +// Character Display Engine // -// assert newline and provide line address to start linefetch -// character data will be provided on cdata two clocks later -// -// assert next to advance: character data will be provided two clocks later +// newline strobes on the first pixel of a new line +// advance strobes on each visible pixel of a new line +// line provides the visible line count 0..239 // // vram_addr/vram_data: connect to sync sram @@ -16,102 +16,12 @@ module pixeldata( input newline, input advance, input [7:0] line, - output [11:0] pixel, - input [7:0] vram_data, output [10:0] vram_addr ); -wire [7:0] new_cdata; -reg next; - -chardata chardata( - .clk(clk), - .newline(newline), - .line(line), - .next(next), - .cdata_o(new_cdata), - .vram_data(vram_data), - .vram_addr_o(vram_addr) - ); - -reg [7:0] cdata, next_cdata; -reg [3:0] bitcount, next_bitcount; -reg [1:0] state = 2'h0, next_state; - -always @(*) begin - next_bitcount = bitcount; - next_cdata = cdata; - next = 1'b0; - - /* s0 machine is used to wait until the first cdata - * is ready after a newline signal, load that cdata, - * then enter the shift-out (s0=0) mode - */ - case (state) - 2'h3: next_state = 2'h2; - 2'h2: next_state = 2'h1; - 2'h1: begin - next_state = 2'h0; - next_cdata = new_cdata; - end - 2'h0: begin - next_state = 2'h0; - if (advance) - next_bitcount = bitcount - 4'd1; - if (bitcount == 4'h4) - next = 1'b1; - if (bitcount == 4'h0) - next_cdata = new_cdata; - end - endcase - - if (newline) begin - next_state = 2'h3; - next_bitcount = 4'hF; - end - -end - -assign pixel = (cdata[bitcount[3:1]] ? 12'hFFF : 12'h00F); - -always @(posedge clk) begin - bitcount <= next_bitcount; - state <= next_state; - cdata <= next_cdata; -end - -endmodule - - -module chardata( - input clk, - input newline, - input next, - input [7:0] line, - output [7:0] cdata_o, - - input [7:0] vram_data, - output [10:0] vram_addr_o - ); - -`define SWAIT 2'h0 -`define SLOAD 2'h1 -`define SLATCH 2'h2 - reg [7:0] pattern_rom [0:1023]; -reg [2:0] pline, next_pline; - -reg [1:0] state = `SWAIT, next_state; -reg [10:0] next_addr; -reg [7:0] next_cdata; - -reg [7:0] cdata; -reg [10:0] vram_addr; - -assign cdata_o = cdata; -assign vram_addr_o = vram_addr; `ifdef HEX_PATHS initial $readmemh("hdl/vga/prom.txt", pattern_rom); @@ -119,42 +29,70 @@ initial $readmemh("hdl/vga/prom.txt", pattern_rom); initial $readmemh("prom.txt", pattern_rom); `endif +reg next_load; +reg [5:0] next_xpos; +reg [3:0] next_ppos; +reg [15:0] next_pattern; + +reg load = 1'b0; +reg [5:0] xpos = 6'b0; +reg [3:0] ppos = 4'b0; +reg [15:0] pattern = 16'b0; + +// generate vram address by using the high bits of the display +// line and the local xpos character counter +assign vram_addr = { line[7:3], next_xpos }; + +// generate pattern rom address by using the character id +// fetched from vram as the high bits and the low bits of +// the display line to further index into the correct pattern +wire [9:0] pattern_addr = { vram_data[6:0], line[2:0] }; + +wire [7:0] cdata = pattern_rom[pattern_addr]; + +// the high bit of the pattern shift register is used to +// select the FG or BG color and feed out to the vga core +assign pixel = pattern[15] ? 12'hFFF : 12'h00F; + always_comb begin - next_state = state; - next_addr = vram_addr; - next_cdata = cdata; - next_pline = pline; + next_xpos = xpos; + next_ppos = ppos; + next_pattern = pattern; + next_load = 1'b0; + if (newline) begin - next_state = `SLOAD; - next_addr = { line[7:3], 6'b0 }; - next_pline = line[2:0]; - end -`ifndef YOSYS - else -`endif - case (state) - `SWAIT: if (next) begin - next_state = `SLOAD; - end - `SLOAD: begin - next_state = `SLATCH; + next_load = 1'b1; + next_xpos = 6'b0; + next_ppos = 4'b0; + end else if (advance) begin + next_ppos = ppos + 4'h1; + if (ppos == 4'hF) begin + next_load = 1'b1; + next_xpos = xpos + 6'b1; end - `SLATCH: begin - next_state = `SWAIT; - next_addr = vram_addr + 11'd1; - next_cdata = pattern_rom[{vram_data[6:0], pline}]; - end - default: begin - next_state = `SWAIT; end - endcase + + // pattern shift register + if (load) begin + // 8bit wide character pattern line is expanded + // into the 16bit pattern shift register + next_pattern = { + cdata[7], cdata[7], cdata[6], cdata[6], + cdata[5], cdata[5], cdata[4], cdata[4], + cdata[3], cdata[3], cdata[2], cdata[2], + cdata[1], cdata[1], cdata[0], cdata[0] + }; + end else if (advance) begin + next_pattern = { pattern[14:0], 1'b0 }; + end + end always_ff @(posedge clk) begin - state <= next_state; - vram_addr <= next_addr; - cdata <= next_cdata; - pline <= next_pline; + load <= next_load; + xpos <= next_xpos; + ppos <= next_ppos; + pattern <= next_pattern; end -endmodule +endmodule diff --git a/hdl/vga/vga.v b/hdl/vga/vga.v @@ -1,4 +1,5 @@ -// Copyright 2012, Brian Swetland +// Copyright 2012, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. `timescale 1ns/1ns @@ -37,13 +38,13 @@ reg next_active; reg next_startline; reg [9:0] next_hcount; reg [9:0] next_vcount; -reg [9:0] next_lineno; -reg [7:0] lineno; + +wire [9:0] adjusted_vcount = next_vcount - 10'd32; assign hs = hsync; assign vs = vsync; assign fr = frame; -assign line = lineno; +assign line = adjusted_vcount[8:1]; assign advance = active; assign newline = startline; @@ -52,60 +53,49 @@ assign g = active ? pixel[7:4] : 4'd0; assign b = active ? pixel[3:0] : 4'd0; always_comb begin - next_hsync = 1'b0; - next_vsync = 1'b0; + next_hsync = hsync; + next_vsync = vsync; next_frame = 1'b0; - next_hcount = 10'd0; - next_vcount = 10'd0; next_active = 1'b0; next_startline = 1'b0; - next_lineno = 10'b0; + next_hcount = 10'd0; + next_vcount = 10'd0; if (hcount == 10'd799) begin if (vcount == 10'd523) begin next_vcount = 10'd0; next_frame = 1'b1; + next_vsync = 1'b0; end else next_vcount = vcount + 10'd1; next_hcount = 10'd0; + next_hsync = 1'b0; + next_startline = 1'b1; end else begin next_vcount = vcount; next_hcount = hcount + 10'd1; - end - - if (next_hcount == 0) - next_startline = 1'b1; - else - next_startline = 1'b0; + + if (hcount == 10'd96) + next_hsync = 1'b1; - if (next_hcount < 10'd96) - next_hsync = 1'b0; - else - next_hsync = 1'b1; - - if (next_vcount < 10'd2) - next_vsync = 1'b0; - else - next_vsync = 1'b1; + if (vcount == 10'd2) + next_vsync = 1'b1; - if ((next_vcount > 31) && (next_vcount < 512)) - if ((next_hcount > 143) && (next_hcount < 784)) - next_active = 1'b1; + if ((vcount > 30) && (vcount < 511)) + if ((hcount > 142) && (hcount < 783)) + next_active = 1'b1; + end - next_lineno = next_vcount - 10'd32; end always_ff @(posedge clk) begin - hcount <= next_hcount; - vcount <= next_vcount; hsync <= next_hsync; vsync <= next_vsync; frame <= next_frame; - - /* signals to pixel generator */ - startline <= next_startline; active <= next_active; - lineno <= next_lineno[8:1]; + startline <= next_startline; + hcount <= next_hcount; + vcount <= next_vcount; end endmodule diff --git a/hdl/vga/vga40x30x2.v b/hdl/vga/vga40x30x2.v @@ -1,3 +1,5 @@ +// Copyright 2012, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. module vga40x30x2( input clk25m, diff --git a/hdl/vga/videoram.v b/hdl/vga/videoram.v @@ -1,4 +1,5 @@ -// Copyright 2012, Brian Swetland. Use at your own risk. +// Copyright 2012, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. // // sync sram with independent read/write addressing