commit 7325aaa9c7a3926d1db2d5b5da6e602fd13e0436
parent 1ae545c4a42369580a84008f3aab3eef7e0e8a1b
Author: Brian Swetland <swetland@frotz.net>
Date: Tue, 18 Dec 2018 14:35:07 -0800
vga40x30: fix cdata and pdata preloading
This still could use some more tidying, but at least
it correctly displays all 40 columns in their correct
locations.
Diffstat:
2 files changed, 59 insertions(+), 26 deletions(-)
diff --git a/hdl/vga/chardata.v b/hdl/vga/chardata.v
@@ -37,32 +37,50 @@ initial $readmemh("prom.txt", pattern_rom);
`endif
reg next_load;
+reg next_load_cdata;
+reg next_loaded_cdata;
+reg next_load_pdata;
+reg next_load_pattern;
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;
+reg load_cdata = 1'b0;
+reg loaded_cdata = 1'b0;
+reg load_pdata = 1'b0;
+reg load_pattern = 1'b0;
+reg [5:0]xpos = 6'b0;
+reg [3:0]ppos = 4'b0;
+reg [15:0]pattern = 16'b0;
+
+reg [7:0]cdata;
+reg [7:0]pdata;
// 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 };
+assign vram_addr = { line[7:3], 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 [9:0] prom_addr = { cdata[6:0], line[2:0] };
`ifdef ASYNC_ROM
-wire [7:0] cdata = pattern_rom[pattern_addr];
+wire [7:0] prom_data = pattern_rom[prom_addr];
`else
-reg [7:0] cdata;
+reg [7:0] prom_data;
always_ff @(posedge clk)
- cdata <= pattern_rom[pattern_addr];
+ prom_data <= pattern_rom[prom_addr];
`endif
+// double-wide pattern data
+wire [15:0]pdata2x = {
+ pdata[7], pdata[7], pdata[6], pdata[6],
+ pdata[5], pdata[5], pdata[4], pdata[4],
+ pdata[3], pdata[3], pdata[2], pdata[2],
+ pdata[1], pdata[1], pdata[0], pdata[0]
+ };
// the high bit of the pattern shift register is used to
// select the FG or BG color and feed out to the vga core
@@ -74,39 +92,54 @@ always_comb begin
next_pattern = pattern;
next_load = 1'b0;
+ // multi-step load (cdata, then pdata, then pattern)
+ next_load_cdata = load;
+ next_loaded_cdata = load_cdata;
+ next_load_pdata = loaded_cdata;
+ next_load_pattern = load_pdata;
+
if (newline) begin
+ // reset character counter (xpos), pattern counter (ppos),
+ // and preload the first pattern
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;
+ // advance to next pattern (preloaded in pdata)
+ next_pattern = pdata2x;
+ end else begin
+ // advance to the next bit in the current pattern
+ next_pattern = { pattern[14:0], 1'b0 };
+ if (ppos == 4'd0) begin
+ // advance xpos and start preloading
+ // for the next character
+ next_load = 1'b1;
+ next_xpos = xpos + 6'd1;
+ end
end
+ end else begin
+ // handle the final step of preloading the pattern
+ // for xpos 0 (between newline=1 and advance=1)
+ if (load_pattern)
+ next_pattern = pdata2x;
end
-
- // 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
load <= next_load;
+ load_cdata <= next_load_cdata;
+ loaded_cdata <= next_loaded_cdata;
+ load_pdata <= next_load_pdata;
+ load_pattern <= next_load_pattern;
xpos <= next_xpos;
ppos <= next_ppos;
pattern <= next_pattern;
+ if (load_cdata)
+ cdata <= vram_data;
+ if (load_pdata)
+ pdata <= prom_data;
end
endmodule
diff --git a/hdl/vga/vram.txt b/hdl/vga/vram.txt
@@ -37,7 +37,7 @@
00
00
00
-00
+7F
00
00
00