aboutsummaryrefslogtreecommitdiff
path: root/design
diff options
context:
space:
mode:
Diffstat (limited to 'design')
-rw-r--r--design/div.v70
-rw-r--r--design/font.mem1795
-rw-r--r--design/intercon.v142
-rw-r--r--design/stack_machine.v353
-rw-r--r--design/vga.v241
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
+