diff options
author | Wojciech Kosior <kwojtus@protonmail.com> | 2020-09-01 10:54:59 +0200 |
---|---|---|
committer | Wojciech Kosior <kwojtus@protonmail.com> | 2020-09-01 11:04:22 +0200 |
commit | ee1f6c47e1eff920068f4bceaf604f9535a2e8a9 (patch) | |
tree | 580eb001a72601d254bb29cc348a529490f84808 /design | |
parent | cd02ddff8886aa1db29f80d3cc5cf99a349d8258 (diff) | |
download | AGH-engineering-thesis-ee1f6c47e1eff920068f4bceaf604f9535a2e8a9.tar.gz AGH-engineering-thesis-ee1f6c47e1eff920068f4bceaf604f9535a2e8a9.zip |
start anew
Diffstat (limited to 'design')
-rw-r--r-- | design/div.v | 70 | ||||
-rw-r--r-- | design/font.mem | 1795 | ||||
-rw-r--r-- | design/intercon.v | 142 | ||||
-rw-r--r-- | design/stack_machine.v | 353 | ||||
-rw-r--r-- | design/vga.v | 241 |
5 files changed, 2601 insertions, 0 deletions
diff --git a/design/div.v b/design/div.v new file mode 100644 index 0000000..10db627 --- /dev/null +++ b/design/div.v @@ -0,0 +1,70 @@ +`default_nettype none + +module div + #( + parameter WIDTH = 16 + ) + ( + input wire clock, + input wire start, + + input wire [WIDTH-1 : 0] dividend, + input wire [WIDTH-1 : 0] divisor, + + output wire [WIDTH-1 : 0] quotient, + output wire [WIDTH-1 : 0] remainder, + + output wire done + ); + + reg [$clog2(WIDTH)-1 : 0] steps; + reg [2*WIDTH : 0] work_reg; + reg [WIDTH-1 : 0] divisor_latched; + + wire [WIDTH+1 : 0] work_remainder; + wire work_remainder_sign; + assign work_remainder = work_reg[2*WIDTH : WIDTH-1]; + assign work_remainder_sign = work_remainder[WIDTH + 1]; + + /* + * The following variable represents quotient using digits 1 and -1, + * where -1 is internally represented as 0 + */ +`define MINUS_ONE 1'b0 +`define PLUS_ONE 1'b1 + + wire [WIDTH-1 : 0] work_quotient; + assign work_quotient = work_reg[WIDTH-1 : 0]; + + reg work_quotient_ready; + + always @ (posedge clock) begin + if (start) begin + steps <= WIDTH - 1; + work_reg <= dividend; + divisor_latched <= divisor; + work_quotient_ready <= 0; + end else begin + if (steps) + steps <= steps - 1; + else + work_quotient_ready <= 1; + + if (!work_quotient_ready) begin + work_reg[WIDTH-1 : 1] <= work_reg[WIDTH-2 : 0]; + + if (work_remainder_sign) begin /* work remainder negative */ + work_reg[0] <= `MINUS_ONE; /* Filling up quotient */ + work_reg[2*WIDTH : WIDTH] <= work_remainder + divisor_latched; + end else begin /* work remainder equal 0 or positive */ + work_reg[0] <= `PLUS_ONE; /* Filling up quotient */ + work_reg[2*WIDTH : WIDTH] <= work_remainder - divisor_latched; + end + end + end + end // always @ (posedge clock) + + assign quotient = work_quotient - ~work_quotient - work_remainder_sign; + assign remainder = (work_remainder >> 1) + (work_remainder_sign ? divisor_latched : 0); + assign done = work_quotient_ready && !start; +endmodule // div diff --git a/design/font.mem b/design/font.mem new file mode 100644 index 0000000..5e62f0e --- /dev/null +++ b/design/font.mem @@ -0,0 +1,1795 @@ +// all characters, that are not displayed, are shown as space + +// ASCII 0 - NULL (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 1 - SOH (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 2 - STX (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 3 - ETX (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 4 - EOT (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 5 - ENQ (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 6 - ACK (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 7 - BEL '\a' (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 8 - BS '\b' (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 9 - HT '\t' (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 10 - LF '\n' (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 11 - VT '\v' (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 12 - FF '\f' (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 13 - CR '\r' (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 14 - SO (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 15 - SI (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 16 - DLE (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 17 - DC1 (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 18 - DC2 (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 19 - DC3 (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 20 - DC4 (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 21 - NAK (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 22 - SYN (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 23 - ETB (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 24 - CAN (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 25 - EM (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 26 - SUB (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 27 - ESC (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 28 - FS (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 29 - GS (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 30 - US (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 31 - RS (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 32 - SPACE +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +// ASCII 33 - ! +00000000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000000 +00000000 +00001000 +00001000 +00000000 + +// ASCII 34 - " +00000000 +00010100 +00010100 +00010100 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 35 - # +00000000 +00010010 +00010010 +00010010 +00100100 +01111110 +00100100 +00100100 +00100100 +00100100 +01111110 +00100100 +01001000 +01001000 +01001000 +00000000 + +// ASCII 36 - $ +00000000 +00001000 +00011100 +00101010 +01001000 +01001000 +00101000 +00011000 +00001100 +00001010 +00001010 +00001010 +01001010 +00111100 +00001000 +00000000 + +// ASCII 37 - % +00000000 +00000000 +00100010 +01010010 +00100100 +00000100 +00001000 +00001000 +00010000 +00010000 +00100000 +00100100 +01001010 +01000100 +00000000 +00000000 + +// ASCII 38 - & +00000000 +00110000 +01001000 +01001000 +01001000 +01001000 +00110000 +00110000 +00010000 +00101000 +00101000 +01000100 +01000110 +01000100 +00111010 +00000000 + +// ASCII 39 - ' +00000000 +00001000 +00001000 +00001000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 40 - ( +00000000 +00000100 +00001000 +00001000 +00001000 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00001000 +00001000 +00001000 +00000100 +00000000 + +// ASCII 41 - ) +00000000 +00100000 +00010000 +00010000 +00010000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00010000 +00010000 +00010000 +00100000 +00000000 + +// ASCII 42 - * +00000000 +00101010 +00011100 +00101010 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 43 - + +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00111110 +00001000 +00001000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 44 - , +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00110000 +00000000 + +// ASCII 45 - - +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01111110 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 46 - . +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00000000 +00000000 + +// ASCII 47 - / +00000000 +00000010 +00000010 +00000100 +00000100 +00000100 +00001000 +00001000 +00010000 +00010000 +00100000 +00100000 +00100000 +01000000 +01000000 +00000000 + +// ASCII 48 - 0 +00000000 +00011000 +00100100 +00100100 +01000110 +01001010 +01001010 +01001010 +01010010 +01010010 +01010010 +01100010 +00100100 +00100100 +00011000 +00000000 + +// ASCII 49 - 1 +00000000 +00001000 +00011000 +00111000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000000 + +// ASCII 50 - 2 +00000000 +00111000 +01000100 +00000010 +00000010 +00000010 +00000010 +00000100 +00001000 +00010000 +00100000 +00100000 +01000000 +01000000 +01111110 +00000000 + +// ASCII 51 - 3 +00000000 +00111000 +01000100 +00000010 +00000010 +00000010 +00000100 +00011000 +00000100 +00000010 +00000010 +00000010 +00000010 +01000100 +00111000 +00000000 + +// ASCII 52 - 4 +00000000 +00001000 +00001000 +00010000 +00010000 +00100000 +00100000 +01000100 +01111110 +00000100 +00000100 +00000100 +00000100 +00000100 +00000100 +00000000 + +// ASCII 53 - 5 +00000000 +01111100 +01000000 +01000000 +01000000 +01000000 +01111000 +00000100 +00000010 +00000010 +00000010 +00000010 +00000010 +01000100 +00111000 +00000000 + +// ASCII 54 - 6 +00000000 +00001100 +00010000 +00100000 +00100000 +01000000 +01000000 +01011000 +01100100 +01000010 +01000010 +01000010 +01000010 +00100100 +00011000 +00000000 + +// ASCII 55 - 7 +00000000 +01111110 +00000010 +00000100 +00000100 +00001000 +00001000 +00111100 +00010000 +00010000 +00010000 +00100000 +00100000 +00100000 +00100000 +00000000 + +// ASCII 56 - 8 +00000000 +00011000 +00100100 +01000010 +01000010 +01000010 +00100100 +00011000 +00100100 +01000010 +01000010 +01000010 +01000010 +00100100 +00011000 +00000000 + +// ASCII 57 - 9 +00000000 +00011000 +00100100 +01000010 +01000010 +01000010 +01000010 +00100110 +00011010 +00000010 +00000010 +00000100 +00000100 +00001000 +00110000 +00000000 + +// ASCII 58 - : +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00000000 +00000000 + +// ASCII 59 - ; +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00110000 +00000000 + +// ASCII 60 - < +00000000 +00000000 +00000000 +00000010 +00000100 +00001000 +00010000 +00100000 +01000000 +00100000 +00010000 +00001000 +00000100 +00000010 +00000000 +00000000 + +// ASCII 61 - = +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01111110 +00000000 +00000000 +01111110 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 62 - > +00000000 +00000000 +00000000 +01000000 +00100000 +00010000 +00001000 +00000100 +00000010 +00000100 +00001000 +00010000 +00100000 +01000000 +00000000 +00000000 + +// ASCII 63 - ? +00000000 +00111100 +01000010 +00000010 +00000010 +00000100 +00001000 +00001000 +00001000 +00001000 +00000000 +00000000 +00001000 +00001000 +00000000 +00000000 + +// ASCII 64 - @ +00000000 +00000000 +00011000 +00100100 +01000010 +01000010 +01001110 +01010010 +01010010 +01010010 +01010010 +01011110 +01000000 +01000000 +00111100 +00000000 + +// ASCII 65 - A +00000000 +00011000 +00100100 +00100100 +00100100 +01000010 +01000010 +01000010 +01111110 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +00000000 + +// ASCII 66 - B +00000000 +01111000 +01000100 +01000010 +01000010 +01000010 +01000100 +01111000 +01000100 +01000010 +01000010 +01000010 +01000010 +01000100 +01111000 +00000000 + +// ASCII 67 - C +00000000 +00011100 +00100010 +00100000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +00100000 +00100010 +00011100 +00000000 + +// ASCII 68 - D +00000000 +01110000 +01001000 +01000100 +01000100 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000100 +01000100 +01001000 +01110000 +00000000 + +// ASCII 69 - E +00000000 +01111110 +01000000 +01000000 +01000000 +01000000 +01000000 +01111000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01111110 +00000000 + +// ASCII 70 - F +00000000 +01111110 +01000000 +01000000 +01000000 +01000000 +01000000 +01111000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +00000000 + +// ASCII 71 - G +00000000 +00011100 +00100010 +00100000 +01000000 +01000000 +01000000 +01000000 +01001110 +01000010 +01000010 +01000010 +00100010 +00100010 +00011110 +00000000 + +// ASCII 72 - H +00000000 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01111110 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +00000000 + +// ASCII 73 - I +00000000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000000 + +// ASCII 74 - J +00000000 +00011110 +00000010 +00000010 +00000010 +00000010 +00000010 +00000010 +00000010 +00000010 +00000010 +00000010 +00000010 +01000010 +00111100 +00000000 + +// ASCII 75 - K +00000000 +01000010 +01000100 +01000100 +01001000 +01001000 +01010000 +01010000 +01110000 +01001000 +01001000 +01000100 +01000100 +01000010 +01000010 +00000000 + +// ASCII 76 - L +00000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01111110 +00000000 + +// ASCII 77 - M +00000000 +01000010 +01000010 +01100110 +01011010 +01001010 +01001010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +00000000 + +// ASCII 78 - N +00000000 +01000010 +01100010 +01100010 +01010010 +01010010 +01010010 +01010010 +01001010 +01001010 +01001010 +01001010 +01000110 +01000110 +01000010 +00000000 + +// ASCII 79 - O +00000000 +00011000 +00100100 +00100100 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +00100100 +00100100 +00011000 +00000000 + +// ASCII 80 - P +00000000 +01111000 +01000100 +01000010 +01000010 +01000010 +01000100 +01111000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +00000000 + +// ASCII 81 - Q +00000000 +00011000 +00100100 +00100100 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01001010 +00101100 +00100100 +00011010 +00000000 + +// ASCII 82 - R +00000000 +01111000 +01000100 +01000010 +01000010 +01000010 +01000100 +01111000 +01001000 +01000100 +01000100 +01000100 +01000010 +01000010 +01000010 +00000000 + +// ASCII 83 - S +00000000 +00011100 +00100010 +01000000 +01000000 +01000000 +00100000 +00010000 +00001000 +00000100 +00000010 +00000010 +00000010 +01000010 +00111100 +00000000 + +// ASCII 84 - T +00000000 +00111110 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000000 + +// ASCII 85 - U +00000000 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +00111100 +00000000 + +// ASCII 86 - V +00000000 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +00100100 +00100100 +00100100 +00100100 +00100100 +00011000 +00011000 +00000000 + +// ASCII 87 - W +00000000 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01000010 +01001010 +01001010 +01001010 +01011010 +00100100 +00100100 +00100100 +00000000 + +// ASCII 88 - X +00000000 +01000010 +01000010 +00100100 +00100100 +00100100 +00011000 +00011000 +00011000 +00011000 +00100100 +00100100 +00100100 +01000010 +01000010 +00000000 + +// ASCII 89 - Y +00000000 +00100010 +00100010 +00100010 +00010100 +00010100 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000000 + +// ASCII 90 - Z +00000000 +01111110 +00000010 +00000010 +00000100 +00000100 +00001000 +00001000 +00010000 +00010000 +00100000 +00100000 +01000000 +01000000 +01111110 +00000000 + +// ASCII 91 - [ +00000000 +00011100 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00011100 +00000000 + +// ASCII 92 - \ +00000000 +01000000 +01000000 +00100000 +00100000 +00100000 +00010000 +00010000 +00001000 +00001000 +00000100 +00000100 +00000100 +00000010 +00000010 +00000000 + +// ASCII 93 - ] +00000000 +00111000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00111000 +00000000 + +// ASCII 94 - ^ +00000000 +00011000 +00100100 +01000010 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 95 - _ +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01111110 +00000000 + +// ASCII 96 - ` +00000000 +00110000 +00001100 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 97 - a +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00111100 +01000010 +00000010 +00011110 +00100010 +01000010 +01000110 +00111010 +00000000 + +// ASCII 98 - b +00000000 +00000000 +00000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01011100 +01100010 +01000010 +01000010 +01100010 +01011100 +00000000 + +// ASCII 99 - c +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00111100 +01000010 +01000000 +01000000 +01000010 +00111100 +00000000 + +// ASCII 100 - d +00000000 +00000000 +00000000 +00000010 +00000010 +00000010 +00000010 +00000010 +00000010 +00111010 +01000110 +01000010 +01000010 +01000110 +00111010 +00000000 + +// ASCII 101 - e +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00111100 +01000010 +01111110 +01000000 +01000010 +00111100 +00000000 + +// ASCII 102 - f +00000000 +00000000 +00000000 +00001100 +00010000 +00010000 +00010000 +00111100 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00010000 +00000000 + +// ASCII 103 - g +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00111010 +01000110 +01000010 +01000110 +00111010 +00000010 +00000010 +00111100 +00000000 + +// ASCII 104 - h +00000000 +00000000 +00000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01111100 +01000010 +01000010 +01000010 +01000010 +00000000 + +// ASCII 105 - i +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00000000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000000 + +// ASCII 106 - j +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00001000 +00001000 +00000000 +00111000 +00001000 +00001000 +00001000 +00110000 +00000000 + +// ASCII 107 - k +00000000 +00000000 +00000000 +01000000 +01000000 +01000000 +01000100 +01001000 +01010000 +01100000 +01010000 +01010000 +01001000 +01001000 +01000100 +00000000 + +// ASCII 108 - l +00000000 +00000000 +00000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +01000000 +00110000 +00000000 + +// ASCII 109 - m +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01100100 +01011010 +01011010 +01011010 +01011010 +01011010 +00000000 + +// ASCII 110 - n +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01011100 +01100010 +01000010 +01000010 +01000010 +00000000 + +// ASCII 111 - o +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00111100 +01000010 +01000010 +01000010 +01000010 +00111100 +00000000 + +// ASCII 112 - p +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01011100 +01100010 +01000010 +01000010 +01100010 +01011100 +01000000 +01000000 +00000000 + +// ASCII 113 - q +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00111010 +01000110 +01000010 +01000010 +01000110 +00111010 +00000010 +00000010 +00000000 + +// ASCII 114 - r +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00101100 +00110000 +00100000 +00100000 +00100000 +00100000 +00100000 +00000000 + +// ASCII 115 - s +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00111100 +01000010 +01000000 +00111100 +00000010 +01000010 +00111100 +00000000 + +// ASCII 116 - t +00000000 +00000000 +00000000 +00100000 +00100000 +01111000 +00100000 +00100000 +00100000 +00100000 +00100000 +00100000 +00100000 +00100000 +00011000 +00000000 + +// ASCII 117 - u +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01000010 +01000010 +01000010 +01000010 +01000110 +00111010 +00000000 + +// ASCII 118 - v +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01000010 +01000010 +00100100 +00100100 +00011000 +00011000 +00000000 + +// ASCII 119 - w +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01000010 +01000010 +01011010 +01011010 +00100100 +00100100 +00000000 + +// ASCII 120 - x +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01000010 +00100100 +00011000 +00011000 +00100100 +01000010 +00000000 + +// ASCII 121 - y +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00100010 +00100010 +00010010 +00001100 +00001000 +00110000 +00000000 + +// ASCII 122 - z +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01111110 +00000100 +00001000 +00010000 +00100000 +01111110 +00000000 + +// ASCII 123 - { +00000000 +00001100 +00010000 +00010000 +00010000 +00010000 +00010000 +00100000 +00100000 +00010000 +00010000 +00010000 +00010000 +00010000 +00001100 +00000000 + +// ASCII 123 - | +00000000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000000 +00000000 +00001000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000000 + +// ASCII 124 - } +00000000 +00110000 +00001000 +00001000 +00001000 +00001000 +00001000 +00000100 +00000100 +00001000 +00001000 +00001000 +00001000 +00001000 +00110000 +00000000 + +// ASCII 125 - ~ +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00110010 +01001100 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 + +// ASCII 127 - DEL (not displayed) +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/design/intercon.v b/design/intercon.v new file mode 100644 index 0000000..bf908af --- /dev/null +++ b/design/intercon.v @@ -0,0 +1,142 @@ +`default_nettype none + +module intercon + ( + input wire CLK, + input wire RST, + + input wire S0_ACK_O, + output wire S0_CLK_I, + output wire [17:0] S0_ADR_I, + output wire [15:0] S0_DAT_I, + input wire [15:0] S0_DAT_O, + output wire S0_RST_I, + output wire S0_STB_I, + output wire S0_WE_I, + input wire S0_STALL_O, + + input wire S1_ACK_O, + output wire S1_CLK_I, + output wire [17:0] S1_ADR_I, + output wire [15:0] S1_DAT_I, + input wire [15:0] S1_DAT_O, + output wire S1_RST_I, + output wire S1_STB_I, + output wire S1_WE_I, + input wire S1_STALL_O, + + input wire S2_ACK_O, + output wire S2_CLK_I, + output wire [17:0] S2_ADR_I, + output wire [15:0] S2_DAT_I, + input wire [15:0] S2_DAT_O, + output wire S2_RST_I, + output wire S2_STB_I, + output wire S2_WE_I, + input wire S2_STALL_O, + + input wire S3_ACK_O, + output wire S3_CLK_I, + output wire [17:0] S3_ADR_I, + output wire [15:0] S3_DAT_I, + input wire [15:0] S3_DAT_O, + output wire S3_RST_I, + output wire S3_STB_I, + output wire S3_WE_I, + input wire S3_STALL_O, + + output wire M_ACK_I, + output wire M_CLK_I, + input wire [19:0] M_ADR_O, + input wire [15:0] M_DAT_O, + output wire [15:0] M_DAT_I, + output wire M_RST_I, + input wire M_STB_O, + input wire M_CYC_O, + input wire M_WE_O, + output wire M_STALL_I + ); + + wire [0:3] acks; + wire [0:3] stalls; + wire [15:0] datas [0:3]; + assign acks = {S0_ACK_O, S1_ACK_O, S2_ACK_O, S3_ACK_O}; + assign stalls = {S0_STALL_O, S1_STALL_O, S2_STALL_O, S3_STALL_O}; + assign datas[0] = S0_DAT_O; + assign datas[1] = S1_DAT_O; + assign datas[2] = S2_DAT_O; + assign datas[3] = S3_DAT_O; + + reg [1:0] commands_awaiting; + reg [1:0] slave_last_accessed; + + wire operation_requested; + wire working; + wire [1:0] slave_accessed; + wire slave_switch; + wire [1:0] commands_awaiting_next_tick; + assign operation_requested = M_STB_O && M_CYC_O; + assign working = commands_awaiting || operation_requested; + assign slave_accessed = commands_awaiting ? slave_last_accessed : + M_ADR_O[19:18]; + assign M_ACK_I = acks[slave_accessed] && working; + assign M_DAT_I = datas[slave_accessed]; + assign slave_switch = slave_accessed != M_ADR_O[19:18]; + assign M_STALL_I = stalls[slave_accessed] || slave_switch || + (commands_awaiting == 3 && !M_ACK_I); + assign commands_awaiting_next_tick + = commands_awaiting - M_ACK_I + (operation_requested && !M_STALL_I); + +`ifdef SIMULATION + /* anything could be latched here, this is just to avoid undefined values */ + initial begin + slave_last_accessed <= 0; + commands_awaiting <= 2; /* It is supposed to be driven low by RST */ + end +`endif + + always @ (posedge CLK) begin + slave_last_accessed <= slave_accessed; + + if (RST) + commands_awaiting <= 0; + else + commands_awaiting <= commands_awaiting_next_tick; + end + + assign S0_CLK_I = CLK; + assign S1_CLK_I = CLK; + assign S2_CLK_I = CLK; + assign S3_CLK_I = CLK; + assign M_CLK_I = CLK; + + assign S0_RST_I = RST; + assign S1_RST_I = RST; + assign S2_RST_I = RST; + assign S3_RST_I = RST; + assign M_RST_I = RST; + + assign S0_ADR_I = M_ADR_O[17:0]; + assign S1_ADR_I = M_ADR_O[17:0]; + assign S2_ADR_I = M_ADR_O[17:0]; + assign S3_ADR_I = M_ADR_O[17:0]; + + assign S0_DAT_I = M_DAT_O; + assign S1_DAT_I = M_DAT_O; + assign S2_DAT_I = M_DAT_O; + assign S3_DAT_I = M_DAT_O; + + wire pass_strobe; + assign pass_strobe = operation_requested && !slave_switch && + (commands_awaiting != 3 || M_ACK_I); + + assign S0_STB_I = slave_accessed == 0 && pass_strobe; + assign S1_STB_I = slave_accessed == 1 && pass_strobe; + assign S2_STB_I = slave_accessed == 2 && pass_strobe; + assign S3_STB_I = slave_accessed == 3 && pass_strobe; + + assign S0_WE_I = M_WE_O; + assign S1_WE_I = M_WE_O; + assign S2_WE_I = M_WE_O; + assign S3_WE_I = M_WE_O; +endmodule // intercon diff --git a/design/stack_machine.v b/design/stack_machine.v new file mode 100644 index 0000000..1fddb18 --- /dev/null +++ b/design/stack_machine.v @@ -0,0 +1,353 @@ +`default_nettype none + +module stack_machine + ( + input wire ACK_I, + input wire CLK_I, + output reg [19:0] ADR_O, + input wire [15:0] DAT_I, + output reg [15:0] DAT_O, + input wire RST_I, + output reg STB_O, + output reg CYC_O, + output reg WE_O, + input wire STALL_I, + + /* non-wishbone */ + output wire finished + ); + + reg [19:0] pc; + reg [19:0] sp; + + reg [15:0] instr; + + reg [31:0] r0; + reg [31:0] r1; + reg [31:0] im; + + parameter STEP_START = 0; + parameter STEP_LOADING_INSTRUCTION = 1; + parameter STEP_PARSING_INSTRUCTION = 2; + parameter STEP_LOAD_OR_STORE = 3; + parameter STEP_PERFORM_OPERATION = 4; + reg [2:0] step; + + reg [15:0] DAT_I_latched; + reg [15:0] instruction_latched; + reg instruction_just_received; + wire [15:0] instruction; + assign instruction = instruction_just_received ? + DAT_I_latched : instruction_latched; + + /* Results of instruction parsing */ + wire shift_immediate; /* only if modify_immediate is true */ + assign shift_immediate = instruction[11]; + + /* only if shift_immediate is true */ + wire [10:0] immediate_bits_to_shift; + assign immediate_bits_to_shift = instruction[10:0]; + + /* only if shift_immediate is false */ + wire set_immediate; + assign set_immediate = instruction[10]; + + /* only if (set_immediate && !shift_immediate) is true */ + wire [31:0] immediate_value_to_set; + assign immediate_value_to_set = {{22{instruction[9]}}, instruction[9:0]}; + + /* only if (!set_immediate && !shift_immediate) is true */ + wire add_immediate; + assign add_immediate = instruction[9]; + + /* only if (add_immediate && !set_immediate && !shift_immediate) is true */ + wire [9:0] immediate_value_to_add; + assign immediate_value_to_add = instruction[8:0]; + + + wire [31:0] new_im; + assign new_im = shift_immediate ? {im[20:0], immediate_bits_to_shift} : + set_immediate ? immediate_value_to_set : + add_immediate ? im + immediate_value_to_add : im; + + + wire shift_regs; + assign shift_regs = instruction[12]; + + + wire load_or_store; + assign load_or_store = instruction[15]; + + wire [19:0] addr_to_use; /* only if load_or_store is true */ + /* The implementation is currently unable to make non-aligned accesses */ + assign addr_to_use = new_im / 2 + (immediate_addressing ? 0 : sp); + + wire load; /* only if load_or_store is true */ + assign load = instruction[14]; + + wire store; /* only if load_or_store is true */ + assign store = !load; + + wire immediate_addressing; /* only if load_or_store is true */ + assign immediate_addressing = instruction[13]; + wire sp_addressing; /* only if load_or_store is true */ + assign sp_addressing = !immediate_addressing; + + wire load_or_store_r0; /* only if load_or_store is true */ + assign load_or_store_r0 = instruction[12]; + + wire load_or_store_r1; /* only if load_or_store is true */ + assign load_or_store_r1 = !load_or_store_r0; + + + /* only if load_or_store is false */ + wire cond_jump; + assign cond_jump = instruction[14:13] == 2'b11; + + /* only if load_or_store is false */ + wire jump; + assign jump = instruction[14:13] == 2'b10; + + /* only if load_or_store is false */ + wire exchange_r1_im; + assign exchange_r1_im = instruction[14:13] == 2'b01; + + /* only if load_or_store is false */ + wire immediate_modification; + assign immediate_modification + = instruction[14:13] == 0 && + (shift_immediate || set_immediate || add_immediate); + + wire extended_instruction; /* only if load_or_store is false */ + assign extended_instruction = instruction[14:13] == 0 && ! shift_immediate && + !set_immediate && !add_immediate; + + /* only if (!load_or_store && extended_instruction) is true */ + wire [8:0] extended_instruction_bits; + assign extended_instruction_bits = instruction[8:0]; + + /* extended instructions */ + parameter INSTR_MUL = 9'd6; + parameter INSTR_DIV = 9'd5; + parameter INSTR_SUB = 9'd4; + parameter INSTR_ADD = 9'd3; + parameter INSTR_SET_SP = 9'd2; + parameter INSTR_HALT = 9'd1; + parameter INSTR_NOP = 9'd0; + + /* module for division */ + wire [31:0] div_quotient; + wire [31:0] div_remainder; + wire div_done; + + div + #( + .WIDTH(32) + ) div + ( + .clock(CLK_I), + .start(step == STEP_PARSING_INSTRUCTION), + .dividend(r0), + .divisor(r1), + + .quotient(div_quotient), + .remainder(div_remainder), + .done(div_done) + ); + + assign finished = !load_or_store && extended_instruction && + extended_instruction_bits == INSTR_HALT; + + + reg [15:0] second_word_to_store; + + /* + * Variables necessary to know where we are when transferring + * a sequence of words through wishbone + */ + reg first_command_sent; + reg first_ack_received; + + /* Informs us, that DAT_I_latched should be moved to r0 or r1 */ + reg load_half_of_r0; + reg load_half_of_r1; + +`ifdef SIMULATION + /* + * RST should still be used when powering up, even in benches; + * this is just to avoid undefined values + */ + initial begin + ADR_O <= 0; + STB_O <= 0; + CYC_O <= 0; + WE_O <= 0; + + r0 <= 0; + r1 <= 0; + im <= 0; + pc <= 0; + sp <= 20'h40000; + step <= STEP_START; + instruction_latched <= 0; + instruction_just_received <= 0; + end +`endif + + always @ (posedge CLK_I) begin + DAT_I_latched <= DAT_I; + + /* + * Later part of this always block sets them to 1 under certain + * conditions, which takes precedence over this assignment + */ + load_half_of_r0 <= 0; + load_half_of_r1 <= 0; + instruction_just_received <= 0; + + if (RST_I) begin + STB_O <= 0; + CYC_O <= 0; + + pc <= 0; + sp <= 20'h40000; + step <= STEP_START; + end else begin + case (step) + STEP_START : begin + ADR_O <= pc; + STB_O <= 1; + CYC_O <= 1; + WE_O <= 0; + step <= STEP_LOADING_INSTRUCTION; + pc <= pc + 1; + end + STEP_LOADING_INSTRUCTION : begin + if (!STALL_I) + STB_O <= 0; + + if (ACK_I) begin + instruction_just_received <= 1; + step <= STEP_PARSING_INSTRUCTION; + CYC_O <= 0; + end + end // case: STEP_LOADING_INSTRUCTION + STEP_PARSING_INSTRUCTION : begin + im <= new_im; + instruction_latched <= instruction; + + first_command_sent <= 0; + first_ack_received <= 0; + + if (shift_regs) + {r0, r1} <= {r1, r0}; /* magic! */ + + if (load_or_store) begin + CYC_O <= 1; + STB_O <= 1; + WE_O <= store; + ADR_O <= addr_to_use; + + /* Even if not a store, setting these won't break anything */ + DAT_O <= load_or_store_r0 ? r0[15:0] : r1[15:0]; + second_word_to_store <= load_or_store_r0 ? + r0[31:16] : r1[31:16]; + + if (load_or_store_r0) + sp <= sp + (load ? 2 : -2); + + step <= STEP_LOAD_OR_STORE; + end else begin // if (load_or_store) + if (immediate_modification) begin + step <= STEP_START; + end else if (exchange_r1_im || extended_instruction) begin + step <= STEP_PERFORM_OPERATION; + end else if (jump) begin + pc <= new_im / 2; + step <= STEP_START; + end else if (cond_jump) begin + if (r1 != 0) + pc <= new_im / 2; + + step <= STEP_START; + end else begin +`ifdef SIMULATION + $display("operation not implemented yet"); +`endif + step <= STEP_START; + end + end // else: !if(load_or_store) + end // case: STEP_PARSING_INSTRUCTION + STEP_LOAD_OR_STORE : begin + if (!STALL_I) begin + ADR_O <= ADR_O + 1; + + DAT_O <= second_word_to_store; + + if (!first_command_sent) + first_command_sent <= 1; + else + STB_O <= 0; + end // if (!STALL_I) + + if (ACK_I) begin + if (load) begin + if (load_or_store_r0) + load_half_of_r0 <= 1; + else + load_half_of_r1 <= 1; + end + + if (!first_ack_received) + first_ack_received <= 1; + else + step <= STEP_START; + end // if (ACK_I) + end // case: STEP_LOAD_OR_STORE + STEP_PERFORM_OPERATION : begin + step <= STEP_START; /* unless overwritten in case block below */ + + if (extended_instruction) begin + case (extended_instruction_bits) + INSTR_NOP : + ; + INSTR_HALT : + step <= step; /* stay in this step forever */ + INSTR_SET_SP : + sp <= im / 2; + INSTR_ADD : + r0 <= r0 + r1; + INSTR_SUB : + r0 <= r0 - r1; + INSTR_DIV : begin + {r0, r1} <= {div_quotient, div_remainder}; + if (!div_done) + step <= step; + end + INSTR_MUL : + r0 <= r0 * r1; + default : begin +`ifdef SIMULATION + $display("operation not implemented yet"); +`endif + end + endcase // case (extended_instruction_bits) + end else if (exchange_r1_im) begin + {r1, im} <= {im, r1}; + end else begin +`ifdef SIMULATION + $display("operation not implemented yet"); +`endif + end + end // case: STEP_PERFORM_OPERATION + endcase // case (step) + end // else: !if(RST_I) + + if (load_half_of_r0) + r0 <= {DAT_I_latched, r0[31:16]}; + + if (load_half_of_r1) + r1 <= {DAT_I_latched, r1[31:16]}; + end // always @ (posedge CLK_I) + +endmodule // stack_machine diff --git a/design/vga.v b/design/vga.v new file mode 100644 index 0000000..4b71b28 --- /dev/null +++ b/design/vga.v @@ -0,0 +1,241 @@ +`default_nettype none + + module vga + #( + parameter FONT_FILE = "font.mem" + ) + ( + output wire ACK_O, + input wire CLK_I, + input wire [10:0] ADR_I, + input wire [15:0] DAT_I, + output wire [15:0] DAT_O, + input wire RST_I, + input wire STB_I, + input wire WE_I, + output wire STALL_O, + + /* Non-wishbone */ + input wire clock_25mhz, + output reg h_sync, + output reg v_sync, + output reg [2:0] red, + output reg [2:0] green, + output reg [2:0] blue + ); + + reg powered_on; + + parameter LINES = V_ACTIVE_VIDEO / 16; /* 30 */ + parameter LINE_LENGTH = H_ACTIVE_VIDEO / 8; /* 80 */ + parameter CHARACTERS_ON_SCREEN = LINE_LENGTH * LINES; /* 2400 */ + + /* + * We want to store 2400 characters in memory. 2 chars go into one 16-bit + * word, so wee need a 1200x16 array. One embedded RAM block in iCE40 FPGAs + * is able to store 256x16 bits. This means, instead of choosing 1200 as + * array size, we can choose 1280, which is a multiple of 256. + */ + reg [15:0] text_memory [1279 : 0]; + + /* + * Enable writes to text_memory using wishbone interface. + * (no reads for now) + */ + + reg ack; + + assign DAT_O = {16{powered_on}}; + assign ACK_O = ack; + assign STALL_O = 1'b0; + + always @ (posedge CLK_I) begin + ack <= STB_I && !RST_I; + + if (STB_I && WE_I) begin + if (ADR_I < 1280) + text_memory[ADR_I] <= DAT_I; + else + powered_on <= DAT_I != 16'b0; + end + end + + /* Non-wishbone part - generate 640x480 60Hz VGA output */ + + reg powered_on_latched; + + always @ (posedge clock_25mhz) + powered_on_latched <= powered_on; + + parameter H_POLARITY = 1'b0; + parameter H_FRONT_PORCH = 8; + parameter H_SYNC = 96; + parameter H_BACK_PORCH = 40; + parameter H_LEFT_BORDER = 8; + parameter H_ACTIVE_VIDEO = 640; + parameter H_RIGHT_BORDER = 8; + + reg [9:0] h_counter; + + parameter H_STAGE_RB_OR_FP = 0; /* right border of front porch */ + parameter H_STAGE_SYNC = 1; + parameter H_STAGE_BP_OR_LB = 2; /* back porch or left border */ + parameter H_STAGE_ACTIVE_VIDEO = 3; + + reg [1:0] h_stage; + + always @ (posedge clock_25mhz) begin + if (powered_on_latched) begin + if ((h_stage == H_STAGE_RB_OR_FP && + h_counter + 1 == H_RIGHT_BORDER + H_FRONT_PORCH) || + (h_stage == H_STAGE_SYNC && + h_counter + 1 == H_SYNC) || + (h_stage == H_STAGE_BP_OR_LB && + h_counter + 1 == H_BACK_PORCH + H_LEFT_BORDER) || + (h_stage == H_STAGE_ACTIVE_VIDEO && + h_counter + 1 == H_ACTIVE_VIDEO)) begin + h_stage <= h_stage + 1; + h_counter <= 0; + end else begin // if ((h_stage == H_STAGE_RB_OR_FP &&... + h_counter <= h_counter + 1; + end + end else begin // if (powered_on_latched) + h_stage <= H_STAGE_RB_OR_FP; + h_counter <= H_RIGHT_BORDER; + end // else: !if(powered_on_latched) + end // always @ (posedge clock_25mhz) + + wire end_of_line; + assign end_of_line = h_stage == H_STAGE_RB_OR_FP && + h_counter + 1 == H_RIGHT_BORDER; + + parameter V_POLARITY = 1'b1; + parameter V_FRONT_PORCH = 2; + parameter V_SYNC = 2; + parameter V_BACK_PORCH = 25; + parameter V_TOP_BORDER = 8; + parameter V_ACTIVE_VIDEO = 480; + parameter V_BOTTOM_BORDER = 8; + + reg [8:0] v_counter; + + parameter V_STAGE_BB_OR_FP = 0; /* bottom border of front porch */ + parameter V_STAGE_SYNC = 1; + parameter V_STAGE_BP_OR_TB = 2; /* back porch or top border */ + parameter V_STAGE_ACTIVE_VIDEO = 3; + + reg [1:0] v_stage; + + always @ (posedge clock_25mhz) begin + if (powered_on_latched) begin + if (end_of_line) begin + if ((v_stage == V_STAGE_BB_OR_FP && + v_counter + 1 == V_BOTTOM_BORDER + V_FRONT_PORCH) || + (v_stage == V_STAGE_SYNC && + v_counter + 1 == V_SYNC) || + (v_stage == V_STAGE_BP_OR_TB && + v_counter + 1 == V_BACK_PORCH + V_TOP_BORDER) || + (v_stage == V_STAGE_ACTIVE_VIDEO && + v_counter + 1 == V_ACTIVE_VIDEO)) begin + v_stage <= v_stage + 1; + v_counter <= 0; + end else begin // if ((v_stage == V_STAGE_BB_OR_FP &&... + v_counter <= v_counter + 1; + end + end // if (end_of_line) + end else begin // if (powered_on_latched) + v_stage <= V_STAGE_BB_OR_FP; + v_counter <= V_BOTTOM_BORDER; + end // else: !if(powered_on_latched) + end // always @ (posedge clock_25mhz) + + reg [0:7] font [128 * 16 - 1 : 0]; + + initial begin + $readmemb(FONT_FILE, font, 0, 128 * 16 - 1); + end + + wire [6:0] char_x; + wire [4:0] char_y; + wire [12:0] char_flat_idx; + wire [15:0] text_memory_field; + wire [7:0] char; + assign char_x = h_counter / 8; + assign char_y = v_counter / 16; + assign char_flat_idx = char_x + char_y * LINE_LENGTH; + assign text_memory_field = text_memory[char_flat_idx[12:1]]; + assign char = char_flat_idx[0] ? + text_memory_field[15:8] : text_memory_field[7:0]; + + wire [0:7] replacement_char [0:16]; + assign replacement_char[0] = 8'b00000000; + assign replacement_char[1] = 8'b00011000; + assign replacement_char[2] = 8'b00111100; + assign replacement_char[3] = 8'b01100110; + assign replacement_char[4] = 8'b01011010; + assign replacement_char[5] = 8'b01111010; + assign replacement_char[6] = 8'b01111010; + assign replacement_char[7] = 8'b01111010; + assign replacement_char[8] = 8'b01110110; + assign replacement_char[9] = 8'b01101110; + assign replacement_char[10] = 8'b01101110; + assign replacement_char[11] = 8'b01111110; + assign replacement_char[12] = 8'b01101110; + assign replacement_char[13] = 8'b00111100; + assign replacement_char[14] = 8'b00011000; + assign replacement_char[15] = 8'b00000000; + + wire [2:0] char_pixel_x; + wire [3:0] char_pixel_y; + wire pixel_on; + wire display_on; + assign char_pixel_x = h_counter % 8; + assign char_pixel_y = v_counter % 16; + /* Replace non-ASCII characters (i.e. chars with values above 127) */ + assign pixel_on = char[7] ? replacement_char[char_pixel_y][char_pixel_x] : + font[char[6:0] * 16 + char_pixel_y][char_pixel_x]; + assign display_on = h_stage == H_STAGE_ACTIVE_VIDEO && + v_stage == V_STAGE_ACTIVE_VIDEO; + + parameter FG_COLOR = {3'b010, 3'b111, 3'b101}; + parameter BG_COLOR = {3'b000, 3'b000, 3'b111}; + + always @ (posedge clock_25mhz) begin + if (h_stage == H_STAGE_SYNC) + h_sync <= H_POLARITY; + else + h_sync <= ~H_POLARITY; + + if (v_stage == V_STAGE_SYNC) + v_sync <= V_POLARITY; + else + v_sync <= ~V_POLARITY; + + if (!display_on) + {red, green, blue} <= 9'b0; + else if (pixel_on) + {red, green, blue} <= FG_COLOR; + else + {red, green, blue} <= BG_COLOR; + end // always @ (posedge clock_25mhz) + +`ifdef SIMULATION + /* avoid undefined values */ + initial begin + powered_on <= 0; + powered_on_latched <= 0; + ack <= 0; + + h_sync <= ~H_POLARITY; + v_sync <= ~V_POLARITY; + {red, green, blue} <= 9'b0; + + h_counter <= 0; + h_stage <= H_STAGE_RB_OR_FP; + + v_counter <= 0; + v_stage <= V_STAGE_BB_OR_FP; + end +`endif +endmodule // vga + |