diff --git a/Artix-7-HDMI-processing.xpr b/Artix-7-HDMI-processing.xpr
index 8ee608d..1a93e68 100644
--- a/Artix-7-HDMI-processing.xpr
+++ b/Artix-7-HDMI-processing.xpr
@@ -42,7 +42,7 @@
-
+
@@ -214,6 +214,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -235,8 +250,16 @@
+
+
+
+
+
+
+
+
@@ -303,9 +326,14 @@
+
+
+
+
+
-
+
@@ -317,6 +345,7 @@
+
diff --git a/charmap_gen.ipynb b/charmap_gen.ipynb
index 0e3c709..c06d96e 100644
--- a/charmap_gen.ipynb
+++ b/charmap_gen.ipynb
@@ -2,13 +2,14 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 26,
- "id": "similar-recorder",
+ "execution_count": 96,
+ "id": "leading-oasis",
"metadata": {},
"outputs": [],
"source": [
"import string\n",
"import contextlib\n",
+ "import itertools\n",
"\n",
"import bdfparser\n",
"from PIL import Image\n",
@@ -18,8 +19,8 @@
},
{
"cell_type": "code",
- "execution_count": 66,
- "id": "developing-oakland",
+ "execution_count": 104,
+ "id": "plastic-command",
"metadata": {},
"outputs": [],
"source": [
@@ -35,14 +36,16 @@
"end\n",
"'''\n",
" \n",
- " def __init__(self, font_id, bdf_file, glyph_w, glyph_h, chars=string.printable):\n",
+ " def __init__(self, font_id, bdf_file, glyph_w, glyph_h, chars=[chr(x) for x in range(128)]):\n",
" self.font_id = font_id\n",
" self.font = bdfparser.Font(bdf_file)\n",
- " self.chars = [ char for char in chars if ord(char) in font.glyphs ]\n",
+ " self.chars = chars # [ char for char in chars if ord(char) in font.glyphs ]\n",
" self.glyph_w, self.glyph_h = glyph_w, glyph_h\n",
" \n",
- " self.glyphs = [ font.glyph(char).draw().crop(self.glyph_w, self.glyph_h) for char in self.chars ]\n",
- " self.glyphtable = bdfparser.Bitmap.concatall(glyphs, direction=0)\n",
+ " self.glyphs = [ font.glyph(char).draw().crop(self.glyph_w, self.glyph_h)\n",
+ " if ord(char) in font.glyphs else bdfparser.Bitmap(['0'*glyph_w]*glyph_h)\n",
+ " for char in self.chars ]\n",
+ " self.glyphtable = bdfparser.Bitmap.concatall(self.glyphs, direction=0)\n",
" \n",
" def font_preview(self):\n",
" preview = self.font.drawall()\n",
@@ -51,7 +54,7 @@
" def glyphtable_preview(self):\n",
" return Image.frombytes('1',\n",
" (self.glyphtable.width(), self.glyphtable.height()),\n",
- " glyphtable.tobytes('1')).rotate(90, expand=True)\n",
+ " self.glyphtable.tobytes('1')).rotate(90, expand=True)\n",
"\n",
" def write_printable_table(self):\n",
" with open(f'src/gen/gen_charmap_is_printable_{self.font_id}.v', 'w') as f, contextlib.redirect_stdout(f):\n",
@@ -76,18 +79,18 @@
},
{
"cell_type": "code",
- "execution_count": 67,
- "id": "matched-washer",
+ "execution_count": 94,
+ "id": "divided-bookmark",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 67,
+ "execution_count": 94,
"metadata": {},
"output_type": "execute_result"
}
@@ -104,18 +107,18 @@
},
{
"cell_type": "code",
- "execution_count": 65,
- "id": "changed-carpet",
+ "execution_count": 95,
+ "id": "joint-network",
"metadata": {},
"outputs": [
{
"data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAABfAAAAAIAQAAAACeuOMJAAACzElEQVR4nNWSPW4bRxzFf7uiBTkIsFukCOBipnDhLgRcutAewUfwCSLegHsDC7mAdIP4BpoNYECpyM4IBGqHkgMFSOwZQYVJ7sdzsaJtOUKClHkDzMf7fw7+LxH/Z6RLS3wbL22V11b2lEu7LLq8s72v8q70rEddDtBG6PIu72xn12lLe0xc52vWdjNfj9q4zC/tH8fXhY+eK1vl4PGRWOVVvrQXLL+/iMF6KvsLVT6fzzmNAG25snjFoR19sQ9oS3jLcvyZ2F6OAc6CwiIsQpguwiL8pkU4rzehGdbBmZp3jaTTna6WGjW6tag5aIKC9hX6E71bh3MtQh1CXYda56GT5EyoFYI0rcO56nBeL0IthX5f9c3+jc6C9FIuex9mP18ZSZI2J72kXtJMkhRCM+210JuDgQpSI9VB6hQkpSmVTYA9AB6UQP63GcWnm8QT75neISQOkq1j3tMD4KOZ73nYQ+VA4Aef5BD/0H1DCkx4NoHH3MzBx+siddvEjwHYi6AyeU7hI5Mqj8Dg8rsFSBN+8EkJoyH1V60/yAF+tSMSV9nujvX1GEAWICm/tCTA0lpGDtKtFCwOljmAHCR5QvUc4Kfv1mNxSB51DJuCOTB/yGa+mY889EXyCqBzxnvAsTOu8m4egTQp96BISYEcJnfbfxQBnnoA43filk+BZx6YJF4FUPAVjB8+tZ0GUIKJoElSfCgUk3L/1SGvD3/8688X3zIheRHzvth1PAHGO8XuePdJ6qC1kLil/QBYoOSR348Mw/RGuppdHfXTqo6m1oVZSsZlrWlNaxq1xmWSblwmNVplrVklrVllbWi0MisprGcr08x85jJvXOZuT0lHLnNZ0PD2xmWXR7WcqaR6NrtR/VKSmun78GbW32q/11b7g/h7NdMQLlWHgRi0P+BEEvoPWGX3cOafY9ydmPoTN/vEXdfhXyv7e6rMJH0EOlGyruNKhOcAAAAASUVORK5CYII=\n",
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAACAAAAAAIAQAAAABFYCKXAAAC7klEQVR4nOWUT27bRhTGf6QVwykKcBZdFMiCs8giuwrIMgvzCDlCTlDrBtINLPQC9g2aG5gsEMBZUbugMGSO7BQu0CYzhheRxD9fF5ScGE2BNs6uHwES7715783HefNF4v+N+PX0a5RpJkuLU+gtffJeWMLbcGkLU1nZUy7tItvmwFsWw4W5tL8fX2cuOK5sYcDhAqEwhVnYCxbfXwRvHYX9hcLMZjNOw8fG0JrWdq4w7cSxGrQGoAnQmta0trWruKE5JqzMipVdz1aDZpN/DFB53RuHypP3vvz5Ku3t9UknqZNU6szLz/3c+/Hcz/2vmvvzSpK8r8ed5npzcK65r7yvKl/p3LeS8tRX8l4aV/5clT+v5r6SfLev6mb/RmdeUil5qZbWvu6fgzPV72pJpzttJdWqtYmoPqi9vPbluxO9W/nKS628pNia+5//iGcjeMzNDFy4zuJ8G3lMTGEjYA+ABxPAAOwF0CR6zmYegunoAHAhne052EOT3oHr10RT3MP8G2JcYFSYANy2+ojwdB05wmc2OoUohwiA3yxA/F/J/h3Fc4CfvlsNxRQTdAzrjBkwe0jEDy6awKCnYADWs/Vs4KDLopd3a0XAwloGOcSbS4Qlh4UBUA6RiYA2T53j7g94YABe2wFRXtj+MmzxagggCxBNdoaFaWcBiF34UuJb7L+c8mr6459/vPiWEdGLYLpsN+cJMNzJoskeZDExYGAEsDvcfRLn0Nj+RO4idRBNYDsRwATSABpF2YdMIZos7AfA9qFbPAoAT11fZeeWWQw8c8AocsqA7JHbD/SDdXp4fw2Q6vF7/6bsNhrQaasBKl0qXZVXR924qEJa6SJdbNbUY+8vVXmX5IlL8yTffCUd5UmeePW2S/Pk8qhSnhZSVZY3qg6lUlsNUJonTdqkTVqr6fNv8kSqtUyadBk16TJpfK1lupT8qlymddnv80QSX4O+JF1/oZq69J8iefKpVd36yn9ZeZl8xnenWynpL8gRenmHTEe6AAAAAElFTkSuQmCC\n",
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 65,
+ "execution_count": 95,
"metadata": {},
"output_type": "execute_result"
}
@@ -123,6 +126,18 @@
"source": [
"default_glyphtable_gen.glyphtable_preview()"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 107,
+ "id": "revised-launch",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "with open('test_bench/test_data/test_glyphmem_data.hex', 'w') as f:\n",
+ " for c in itertools.islice(itertools.cycle(string.printable), 256*128):\n",
+ " print(f'{ord(c):04x}', file=f)"
+ ]
}
],
"metadata": {
diff --git a/src/gen/gen_charmap_is_printable_default.v b/src/gen/gen_charmap_is_printable_default.v
index c4a989d..1ed3c4c 100644
--- a/src/gen/gen_charmap_is_printable_default.v
+++ b/src/gen/gen_charmap_is_printable_default.v
@@ -2,6 +2,54 @@
module gen_charmap_is_printable_default(input glyph[15:0], output reg is_printable) begin
always @(glyph) begin
case(glyph)
+ 16'h0000: is_printable <= 1;
+ 16'h0001: is_printable <= 1;
+ 16'h0002: is_printable <= 1;
+ 16'h0003: is_printable <= 1;
+ 16'h0004: is_printable <= 1;
+ 16'h0005: is_printable <= 1;
+ 16'h0006: is_printable <= 1;
+ 16'h0007: is_printable <= 1;
+ 16'h0008: is_printable <= 1;
+ 16'h0009: is_printable <= 1;
+ 16'h000a: is_printable <= 1;
+ 16'h000b: is_printable <= 1;
+ 16'h000c: is_printable <= 1;
+ 16'h000d: is_printable <= 1;
+ 16'h000e: is_printable <= 1;
+ 16'h000f: is_printable <= 1;
+ 16'h0010: is_printable <= 1;
+ 16'h0011: is_printable <= 1;
+ 16'h0012: is_printable <= 1;
+ 16'h0013: is_printable <= 1;
+ 16'h0014: is_printable <= 1;
+ 16'h0015: is_printable <= 1;
+ 16'h0016: is_printable <= 1;
+ 16'h0017: is_printable <= 1;
+ 16'h0018: is_printable <= 1;
+ 16'h0019: is_printable <= 1;
+ 16'h001a: is_printable <= 1;
+ 16'h001b: is_printable <= 1;
+ 16'h001c: is_printable <= 1;
+ 16'h001d: is_printable <= 1;
+ 16'h001e: is_printable <= 1;
+ 16'h001f: is_printable <= 1;
+ 16'h0020: is_printable <= 1;
+ 16'h0021: is_printable <= 1;
+ 16'h0022: is_printable <= 1;
+ 16'h0023: is_printable <= 1;
+ 16'h0024: is_printable <= 1;
+ 16'h0025: is_printable <= 1;
+ 16'h0026: is_printable <= 1;
+ 16'h0027: is_printable <= 1;
+ 16'h0028: is_printable <= 1;
+ 16'h0029: is_printable <= 1;
+ 16'h002a: is_printable <= 1;
+ 16'h002b: is_printable <= 1;
+ 16'h002c: is_printable <= 1;
+ 16'h002d: is_printable <= 1;
+ 16'h002e: is_printable <= 1;
+ 16'h002f: is_printable <= 1;
16'h0030: is_printable <= 1;
16'h0031: is_printable <= 1;
16'h0032: is_printable <= 1;
@@ -12,32 +60,13 @@ module gen_charmap_is_printable_default(input glyph[15:0], output reg is_printab
16'h0037: is_printable <= 1;
16'h0038: is_printable <= 1;
16'h0039: is_printable <= 1;
- 16'h0061: is_printable <= 1;
- 16'h0062: is_printable <= 1;
- 16'h0063: is_printable <= 1;
- 16'h0064: is_printable <= 1;
- 16'h0065: is_printable <= 1;
- 16'h0066: is_printable <= 1;
- 16'h0067: is_printable <= 1;
- 16'h0068: is_printable <= 1;
- 16'h0069: is_printable <= 1;
- 16'h006a: is_printable <= 1;
- 16'h006b: is_printable <= 1;
- 16'h006c: is_printable <= 1;
- 16'h006d: is_printable <= 1;
- 16'h006e: is_printable <= 1;
- 16'h006f: is_printable <= 1;
- 16'h0070: is_printable <= 1;
- 16'h0071: is_printable <= 1;
- 16'h0072: is_printable <= 1;
- 16'h0073: is_printable <= 1;
- 16'h0074: is_printable <= 1;
- 16'h0075: is_printable <= 1;
- 16'h0076: is_printable <= 1;
- 16'h0077: is_printable <= 1;
- 16'h0078: is_printable <= 1;
- 16'h0079: is_printable <= 1;
- 16'h007a: is_printable <= 1;
+ 16'h003a: is_printable <= 1;
+ 16'h003b: is_printable <= 1;
+ 16'h003c: is_printable <= 1;
+ 16'h003d: is_printable <= 1;
+ 16'h003e: is_printable <= 1;
+ 16'h003f: is_printable <= 1;
+ 16'h0040: is_printable <= 1;
16'h0041: is_printable <= 1;
16'h0042: is_printable <= 1;
16'h0043: is_printable <= 1;
@@ -64,39 +93,43 @@ module gen_charmap_is_printable_default(input glyph[15:0], output reg is_printab
16'h0058: is_printable <= 1;
16'h0059: is_printable <= 1;
16'h005a: is_printable <= 1;
- 16'h0021: is_printable <= 1;
- 16'h0022: is_printable <= 1;
- 16'h0023: is_printable <= 1;
- 16'h0024: is_printable <= 1;
- 16'h0025: is_printable <= 1;
- 16'h0026: is_printable <= 1;
- 16'h0027: is_printable <= 1;
- 16'h0028: is_printable <= 1;
- 16'h0029: is_printable <= 1;
- 16'h002a: is_printable <= 1;
- 16'h002b: is_printable <= 1;
- 16'h002c: is_printable <= 1;
- 16'h002d: is_printable <= 1;
- 16'h002e: is_printable <= 1;
- 16'h002f: is_printable <= 1;
- 16'h003a: is_printable <= 1;
- 16'h003b: is_printable <= 1;
- 16'h003c: is_printable <= 1;
- 16'h003d: is_printable <= 1;
- 16'h003e: is_printable <= 1;
- 16'h003f: is_printable <= 1;
- 16'h0040: is_printable <= 1;
16'h005b: is_printable <= 1;
16'h005c: is_printable <= 1;
16'h005d: is_printable <= 1;
16'h005e: is_printable <= 1;
16'h005f: is_printable <= 1;
16'h0060: is_printable <= 1;
+ 16'h0061: is_printable <= 1;
+ 16'h0062: is_printable <= 1;
+ 16'h0063: is_printable <= 1;
+ 16'h0064: is_printable <= 1;
+ 16'h0065: is_printable <= 1;
+ 16'h0066: is_printable <= 1;
+ 16'h0067: is_printable <= 1;
+ 16'h0068: is_printable <= 1;
+ 16'h0069: is_printable <= 1;
+ 16'h006a: is_printable <= 1;
+ 16'h006b: is_printable <= 1;
+ 16'h006c: is_printable <= 1;
+ 16'h006d: is_printable <= 1;
+ 16'h006e: is_printable <= 1;
+ 16'h006f: is_printable <= 1;
+ 16'h0070: is_printable <= 1;
+ 16'h0071: is_printable <= 1;
+ 16'h0072: is_printable <= 1;
+ 16'h0073: is_printable <= 1;
+ 16'h0074: is_printable <= 1;
+ 16'h0075: is_printable <= 1;
+ 16'h0076: is_printable <= 1;
+ 16'h0077: is_printable <= 1;
+ 16'h0078: is_printable <= 1;
+ 16'h0079: is_printable <= 1;
+ 16'h007a: is_printable <= 1;
16'h007b: is_printable <= 1;
16'h007c: is_printable <= 1;
16'h007d: is_printable <= 1;
16'h007e: is_printable <= 1;
- 16'h0020: is_printable <= 1;
+ 16'h007f: is_printable <= 1;
default: is_printable <= 0;
endcase
end
diff --git a/src/gen/gen_font_params_default.vh b/src/gen/gen_font_params_default.vh
index 11c6af2..256c6f5 100644
--- a/src/gen/gen_font_params_default.vh
+++ b/src/gen/gen_font_params_default.vh
@@ -1,3 +1,3 @@
`define GEN_FONT_GLYPH_W_default 8
`define GEN_FONT_GLYPH_H_default 16
-`define GEN_FONT_GLYPH_COUNT_default 95
+`define GEN_FONT_GLYPH_COUNT_default 128
diff --git a/src/gen/gen_glyphtable_default.hex b/src/gen/gen_glyphtable_default.hex
index eb0b9d8..4b0f2a0 100644
--- a/src/gen/gen_glyphtable_default.hex
+++ b/src/gen/gen_glyphtable_default.hex
@@ -1,5 +1,773 @@
00
00
+66
+42
+00
+42
+42
+42
+00
+42
+42
+66
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+10
+10
+10
+10
+10
+10
+10
+00
+10
+10
+00
+00
+00
+00
+00
+24
+24
+24
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+24
+24
+24
+7e
+24
+24
+7e
+24
+24
+24
+00
+00
+00
+00
+00
+10
+10
+7c
+92
+90
+90
+7c
+12
+12
+92
+7c
+10
+10
+00
+00
+00
+00
+64
+94
+68
+08
+10
+10
+20
+2c
+52
+4c
+00
+00
+00
+00
+00
+00
+18
+24
+24
+18
+30
+4a
+44
+44
+44
+3a
+00
+00
+00
+00
+00
+10
+10
+10
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+08
+10
+20
+20
+20
+20
+20
+20
+10
+08
+00
+00
+00
+00
+00
+00
+20
+10
+08
+08
+08
+08
+08
+08
+10
+20
+00
+00
+00
+00
+00
+00
+00
+00
+00
+24
+18
+7e
+18
+24
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+10
+10
+7c
+10
+10
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+10
+10
+20
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+7e
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+10
+10
+00
+00
+00
+00
+00
+00
+04
+04
+08
+08
+10
+10
+20
+20
+40
+40
+00
+00
+00
+00
+00
+00
3c
42
42
@@ -163,91 +931,11 @@
00
00
00
-3c
-02
-3e
-42
-42
-42
-3e
-00
-00
-00
-00
-00
-00
-40
-40
-40
-7c
-42
-42
-42
-42
-42
-7c
-00
-00
-00
-00
-00
-00
-00
-00
-00
-3c
-42
-40
-40
-40
-42
-3c
-00
-00
-00
-00
-00
-00
-02
-02
-02
-3e
-42
-42
-42
-42
-42
-3e
-00
-00
-00
-00
-00
-00
-00
-00
-00
-3c
-42
-42
-7e
-40
-40
-3c
-00
-00
-00
-00
-00
-00
-0e
-10
-10
-7c
-10
-10
10
10
+00
+00
+00
10
10
00
@@ -259,316 +947,92 @@
00
00
00
-3e
-42
-42
-42
-42
-42
-3e
-02
-02
-3c
-00
-00
-00
-40
-40
-40
-7c
-42
-42
-42
-42
-42
-42
-00
-00
-00
+10
+10
00
00
00
10
10
+20
00
-30
-10
-10
-10
-10
-10
-38
00
00
00
00
00
-00
-04
-04
-00
-0c
-04
-04
-04
-04
-04
-04
-44
-44
-38
-00
-00
-00
-40
-40
-40
-42
-44
-48
-70
-48
-44
-42
-00
-00
-00
-00
-00
-00
-30
-10
-10
-10
-10
-10
-10
-10
-10
-38
-00
-00
-00
-00
-00
-00
-00
-00
-00
-fc
-92
-92
-92
-92
-92
-92
-00
-00
-00
-00
-00
-00
-00
-00
-00
-7c
-42
-42
-42
-42
-42
-42
-00
-00
-00
-00
-00
-00
-00
-00
-00
-3c
-42
-42
-42
-42
-42
-3c
-00
-00
-00
-00
-00
-00
-00
-00
-00
-7c
-42
-42
-42
-42
-42
-7c
-40
-40
-40
-00
-00
-00
-00
-00
-00
-3e
-42
-42
-42
-42
-42
-3e
-02
-02
-02
-00
-00
-00
-00
-00
-00
-5e
-60
-40
-40
-40
-40
-40
-00
-00
-00
-00
-00
-00
-00
-00
-00
-3e
-40
-40
-3c
-02
-02
-7c
-00
-00
-00
-00
-00
-00
-10
-10
-10
-7c
-10
-10
-10
-10
-10
-0e
-00
-00
-00
-00
-00
-00
-00
-00
-00
-42
-42
-42
-42
-42
-42
-3e
-00
-00
-00
-00
-00
-00
-00
-00
-00
-42
-42
-42
-24
-24
-18
-18
-00
-00
-00
-00
-00
-00
-00
-00
-00
-82
-82
-92
-92
-92
-92
-7c
-00
-00
-00
-00
-00
-00
-00
-00
-00
-42
-42
-24
-18
-24
-42
-42
-00
-00
-00
-00
-00
-00
-00
-00
-00
-42
-42
-42
-42
-42
-42
-3e
-02
-02
-3c
-00
-00
-00
-00
-00
-00
-7e
04
08
10
20
40
+20
+10
+08
+04
+00
+00
+00
+00
+00
+00
+00
+00
+00
+7e
+00
+00
+7e
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+40
+20
+10
+08
+04
+08
+10
+20
+40
+00
+00
+00
+00
+00
+00
+3c
+42
+42
+42
+04
+08
+08
+00
+08
+08
+00
+00
+00
+00
+00
+00
+7c
+82
+9e
+a2
+a2
+a2
+a6
+9a
+80
7e
00
00
@@ -992,358 +1456,6 @@ c6
00
00
00
-10
-10
-10
-10
-10
-10
-10
-00
-10
-10
-00
-00
-00
-00
-00
-24
-24
-24
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-24
-24
-24
-7e
-24
-24
-7e
-24
-24
-24
-00
-00
-00
-00
-00
-10
-10
-7c
-92
-90
-90
-7c
-12
-12
-92
-7c
-10
-10
-00
-00
-00
-00
-64
-94
-68
-08
-10
-10
-20
-2c
-52
-4c
-00
-00
-00
-00
-00
-00
-18
-24
-24
-18
-30
-4a
-44
-44
-44
-3a
-00
-00
-00
-00
-00
-10
-10
-10
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-08
-10
-20
-20
-20
-20
-20
-20
-10
-08
-00
-00
-00
-00
-00
-00
-20
-10
-08
-08
-08
-08
-08
-08
-10
-20
-00
-00
-00
-00
-00
-00
-00
-00
-00
-24
-18
-7e
-18
-24
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-10
-10
-7c
-10
-10
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-10
-10
-20
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-7e
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-10
-10
-00
-00
-00
-00
-00
-00
-04
-04
-08
-08
-10
-10
-20
-20
-40
-40
-00
-00
-00
-00
-00
-00
-00
-00
-00
-10
-10
-00
-00
-00
-10
-10
-00
-00
-00
-00
-00
-00
-00
-00
-00
-10
-10
-00
-00
-00
-10
-10
-20
-00
-00
-00
-00
-00
-00
-04
-08
-10
-20
-40
-20
-10
-08
-04
-00
-00
-00
-00
-00
-00
-00
-00
-00
-7e
-00
-00
-7e
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-40
-20
-10
-08
-04
-08
-10
-20
-40
-00
-00
-00
-00
-00
-00
-3c
-42
-42
-42
-04
-08
-08
-00
-08
-08
-00
-00
-00
-00
-00
-00
-7c
-82
-9e
-a2
-a2
-a2
-a6
-9a
-80
-7e
-00
-00
-00
-00
-00
-00
38
20
20
@@ -1440,6 +1552,422 @@ a6
00
00
00
+00
+00
+00
+3c
+02
+3e
+42
+42
+42
+3e
+00
+00
+00
+00
+00
+00
+40
+40
+40
+7c
+42
+42
+42
+42
+42
+7c
+00
+00
+00
+00
+00
+00
+00
+00
+00
+3c
+42
+40
+40
+40
+42
+3c
+00
+00
+00
+00
+00
+00
+02
+02
+02
+3e
+42
+42
+42
+42
+42
+3e
+00
+00
+00
+00
+00
+00
+00
+00
+00
+3c
+42
+42
+7e
+40
+40
+3c
+00
+00
+00
+00
+00
+00
+0e
+10
+10
+7c
+10
+10
+10
+10
+10
+10
+00
+00
+00
+00
+00
+00
+00
+00
+00
+3e
+42
+42
+42
+42
+42
+3e
+02
+02
+3c
+00
+00
+00
+40
+40
+40
+7c
+42
+42
+42
+42
+42
+42
+00
+00
+00
+00
+00
+00
+10
+10
+00
+30
+10
+10
+10
+10
+10
+38
+00
+00
+00
+00
+00
+00
+04
+04
+00
+0c
+04
+04
+04
+04
+04
+04
+44
+44
+38
+00
+00
+00
+40
+40
+40
+42
+44
+48
+70
+48
+44
+42
+00
+00
+00
+00
+00
+00
+30
+10
+10
+10
+10
+10
+10
+10
+10
+38
+00
+00
+00
+00
+00
+00
+00
+00
+00
+fc
+92
+92
+92
+92
+92
+92
+00
+00
+00
+00
+00
+00
+00
+00
+00
+7c
+42
+42
+42
+42
+42
+42
+00
+00
+00
+00
+00
+00
+00
+00
+00
+3c
+42
+42
+42
+42
+42
+3c
+00
+00
+00
+00
+00
+00
+00
+00
+00
+7c
+42
+42
+42
+42
+42
+7c
+40
+40
+40
+00
+00
+00
+00
+00
+00
+3e
+42
+42
+42
+42
+42
+3e
+02
+02
+02
+00
+00
+00
+00
+00
+00
+5e
+60
+40
+40
+40
+40
+40
+00
+00
+00
+00
+00
+00
+00
+00
+00
+3e
+40
+40
+3c
+02
+02
+7c
+00
+00
+00
+00
+00
+00
+10
+10
+10
+7c
+10
+10
+10
+10
+10
+0e
+00
+00
+00
+00
+00
+00
+00
+00
+00
+42
+42
+42
+42
+42
+42
+3e
+00
+00
+00
+00
+00
+00
+00
+00
+00
+42
+42
+42
+24
+24
+18
+18
+00
+00
+00
+00
+00
+00
+00
+00
+00
+82
+82
+92
+92
+92
+92
+7c
+00
+00
+00
+00
+00
+00
+00
+00
+00
+42
+42
+24
+18
+24
+42
+42
+00
+00
+00
+00
+00
+00
+00
+00
+00
+42
+42
+42
+42
+42
+42
+3e
+02
+02
+3c
+00
+00
+00
+00
+00
+00
+7e
+04
+08
+10
+20
+40
+7e
+00
+00
+00
+00
+00
+00
0c
10
10
diff --git a/src/term_renderer.v b/src/term_renderer.v
index 7b73b7e..4c7c846 100644
--- a/src/term_renderer.v
+++ b/src/term_renderer.v
@@ -8,21 +8,22 @@ input in_vsync, in_hsync,
input [15:0] glyphmem_data,
output [15:0] glyphmem_r_addr,
+output out_hsync, out_vsync,
output [7:0] out_red,
output [7:0] out_green,
output [7:0] out_blue
);
-parameter GLYPHMEM_W = 512; /* glyphs */
-parameter GLYPHMEM_H = 256; /* glyphs */
+parameter GLYPHMEM_W = 256; /* glyphs */
+parameter GLYPHMEM_H = 128; /* glyphs */
/* Glyph table instantiation */
`include "gen/gen_font_params_default.vh"
-`define FONT_GLYPH_W GEN_FONT_GLYPH_W_default
-`define FONT_GLYPH_H GEN_FONT_GLYPH_H_default
-`define FONT_GLYPH_COUNT GEN_FONT_GLYPH_COUNT_default
-reg [FONT_GLYPH_W-1:0] glyph_table [0:FONT_GLYPH_COUNT-1];
-initial $readmemh("../../../../src/gen/gen_glyphtable_default.hex", glyph_table_deault);
+localparam FONT_GLYPH_W = `GEN_FONT_GLYPH_W_default;
+localparam FONT_GLYPH_H = `GEN_FONT_GLYPH_H_default;
+localparam FONT_GLYPH_COUNT = `GEN_FONT_GLYPH_COUNT_default;
+reg [FONT_GLYPH_W-1:0] glyph_table_default [0:FONT_GLYPH_COUNT*FONT_GLYPH_H-1];
+initial $readmemh("../../../../src/gen/gen_glyphtable_default.hex", glyph_table_default);
/* Glyph x/y synchronization logic */
reg [11:0] glyph_x;
@@ -32,7 +33,14 @@ reg [5:0] px_x;
reg [5:0] px_y;
reg in_hsync_last, in_vsync_last;
+assign out_vsync = in_vsync_last;
+assign out_hsync = in_hsync_last;
+
assign glyphmem_r_addr = (GLYPHMEM_W*glyph_y) + glyph_x;
+assign out_red = {8{glyph_sreg_out[FONT_GLYPH_W-1]}};
+assign out_green = {8{glyph_sreg_out[FONT_GLYPH_W-1]}};
+assign out_blue = {8{glyph_sreg_out[FONT_GLYPH_W-1]}};
+/* TODO: fg/bg color, bold, italic, underline, blink */
always @(posedge clk) begin
if (rst) begin
@@ -42,6 +50,7 @@ always @(posedge clk) begin
px_y <= 0;
in_hsync_last <= 0;
in_vsync_last <= 0;
+ glyph_sreg_out <= 0;
end else begin
in_hsync_last <= in_hsync;
@@ -55,18 +64,27 @@ always @(posedge clk) begin
px_y <= px_y + 1;
end else begin
glyph_y <= glyph_y + 1;
+ px_y <= 0;
end
end else if (in_hsync) begin
if (px_x != FONT_GLYPH_W-1) begin
px_x <= px_x + 1;
- glyph_sreg_out <= {glyph_sreg_out[FONT_GLYPH_W-2:0], 0};
end else begin
px_x <= 0;
- glyph_sreg_out <= glyph_table[glyphmem_data[7:0]];
- glyph_x <= glyph_x + 1;
end
+
+ if (px_x == 0) begin
+ glyph_sreg_out <= glyph_table_default[glyphmem_data[7:0]*FONT_GLYPH_H + px_y];
+ glyph_x <= glyph_x + 1;
+
+ end else begin
+ glyph_sreg_out <= {glyph_sreg_out[FONT_GLYPH_W-2:0], 1'b0};
+ end
+
+ end else if (!in_hsync_last) begin
+ glyph_sreg_out <= 0;
end
if (in_vsync_last && !in_vsync) begin
diff --git a/term_renderer_tb_behav.wcfg b/term_renderer_tb_behav.wcfg
new file mode 100644
index 0000000..eb30dfb
--- /dev/null
+++ b/term_renderer_tb_behav.wcfg
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ testcase_id[31:0]
+ testcase_id[31:0]
+ #008000
+ true
+ UNSIGNEDDECRADIX
+
+
+ rst
+ rst
+
+
+ clk
+ clk
+
+
+ in_vsync
+ in_vsync
+
+
+ in_hsync
+ in_hsync
+
+
+ glyphmem_data[15:0]
+ glyphmem_data[15:0]
+
+
+ glyphmem_r_addr[15:0]
+ glyphmem_r_addr[15:0]
+
+
+ out_red[7:0]
+ out_red[7:0]
+
+
+ out_green[7:0]
+ out_green[7:0]
+
+
+ out_blue[7:0]
+ out_blue[7:0]
+
+
+ glyph_sreg_out[7:0]
+ glyph_sreg_out[7:0]
+
+
+ glyph_x[11:0]
+ glyph_x[11:0]
+ UNSIGNEDDECRADIX
+ #FFFF00
+ true
+
+
+ glyph_y[11:0]
+ glyph_y[11:0]
+ UNSIGNEDDECRADIX
+ #FFFF00
+ true
+
+
+ px_x[5:0]
+ px_x[5:0]
+ UNSIGNEDDECRADIX
+ #FFFF00
+ true
+
+
+ px_y[5:0]
+ px_y[5:0]
+ UNSIGNEDDECRADIX
+ #FFFF00
+ true
+
+
+ in_hsync_last
+ in_hsync_last
+
+
+ in_vsync_last
+ in_vsync_last
+
+
+ GLYPHMEM_W[31:0]
+ GLYPHMEM_W[31:0]
+
+
+ GLYPHMEM_H[31:0]
+ GLYPHMEM_H[31:0]
+
+
+ FONT_GLYPH_W[31:0]
+ FONT_GLYPH_W[31:0]
+
+
+ FONT_GLYPH_H[31:0]
+ FONT_GLYPH_H[31:0]
+
+
+ FONT_GLYPH_COUNT[31:0]
+ FONT_GLYPH_COUNT[31:0]
+
+
diff --git a/test_bench/term_renderer_analysis.ipynb b/test_bench/term_renderer_analysis.ipynb
new file mode 100644
index 0000000..54c3edc
--- /dev/null
+++ b/test_bench/term_renderer_analysis.ipynb
@@ -0,0 +1,182 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 70,
+ "id": "exact-wallpaper",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import re\n",
+ "import contextlib\n",
+ "\n",
+ "from PIL import Image\n",
+ "import numpy as np\n",
+ "from matplotlib import pyplot as plt"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 72,
+ "id": "broke-detection",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "TC_BODY = '''\n",
+ "testcase_id = {tc_id};\n",
+ "\n",
+ "rst = 1;\n",
+ "clk = 0;\n",
+ "repeat(2) @(posedge clk);\n",
+ "rst = 0;\n",
+ "repeat(8) @(posedge clk);\n",
+ "\n",
+ "@(posedge clk) vsync = 1;\n",
+ "for (integer y=0; y<{h}; y=y+1) begin\n",
+ " for (integer x=0; x<{w}; x=x+1) begin\n",
+ " @(posedge clk) hsync = 1;\n",
+ " end\n",
+ " repeat(5) @(posedge clk) hsync = 0;\n",
+ "end\n",
+ "repeat(100) @(posedge clk) vsync = 0;\n",
+ "\n",
+ "$writememh(\"test_term_fb_dump_{tc_id}.hex\", data_recording, 0, ({w}+5) * {h} + 100);\n",
+ "'''\n",
+ "\n",
+ "TESTCASES = [\n",
+ " (32, 32),\n",
+ " (100, 20),\n",
+ " (97, 97)\n",
+ "]\n",
+ "\n",
+ "def write_testcases():\n",
+ " with open('test_data/00TERM_RENDERER_TC_IDX.v', 'w') as f, contextlib.redirect_stdout(f):\n",
+ " for tc_id, (w, h) in enumerate(TESTCASES):\n",
+ " print(TC_BODY.format(tc_id=tc_id, w=w, h=h))\n",
+ " \n",
+ "write_testcases()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 66,
+ "id": "synthetic-victim",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def read_hexfile(filename):\n",
+ " with open(filename) as f:\n",
+ " gen = ((int(line, 16) if re.match(r'^[0-9a-f]+$', line) else 0) for line in f if line.strip())\n",
+ " return np.array([ ((p>>16)&0xff, (p>>8)&0xff, p&0xff) for p in gen ])[:-1]\n",
+ "\n",
+ "def display_image(filename, w, h):\n",
+ " w_blanked = w+5\n",
+ " img = read_hexfile(filename).astype(np.uint8)[8+1:][:h*w_blanked].reshape((h, w_blanked, 3))\n",
+ " fig, ax = plt.subplots()\n",
+ " ax.imshow(img, interpolation='None')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 75,
+ "id": "protective-corps",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def show_tc(tc_id):\n",
+ " w, h = TESTCASES[tc_id]\n",
+ " display_image(f'../Artix-7-HDMI-processing.sim/sim_1/behav/xsim/test_term_fb_dump_{tc_id}.hex', w, h)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 76,
+ "id": "numerical-husband",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "show_tc(0)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 78,
+ "id": "regional-control",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAABhCAYAAADP5Pq1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAIC0lEQVR4nO3dXahldRnH8e+vmbI0Ii2VaUbSYLAsKGMQeyEik0aLxssRhLkQ5qbIIgjFq+66iKiLCgY1hwq9MMnBi0qmwJswtSLGl3EmzZycHEV6oYtUerrYS9sd55w5s1/W3v+zvh/YnL3+Z6/9/z/rrPOw1rPeUlVIktrzhkUPQJI0GRO4JDXKBC5JjTKBS1KjTOCS1CgTuCQ1aqoEnmRnksNJjia5cVaDkiSdWiY9DzzJJuAJ4ErgGPAgcG1VPTq74UmSVrN5inkvA45W1ZMASe4EdgGrJvAkXjUkSafvhao6d2XjNCWUrcAzY9PHujZJ0mw9fbLGabbAc5K2121hJ9kL7J2iH0nSSUyTwI8BF4xNbwOeXfmhqtoH7ANLKJI0S9OUUB4Etie5KMmbgN3AgdkMS5J0KhNvgVfVK0m+CPwc2ATcVlWPzGxkkqQ1TXwa4USdTVBCmWR8ycnK85MZ73/a7+0jlkUvr7WsZ1nOcn2cJK719r+e715ELENfx9Zj5fiXaWxreLiqdqxs9EpMSWqUCVySGmUCl6RGTXMa4dxMW3eeZv5ZHxPoI5ZFLq/1fu8klqk2P4m+jpkMeR0bOrfAJalRJnBJatRSllD6ttbuXZ+nWW4ErSxLd+m1EbgFLkmNMoFLUqM2RAllmc926GP3fNElAMsRs+Oy/J++rvg83X4WfYXvOLfAJalRJnBJalSzJZRWznY4XbO+0c56lsWyXpixrLvQk/YzL+NjaT2WcX2tl9Nc7LfWvH38j7gFLkmNMoFLUqOaKqFs1CP084zrdO9bvehdwlmWjOa1Cz1pP/P6rj7mn7ZMM4mWS6F9cQtckhplApekRpnAJalRS18Dt+69nKxPDtc8T9WcZT1/CNwCl6RGmcAlqVFLX0Jpsbywmj4eXbbMN+Ya2u7tWlovoWk5nHILPMltSU4kOTTWdk6S+5Ic6X6ePd9hSpJWWk8J5XZg54q2G4GDVbUdONhNS5J6dMoEXlX3Ay+uaN4F7O/e7weume2wNo6qeu2V5LWXTm58ealtrvvzN+lBzPOr6jhA9/O82Q1JkrQecz+ImWQvsHfe/UjS0EyawJ9LsqWqjifZApxY7YNVtQ/YB5BkXfvFfd/feJKLDCbpb16PfttI94PuKxaX2cnnX495PR5s5TzLetOsea5jfT1S7QCwp3u/B7hnwu+RJE1oPacR3gH8Grg4ybEk1wPfAK5McgS4spuWJPUofR7tX28JRZL0fx6uqh0rG72UXpIaZQKXpEaZwCWpUSZwSWqUCVySGmUCl6RGmcAlqVEmcElqlAlckhplApekRpnAJalRJnBJapQJXJIaZQKXpEaZwCWpUXN/Jqak1z9Sa7VHZ41/bpke27aWFse8SGs9g6GvR6pJkhbMBC5JjTKBS1KjlrIGPm1NbT3zz6uP9dY6p+3ndD8zSR+LjmVa81p3ltl6x7+sca729+8rlkn6XyS3wCWpUSZwSWrUUpZQNFzz2gXWdNa7XOdVAplnyWfR/U/DLXBJapQJXJIalT53OZM8DzwNvBN4obeOl8uQYwfjN/7hxj9N7O+uqnNXNvaawF/rNHmoqnb03vESGHLsYPzGP9z45xG7JRRJapQJXJIatagEvm9B/S6DIccOxm/8wzXz2BdSA5ckTc8SiiQ1qtcEnmRnksNJjia5sc++FyHJBUl+leSxJI8kuaFrPyfJfUmOdD/PXvRY5yXJpiS/S3JvNz2k2N+e5K4kj3frwEcGFv9XuvX+UJI7krx5I8ef5LYkJ5IcGmtbNd4kN3W58HCSz0zSZ28JPMkm4LvAVcAlwLVJLumr/wV5BfhqVb0PuBz4QhfzjcDBqtoOHOymN6obgMfGpocU+3eAn1XVe4EPMloOg4g/yVbgS8COqvoAsAnYzcaO/3Zg54q2k8bb5YHdwPu7eb7X5cjT0ucW+GXA0ap6sqpeAu4EdvXYf++q6nhV/bZ7/09G/8BbGcW9v/vYfuCahQxwzpJsAz4L3DLWPJTY3wZ8ArgVoKpeqqq/MZD4O5uBtyTZDJwJPMsGjr+q7gdeXNG8Wry7gDur6t9V9RRwlFGOPC19JvCtwDNj08e6tkFIciFwKfAAcH5VHYdRkgfOW+DQ5unbwNeA/4y1DSX29wDPAz/oSki3JDmLgcRfVX8Bvgn8GTgO/L2qfsFA4h+zWrwzyYd9JvCT3cJrEKfAJHkr8BPgy1X1j0WPpw9JPgecqKqHFz2WBdkMfBj4flVdCvyLjVUuWFNX690FXAS8CzgryXWLHdVSmUk+7DOBHwMuGJvexmiXakNL8kZGyfvHVXV31/xcki3d77cAJxY1vjn6GPD5JH9iVC77VJIfMYzYYbS+H6uqB7rpuxgl9KHE/2ngqap6vqpeBu4GPspw4n/VavHOJB/2mcAfBLYnuSjJmxgV8A/02H/vMrpx8K3AY1X1rbFfHQD2dO/3APf0PbZ5q6qbqmpbVV3I6G/9y6q6jgHEDlBVfwWeSXJx13QF8CgDiZ9R6eTyJGd2/wdXMDoGNJT4X7VavAeA3UnOSHIRsB34zWl/e1X19gKuBp4A/gjc3Gffi3gBH2e0W/QH4Pfd62rgHYyOSB/pfp6z6LHOeTl8Eri3ez+Y2IEPAQ91f/+fAmcPLP6vA48Dh4AfAmds5PiBOxjV+19mtIV9/VrxAjd3ufAwcNUkfXolpiQ1yisxJalRJnBJapQJXJIaZQKXpEaZwCWpUSZwSWqUCVySGmUCl6RG/RcBOe6mM5v0DAAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "show_tc(1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 79,
+ "id": "wired-albany",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "show_tc(2)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/test_bench/term_renderer_tb.v b/test_bench/term_renderer_tb.v
new file mode 100644
index 0000000..06af2e4
--- /dev/null
+++ b/test_bench/term_renderer_tb.v
@@ -0,0 +1,107 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 06/15/2021 10:49:32 AM
+// Design Name:
+// Module Name: window_matcher_tb
+// Project Name:
+// Target Devices:
+// Tool Versions:
+// Description:
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module term_renderer_tb();
+
+parameter GLYPHMEM_W = 256; /* glyphs */
+parameter GLYPHMEM_H = 128; /* glyphs */
+
+localparam period = 4;
+localparam REC_MAXLEN = 1000000;
+
+reg rst, clk;
+reg vsync, hsync;
+reg [15:0] glyphmem_data;
+wire [15:0] glyphmem_r_addr;
+wire [7:0] out_red;
+wire [7:0] out_green;
+wire [7:0] out_blue;
+
+initial begin
+ rst = 1;
+ clk = 0;
+ repeat(2) #period clk = ~clk;
+ rst = 0;
+ forever #period clk = ~clk;
+end
+
+reg [23:0] data_recording [0:100000];
+integer testcase_id;
+integer rec_pos;
+initial begin
+ `include "test_data/00TERM_RENDERER_TC_IDX.v"
+ $finish();
+end
+
+always @(posedge clk) begin
+ if (rst) begin
+ rec_pos <= 0;
+ for (integer i=0; i