--- /dev/null
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+\r
+entity lcd is\r
+ port(\r
+ CLK : in std_logic;\r
+ RESET : in std_logic;\r
+ \r
+ MOSI : out std_logic;\r
+ SCK : out std_logic;\r
+ DC : out std_logic;\r
+ CS : out std_logic;\r
+ RST : out std_logic;\r
+ \r
+ INPUT: in std_logic_vector(255 downto 0);\r
+ LED : out std_logic_vector(3 downto 0)\r
+ \r
+ );\r
+end entity;\r
+\r
+\r
+\r
+architecture base of lcd is\r
+-- Font size in bytes : 2002\r
+-- Font width : 10\r
+-- Font height : 16\r
+-- Font first char : 0x20\r
+-- Font last char : 0x7E\r
+type fontram_t is array (0 to 2047) of std_logic_vector(7 downto 0);\r
+constant fontram : fontram_t := ( \r
+ x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", \r
+ x"00", x"00", x"00", x"00",\r
+ x"00", x"00", x"00", x"00", x"00", x"00", x"FF", x"33", x"FF", x"33", x"FF", x"33", x"00", x"00", x"00", x"00", \r
+ x"00", x"00", x"00", x"00", x"00", x"00", x"1F", x"00", x"1F", x"00", x"1F", x"00", x"00", x"00", x"00", x"00", \r
+ x"1F", x"00", x"1F", x"00", x"1F", x"00", x"00", x"00", x"00", x"32", x"20", x"3F", x"F8", x"0F", x"FE", x"02", \r
+ x"26", x"32", x"A0", x"3F", x"F8", x"0F", x"7E", x"02", x"26", x"02", x"20", x"00", x"38", x"30", x"7C", x"70", \r
+ x"FE", x"60", x"C6", x"60", x"FF", x"FF", x"FF", x"FF", x"06", x"63", x"06", x"3F", x"04", x"1C", x"00", x"00", \r
+ x"3C", x"60", x"7E", x"38", x"42", x"1C", x"7E", x"0E", x"FE", x"3F", x"FC", x"7F", x"70", x"7E", x"38", x"42", \r
+ x"1C", x"7E", x"06", x"3C", x"00", x"1E", x"00", x"3F", x"BC", x"7F", x"FE", x"71", x"FE", x"63", x"E6", x"67", \r
+ x"3E", x"7F", x"1C", x"7C", x"00", x"7F", x"00", x"47", x"00", x"00", x"00", x"00", x"00", x"00", x"1F", x"00", \r
+ x"1F", x"00", x"1F", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"C0", x"03", \r
+ x"F0", x"0F", x"FC", x"3F", x"3E", x"7C", x"0E", x"70", x"07", x"E0", x"03", x"C0", x"03", x"C0", x"00", x"00", \r
+ x"00", x"00", x"03", x"C0", x"03", x"C0", x"07", x"E0", x"0E", x"70", x"3E", x"7C", x"FC", x"3F", x"F0", x"0F", \r
+ x"C0", x"03", x"00", x"00", x"18", x"00", x"98", x"00", x"D8", x"01", x"DE", x"01", x"4E", x"00", x"DE", x"01", \r
+ x"D8", x"01", x"98", x"00", x"18", x"00", x"00", x"00", x"00", x"00", x"00", x"03", x"00", x"03", x"00", x"03", \r
+ x"F0", x"3F", x"F0", x"3F", x"F0", x"3F", x"00", x"03", x"00", x"03", x"00", x"03", x"00", x"00", x"00", x"4E", \r
+ x"00", x"7E", x"00", x"7E", x"00", x"1E", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", \r
+ x"00", x"00", x"80", x"01", x"80", x"01", x"80", x"01", x"80", x"01", x"80", x"01", x"80", x"01", x"80", x"01", \r
+ x"80", x"01", x"00", x"00", x"00", x"00", x"00", x"38", x"00", x"38", x"00", x"38", x"00", x"38", x"00", x"00", \r
+ x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"60", x"00", x"78", x"00", x"7F", \r
+ x"E0", x"1F", x"F8", x"07", x"FE", x"00", x"1E", x"00", x"06", x"00", x"00", x"00", x"F0", x"0F", x"F8", x"1F", \r
+ x"FC", x"3F", x"1E", x"78", x"06", x"60", x"06", x"60", x"1E", x"78", x"FC", x"3F", x"FC", x"1F", x"F0", x"0F", \r
+ x"00", x"60", x"18", x"60", x"1C", x"60", x"0C", x"60", x"FE", x"7F", x"FE", x"7F", x"FE", x"7F", x"00", x"60", \r
+ x"00", x"60", x"00", x"60", x"0C", x"70", x"0E", x"78", x"06", x"7C", x"06", x"6E", x"06", x"67", x"8E", x"63", \r
+ x"FE", x"61", x"FC", x"60", x"78", x"60", x"00", x"60", x"00", x"00", x"0C", x"60", x"CE", x"60", x"C6", x"60", \r
+ x"C6", x"60", x"E6", x"71", x"FE", x"7F", x"BE", x"3F", x"1C", x"1E", x"00", x"00", x"00", x"06", x"80", x"07", \r
+ x"C0", x"07", x"E0", x"06", x"78", x"06", x"1C", x"06", x"FE", x"7F", x"FE", x"7F", x"FE", x"7F", x"00", x"06", \r
+ x"00", x"00", x"FE", x"60", x"FE", x"60", x"FE", x"60", x"C6", x"60", x"C6", x"71", x"C6", x"7F", x"86", x"3F", \r
+ x"06", x"1F", x"06", x"0E", x"E0", x"0F", x"F8", x"3F", x"FC", x"3F", x"9E", x"71", x"CE", x"60", x"C6", x"60", \r
+ x"C6", x"71", x"C6", x"7F", x"84", x"3F", x"00", x"1F", x"06", x"00", x"06", x"60", x"06", x"7C", x"06", x"7F", \r
+ x"C6", x"1F", x"F6", x"03", x"FE", x"00", x"3E", x"00", x"0E", x"00", x"06", x"00", x"00", x"1E", x"3C", x"3F", \r
+ x"7C", x"7F", x"FE", x"71", x"E6", x"61", x"C6", x"61", x"FE", x"73", x"7E", x"7F", x"3C", x"3F", x"00", x"1E", \r
+ x"F8", x"00", x"FC", x"21", x"FE", x"63", x"8E", x"63", x"06", x"63", x"06", x"73", x"8E", x"79", x"FC", x"3F", \r
+ x"FC", x"1F", x"F0", x"07", x"00", x"00", x"00", x"00", x"00", x"00", x"38", x"1C", x"38", x"1C", x"38", x"1C", \r
+ x"38", x"1C", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"38", x"9C", x"38", x"FC", x"38", x"FC", \r
+ x"38", x"3C", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"80", x"01", x"80", x"01", \r
+ x"C0", x"03", x"E0", x"07", x"60", x"06", x"70", x"0E", x"30", x"0C", x"38", x"1C", x"18", x"18", x"18", x"18", \r
+ x"30", x"03", x"30", x"03", x"30", x"03", x"30", x"03", x"30", x"03", x"30", x"03", x"30", x"03", x"30", x"03", \r
+ x"30", x"03", x"30", x"03", x"18", x"18", x"18", x"18", x"38", x"1C", x"30", x"0C", x"70", x"0E", x"60", x"06", \r
+ x"E0", x"07", x"C0", x"03", x"80", x"01", x"80", x"01", x"0E", x"00", x"0E", x"00", x"06", x"00", x"06", x"66", \r
+ x"06", x"67", x"86", x"67", x"CE", x"01", x"FE", x"00", x"7C", x"00", x"3C", x"00", x"F0", x"0F", x"FC", x"3F", \r
+ x"1C", x"38", x"C6", x"67", x"E2", x"4F", x"32", x"4C", x"36", x"4C", x"3E", x"6C", x"FC", x"6F", x"F8", x"0F", \r
+ x"00", x"38", x"80", x"3F", x"E0", x"1F", x"FC", x"07", x"3C", x"06", x"3C", x"06", x"FC", x"07", x"E0", x"1F", \r
+ x"80", x"3F", x"00", x"38", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"8C", x"31", x"8C", x"31", x"8C", x"31", \r
+ x"CC", x"33", x"FC", x"3F", x"78", x"1F", x"78", x"1E", x"E0", x"07", x"F0", x"0F", x"F8", x"1F", x"38", x"1C", \r
+ x"1C", x"38", x"0C", x"30", x"0C", x"30", x"0C", x"30", x"1C", x"30", x"18", x"10", x"FC", x"3F", x"FC", x"3F", \r
+ x"FC", x"3F", x"0C", x"30", x"0C", x"30", x"1C", x"38", x"3C", x"3C", x"F8", x"1F", x"F8", x"0F", x"E0", x"07", \r
+ x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"8C", x"31", x"8C", x"31", x"8C", x"31", x"8C", x"31", x"8C", x"31", \r
+ x"0C", x"30", x"0C", x"30", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"8C", x"01", x"8C", x"01", x"8C", x"01", \r
+ x"8C", x"01", x"8C", x"01", x"0C", x"00", x"0C", x"00", x"E0", x"07", x"F0", x"0F", x"F8", x"1F", x"38", x"1C", \r
+ x"1C", x"38", x"0C", x"30", x"8C", x"31", x"8C", x"31", x"9C", x"3F", x"98", x"1F", x"FC", x"3F", x"FC", x"3F", \r
+ x"FC", x"3F", x"80", x"01", x"80", x"01", x"80", x"01", x"80", x"01", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", \r
+ x"0C", x"30", x"0C", x"30", x"0C", x"30", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"0C", x"30", x"0C", x"30", \r
+ x"0C", x"30", x"00", x"00", x"00", x"00", x"00", x"30", x"0C", x"30", x"0C", x"30", x"0C", x"30", x"0C", x"38", \r
+ x"FC", x"3F", x"FC", x"1F", x"FC", x"0F", x"00", x"00", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"C0", x"03", \r
+ x"E0", x"07", x"78", x"0F", x"3C", x"1E", x"1C", x"3C", x"0C", x"38", x"04", x"30", x"FC", x"3F", x"FC", x"3F", \r
+ x"FC", x"3F", x"00", x"30", x"00", x"30", x"00", x"30", x"00", x"30", x"00", x"30", x"00", x"30", x"00", x"00", \r
+ x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"F8", x"00", x"F0", x"07", x"C0", x"07", x"E0", x"07", x"F8", x"00", \r
+ x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"F8", x"00", x"F0", x"03", x"C0", x"0F", \r
+ x"00", x"1F", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"E0", x"07", x"F8", x"1F", x"F8", x"1F", x"1C", x"38", \r
+ x"0C", x"30", x"0C", x"30", x"1C", x"38", x"F8", x"1F", x"F8", x"1F", x"E0", x"07", x"FC", x"3F", x"FC", x"3F", \r
+ x"FC", x"3F", x"8C", x"01", x"8C", x"01", x"8C", x"01", x"CC", x"01", x"FC", x"01", x"F8", x"00", x"78", x"00", \r
+ x"E0", x"07", x"F8", x"0F", x"F8", x"1F", x"1C", x"38", x"0C", x"30", x"0C", x"70", x"1C", x"F8", x"F8", x"DF", \r
+ x"F8", x"CF", x"E0", x"87", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"8C", x"01", x"8C", x"03", x"CC", x"07", \r
+ x"FC", x"1F", x"FC", x"3E", x"78", x"38", x"00", x"30", x"78", x"18", x"F8", x"38", x"FC", x"38", x"CC", x"30", \r
+ x"8C", x"31", x"8C", x"31", x"8C", x"33", x"1C", x"3F", x"18", x"1F", x"00", x"0E", x"00", x"00", x"0C", x"00", \r
+ x"0C", x"00", x"0C", x"00", x"FC", x"3F", x"FC", x"3F", x"FC", x"3F", x"0C", x"00", x"0C", x"00", x"0C", x"00", \r
+ x"FC", x"0F", x"FC", x"1F", x"FC", x"3F", x"00", x"38", x"00", x"30", x"00", x"30", x"00", x"38", x"FC", x"3F", \r
+ x"FC", x"1F", x"FC", x"0F", x"0C", x"00", x"FC", x"00", x"F8", x"03", x"E0", x"1F", x"80", x"3F", x"00", x"3C", \r
+ x"80", x"3F", x"E0", x"1F", x"FC", x"03", x"3C", x"00", x"00", x"00", x"FC", x"07", x"FC", x"1F", x"00", x"3F", \r
+ x"C0", x"1F", x"E0", x"07", x"C0", x"1F", x"00", x"3F", x"FC", x"1F", x"FC", x"07", x"00", x"00", x"0C", x"30", \r
+ x"1C", x"38", x"78", x"1E", x"E0", x"07", x"C0", x"03", x"E0", x"07", x"78", x"1E", x"1C", x"38", x"0C", x"30", \r
+ x"00", x"00", x"1C", x"00", x"7C", x"00", x"F0", x"00", x"E0", x"3F", x"80", x"3F", x"E0", x"3F", x"F0", x"00", \r
+ x"7C", x"00", x"1C", x"00", x"0C", x"38", x"0C", x"3C", x"0C", x"3E", x"0C", x"3F", x"8C", x"37", x"CC", x"33", \r
+ x"EC", x"31", x"FC", x"30", x"7C", x"30", x"1C", x"30", x"00", x"00", x"00", x"00", x"FF", x"FF", x"FF", x"FF", \r
+ x"FF", x"FF", x"03", x"C0", x"03", x"C0", x"03", x"C0", x"03", x"C0", x"00", x"00", x"00", x"00", x"07", x"00", \r
+ x"1F", x"00", x"FF", x"00", x"F8", x"07", x"E0", x"1F", x"00", x"FF", x"00", x"F8", x"00", x"E0", x"00", x"00", \r
+ x"00", x"00", x"03", x"C0", x"03", x"C0", x"03", x"C0", x"03", x"C0", x"FF", x"FF", x"FF", x"FF", x"FF", x"FF", \r
+ x"00", x"00", x"00", x"00", x"00", x"00", x"80", x"01", x"E0", x"01", x"FC", x"00", x"1E", x"00", x"1E", x"00", \r
+ x"FC", x"00", x"E0", x"01", x"80", x"01", x"00", x"00", x"00", x"C0", x"00", x"C0", x"00", x"C0", x"00", x"C0", \r
+ x"00", x"C0", x"00", x"C0", x"00", x"C0", x"00", x"C0", x"00", x"C0", x"00", x"C0", x"00", x"00", x"00", x"00", \r
+ x"00", x"00", x"02", x"00", x"06", x"00", x"06", x"00", x"04", x"00", x"00", x"00", x"00", x"00", x"00", x"00", \r
+ x"00", x"1C", x"60", x"3E", x"70", x"3F", x"30", x"33", x"30", x"31", x"30", x"39", x"F0", x"1F", x"F0", x"3F", \r
+ x"E0", x"3F", x"00", x"30", x"FE", x"3F", x"FE", x"3F", x"FE", x"3F", x"60", x"38", x"30", x"30", x"30", x"30", \r
+ x"70", x"38", x"F0", x"3F", x"E0", x"1F", x"C0", x"07", x"80", x"07", x"E0", x"1F", x"E0", x"1F", x"70", x"38", \r
+ x"30", x"38", x"30", x"30", x"30", x"30", x"30", x"30", x"30", x"30", x"20", x"10", x"80", x"0F", x"E0", x"1F", \r
+ x"F0", x"3F", x"70", x"38", x"30", x"30", x"30", x"30", x"70", x"38", x"FE", x"3F", x"FE", x"3F", x"FE", x"3F", \r
+ x"80", x"0F", x"E0", x"1F", x"E0", x"1F", x"70", x"3B", x"30", x"33", x"30", x"33", x"70", x"33", x"F0", x"33", \r
+ x"E0", x"3B", x"C0", x"1B", x"60", x"00", x"60", x"00", x"60", x"00", x"FC", x"3F", x"FE", x"3F", x"FF", x"3F", \r
+ x"63", x"00", x"63", x"00", x"63", x"00", x"63", x"00", x"80", x"0F", x"E0", x"4F", x"F0", x"DF", x"70", x"DC", \r
+ x"30", x"D8", x"30", x"D8", x"70", x"D8", x"F0", x"FF", x"F0", x"FF", x"F0", x"7F", x"FE", x"3F", x"FE", x"3F", \r
+ x"FE", x"3F", x"60", x"00", x"70", x"00", x"30", x"00", x"30", x"00", x"F0", x"3F", x"F0", x"3F", x"E0", x"3F", \r
+ x"00", x"00", x"30", x"00", x"30", x"00", x"30", x"00", x"30", x"00", x"F3", x"3F", x"F3", x"3F", x"F3", x"3F", \r
+ x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"60", x"30", x"E0", x"30", x"C0", x"30", x"C0", x"30", x"C0", \r
+ x"F3", x"FF", x"F3", x"7F", x"F3", x"3F", x"00", x"00", x"FE", x"3F", x"FE", x"3F", x"FE", x"3F", x"80", x"07", \r
+ x"E0", x"0F", x"F0", x"1F", x"70", x"3C", x"30", x"38", x"10", x"30", x"00", x"20", x"00", x"00", x"06", x"00", \r
+ x"06", x"00", x"06", x"00", x"06", x"00", x"FE", x"3F", x"FE", x"3F", x"FE", x"3F", x"00", x"00", x"00", x"00", \r
+ x"F0", x"3F", x"F0", x"3F", x"F0", x"3F", x"70", x"00", x"F0", x"3F", x"E0", x"3F", x"70", x"00", x"F0", x"3F", \r
+ x"F0", x"3F", x"E0", x"3F", x"F0", x"3F", x"F0", x"3F", x"F0", x"3F", x"60", x"00", x"70", x"00", x"30", x"00", \r
+ x"30", x"00", x"F0", x"3F", x"F0", x"3F", x"E0", x"3F", x"80", x"07", x"E0", x"1F", x"E0", x"1F", x"70", x"38", \r
+ x"30", x"30", x"30", x"30", x"70", x"38", x"E0", x"1F", x"E0", x"1F", x"80", x"07", x"F0", x"FF", x"F0", x"FF", \r
+ x"F0", x"FF", x"70", x"1C", x"30", x"18", x"30", x"18", x"70", x"1C", x"F0", x"1F", x"E0", x"0F", x"C0", x"07", \r
+ x"80", x"07", x"E0", x"0F", x"F0", x"1F", x"70", x"1C", x"30", x"18", x"30", x"18", x"70", x"1C", x"F0", x"FF", \r
+ x"F0", x"FF", x"F0", x"FF", x"00", x"00", x"F0", x"3F", x"F0", x"3F", x"F0", x"3F", x"70", x"00", x"30", x"00", \r
+ x"30", x"00", x"70", x"00", x"70", x"00", x"00", x"00", x"E0", x"18", x"F0", x"39", x"F0", x"31", x"B0", x"33", \r
+ x"30", x"33", x"30", x"33", x"30", x"3F", x"30", x"1E", x"00", x"1C", x"00", x"00", x"30", x"00", x"30", x"00", \r
+ x"30", x"00", x"FC", x"1F", x"FC", x"3F", x"FC", x"3F", x"30", x"30", x"30", x"30", x"30", x"30", x"30", x"30", \r
+ x"F0", x"1F", x"F0", x"3F", x"F0", x"3F", x"00", x"30", x"00", x"30", x"00", x"38", x"00", x"18", x"F0", x"3F", \r
+ x"F0", x"3F", x"F0", x"3F", x"10", x"00", x"F0", x"00", x"F0", x"03", x"E0", x"1F", x"00", x"3F", x"00", x"3C", \r
+ x"C0", x"3F", x"F0", x"0F", x"F0", x"01", x"30", x"00", x"30", x"00", x"F0", x"0F", x"E0", x"3F", x"00", x"1E", \r
+ x"C0", x"03", x"C0", x"03", x"00", x"1E", x"E0", x"3F", x"F0", x"0F", x"30", x"00", x"10", x"20", x"30", x"30", \r
+ x"F0", x"3C", x"F0", x"1F", x"C0", x"07", x"C0", x"0F", x"E0", x"3F", x"F0", x"3C", x"30", x"30", x"10", x"20", \r
+ x"10", x"00", x"F0", x"00", x"F0", x"C3", x"E0", x"CF", x"00", x"FF", x"00", x"7F", x"C0", x"0F", x"F0", x"01", \r
+ x"F0", x"00", x"10", x"00", x"30", x"30", x"30", x"38", x"30", x"3C", x"30", x"3E", x"30", x"37", x"B0", x"33", \r
+ x"F0", x"31", x"F0", x"30", x"70", x"30", x"30", x"30", x"00", x"00", x"80", x"01", x"80", x"01", x"FE", x"7F", \r
+ x"FF", x"FF", x"7F", x"FE", x"03", x"C0", x"03", x"C0", x"03", x"C0", x"00", x"00", x"00", x"00", x"00", x"00", \r
+ x"00", x"00", x"FF", x"FF", x"FF", x"FF", x"FF", x"FF", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", \r
+ x"00", x"00", x"03", x"C0", x"03", x"C0", x"03", x"C0", x"7F", x"FE", x"FF", x"FF", x"FE", x"7F", x"80", x"01", \r
+ x"80", x"01", x"00", x"00", x"00", x"03", x"80", x"03", x"80", x"01", x"80", x"01", x"80", x"03", x"80", x"03", \r
+ x"00", x"03", x"00", x"03", x"80", x"03", x"80", x"01", others => x"00");\r
+\r
+ type initdc_t is array (0 to 15) of std_logic;\r
+ constant initdc : initdc_t := ('0','1','0','1','0','0','1','1','1','1','0','1','1','1','1','0');\r
+\r
+ type data_t is array (0 to 1023) of std_logic_vector(7 downto 0);\r
+ constant dataram : data_t := (\r
+ x"36",x"48",x"3A",x"55",x"29",x"2A",x"00",x"00",\r
+ x"00",x"EF",x"2B",x"00",x"00",x"01",x"3F",x"2C",\r
+ x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",\r
+ x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",\r
+\r
+ \r
+ x"50", x"61", x"64", x"69", x"77", x"61", x"20", x"53", x"74", x"61", x"74", x"75", x"73", x"0a", \r
+ x"0a", \r
+ x"54", x"65", x"6d", x"70", x"65", x"72", x"61", x"74", x"75", x"72", x"65", x"20", x"20", x"20", x"20", x"20", x"20", x"84", x"0a", \r
+ x"55", x"49", x"44", x"20", x"20", x"83", x"82", x"81", x"80", x"0a",\r
+ x"45", x"6e", x"61", x"62", x"6c", x"65", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"85", x"0a", \r
+ x"49", x"6e", x"76", x"65", x"72", x"74", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"86", x"0a",\r
+ x"49", x"6e", x"70", x"75", x"74", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20",x"20", x"87", x"0a", \r
+ x"0a",\r
+ x"54", x"69", x"6d", x"65", x"72", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"20", x"8F", x"8E", x"0a",\r
+ others => x"00");\r
+ \r
+ \r
+ signal timer : unsigned(27 downto 0) := (others => '0');\r
+ --2**16: 2.5ms\r
+ --2**20: 40ms\r
+ \r
+ type state_t is (RSTIDLE, RSTRESET, RSTWAIT, RSTSELECT, \r
+ RSTCONFIG1, RSTCONFIG2, RSTCONFIG3, RSTCONFIG4, \r
+ RSTCONFIG5, RSTCLEAR, RSTCLEAR2, RSTFINISH, WAITSTART,\r
+ TSTART, WAITFONT, WRITEFONT, SETWINDOW,\r
+ WRITEWAIT, WRITESECONDBYTE, GETNIBBLE, \r
+ GETHEX, NEXTCHAR);\r
+ type spistate_t is (SPIIDLE, SPISEND1, SPISEND2, SPISEND3, SPISEND4);\r
+\r
+ signal state : state_t;\r
+ signal spistate : spistate_t; \r
+\r
+ signal cnt : integer range 0 to 200000 := 0; --general purpose counter\r
+ signal datapos : integer range 0 to 1023; --pointer in data ROM\r
+ signal fontpos : integer range 0 to 2047; --pointer in font ROM\r
+ \r
+ signal spi_data : std_logic_vector(7 downto 0);\r
+ signal spi_dc : std_logic;\r
+ signal spi_send : std_logic;\r
+ signal spi_idle : std_logic;\r
+ signal spi_busy : std_logic;\r
+ signal spi_cnt : integer range 0 to 7 := 0;\r
+ signal spi_buf : std_logic_vector(7 downto 0);\r
+ \r
+ signal poscol : integer range 0 to 239 := 0; --horizontal position\r
+ signal posrow : integer range 0 to 19 := 0; --vertical position in 16px steps\r
+ \r
+ signal curdata : std_logic_vector(7 downto 0); --current byte in data ROM\r
+ signal curfont : std_logic_vector(7 downto 0); --curent font byte\r
+ signal nibble : unsigned (7 downto 0); --var. nibble to show\r
+ signal varcnt : integer range 0 to 4 := 0; --position within variable\r
+ \r
+ signal pixcnt : integer range 0 to 15 := 0; --Pixel count when plotting fonts\r
+ signal bytecnt : integer range 0 to 1 := 0; --high or low byte when plotting fonts\r
+ signal colcnt : integer range 0 to 15 := 0; --number of cols in current char\r
+ \r
+begin\r
+\r
+spi_idle <= not spi_busy and not spi_send;\r
+\r
+\r
+spi_fsm : process begin\r
+ wait until rising_edge(CLK);\r
+ case spistate is\r
+ when SPIIDLE =>\r
+ MOSI <= '0';\r
+ SCK <= '0';\r
+ spi_busy <= '0';\r
+ if spi_send = '1' then\r
+ spistate <= SPISEND1;\r
+ spi_buf <= spi_data;\r
+ spi_busy <= '1';\r
+ spi_cnt <= 7;\r
+ DC <= spi_dc;\r
+ end if;\r
+ when SPISEND1 => \r
+ spistate <= SPISEND2;\r
+ SCK <= '0';\r
+ MOSI <= spi_buf(spi_cnt);\r
+ when SPISEND2 => \r
+ spistate <= SPISEND3;\r
+ SCK <= '0';\r
+ MOSI <= spi_buf(spi_cnt);\r
+ when SPISEND3 => \r
+ spistate <= SPISEND4;\r
+ SCK <= '1';\r
+ MOSI <= spi_buf(spi_cnt);\r
+ when SPISEND4 => \r
+ SCK <= '1';\r
+ MOSI <= spi_buf(spi_cnt);\r
+ if spi_cnt = 0 then\r
+ spistate <= SPIIDLE;\r
+ else\r
+ spistate <= SPISEND1;\r
+ spi_cnt <= spi_cnt - 1;\r
+ end if;\r
+ end case;\r
+ if RESET = '1' then\r
+ spistate <= SPIIDLE;\r
+ end if;\r
+end process;\r
+\r
+\r
+fsm : process begin\r
+ wait until rising_edge(CLK);\r
+ timer <= timer + 1;\r
+ RST <= '1';\r
+ CS <= '0';\r
+ spi_send <= '0';\r
+ LED(0) <= '1';\r
+ case state is\r
+-------------------------------------------------------------- \r
+-- Reset sequence\r
+-------------------------------------------------------------- \r
+ when RSTIDLE =>\r
+ RST <= '1';\r
+ CS <= '1';\r
+ if timer = x"4000000" then --2500ms\r
+ state <= RSTRESET;\r
+ timer <= (others => '0');\r
+ end if; \r
+ when RSTRESET =>\r
+ RST <= '0';\r
+ CS <= '1';\r
+ if timer = x"0300000" then --120ms\r
+ state <= RSTWAIT;\r
+ timer <= (others => '0');\r
+ end if; \r
+ when RSTWAIT =>\r
+ RST <= '1';\r
+ CS <= '1';\r
+ if timer = x"0300000" then --120ms\r
+ state <= RSTSELECT;\r
+ timer <= (others => '0');\r
+ end if; \r
+ when RSTSELECT =>\r
+ if timer = x"000000F" then --short...\r
+ state <= RSTCONFIG1;\r
+ spi_data <= x"11";\r
+ spi_dc <= '0';\r
+ spi_send <= '1';\r
+ timer <= (others => '0');\r
+ end if;\r
+ when RSTCONFIG1 =>\r
+ if timer = x"0200000" then --80ms\r
+ state <= RSTCONFIG2;\r
+ timer <= (others => '0');\r
+ datapos <= 0;\r
+ end if;\r
+-------------------------------------------------------------- \r
+-- Load config & clear display\r
+-------------------------------------------------------------- \r
+ when RSTCONFIG2 =>\r
+ if spi_idle = '1' then\r
+ if datapos = 15 then\r
+ state <= RSTCLEAR;\r
+ datapos <= 0;\r
+ else\r
+ datapos <= datapos + 1;\r
+ end if;\r
+ spi_data <= curdata;\r
+ spi_dc <= initdc(datapos);\r
+ spi_send <= '1';\r
+ end if;\r
+ when RSTCLEAR =>\r
+ if spi_idle = '1' then\r
+ cnt <= cnt + 1;\r
+ spi_data <= x"20";\r
+ spi_dc <= '1';\r
+ spi_send <= '1';\r
+ state <= RSTCLEAR2;\r
+ if cnt = 320*240*2-1 then\r
+ state <= RSTFINISH;\r
+ end if;\r
+ end if;\r
+ when RSTCLEAR2 =>\r
+ if spi_idle = '1' then\r
+ cnt <= cnt + 1;\r
+ spi_data <= x"8B";\r
+ spi_dc <= '1';\r
+ spi_send <= '1';\r
+ state <= RSTCLEAR;\r
+ if cnt = 320*240*2-1 then\r
+ state <= RSTFINISH;\r
+ end if;\r
+ end if;\r
+ when RSTFINISH =>\r
+ LED(0) <= '0';\r
+ poscol <= 0;\r
+ posrow <= 0;\r
+ datapos <= 32; --start of text section\r
+ varcnt <= 4; --no nibble active\r
+ state <= WAITSTART;\r
+ \r
+-------------------------------------------------------------- \r
+-- Write text from memory\r
+-------------------------------------------------------------- \r
+ when NEXTCHAR =>\r
+ state <= WAITSTART;\r
+ if varcnt = 0 or varcnt = 4 then\r
+ datapos <= datapos + 1;\r
+ varcnt <= 4;\r
+ end if;\r
+ \r
+ when WAITSTART =>\r
+ state <= TSTART;\r
+ when TSTART =>\r
+ if curdata >= x"20" and curdata <= x"7E" then --plain text\r
+ state <= SETWINDOW;\r
+ cnt <= 0;\r
+ colcnt <= 0;\r
+ bytecnt <= 0;\r
+ varcnt <= 4; \r
+ fontpos <= (to_integer(unsigned(curdata)) - 32)*20;\r
+ elsif curdata(7 downto 4) = x"8" then --show a variable\r
+ state <= GETNIBBLE;\r
+ varcnt <= varcnt - 1; --here: range 4..1\r
+ nibble <= x"0" & unsigned(INPUT(to_integer(unsigned(curdata(3 downto 0)))*16+varcnt*4-1 downto \r
+ to_integer(unsigned(curdata(3 downto 0)))*16+varcnt*4-4));\r
+ elsif curdata = x"0a" then --line break\r
+ poscol <= 0;\r
+ posrow <= posrow + 1;\r
+ datapos <= datapos + 1;\r
+ state <= WAITSTART;\r
+ elsif curdata = x"00" then --end of string\r
+ state <= RSTFINISH;\r
+ else --error, skip\r
+ datapos <= datapos + 1;\r
+ end if;\r
+ \r
+ when GETNIBBLE =>\r
+ state <= GETHEX;\r
+ if nibble < x"0a" then\r
+ nibble <= nibble + x"30";\r
+ else\r
+ nibble <= nibble + x"57";\r
+ end if;\r
+ \r
+ when GETHEX =>\r
+ state <= SETWINDOW;\r
+ cnt <= 0;\r
+ colcnt <= 0;\r
+ bytecnt <= 0;\r
+ fontpos <= (to_integer(nibble) - 32)*20;\r
+ \r
+ when SETWINDOW =>\r
+ if cnt < 11 then\r
+ if spi_idle = '1' then\r
+ cnt <= cnt + 1;\r
+ spi_send <= '1';\r
+ case cnt is\r
+ when 0 => spi_dc <= '0'; spi_data <= x"2A";\r
+ when 1 => spi_dc <= '1'; spi_data <= x"00";\r
+ when 2 => spi_dc <= '1'; spi_data <= std_logic_vector(to_unsigned(poscol,8));\r
+ when 3 => spi_dc <= '1'; spi_data <= x"00";\r
+ when 4 => spi_dc <= '1'; spi_data <= std_logic_vector(to_unsigned(poscol,8));\r
+ when 5 => spi_dc <= '0'; spi_data <= x"2B";\r
+ when 6 => spi_dc <= '1'; spi_data <= std_logic_vector(to_unsigned(posrow/16,8));\r
+ when 7 => spi_dc <= '1'; spi_data <= std_logic_vector(to_unsigned(posrow*16,8));\r
+ when 8 => spi_dc <= '1'; spi_data <= std_logic_vector(to_unsigned((posrow*16+15)/256,8));\r
+ when 9 => spi_dc <= '1'; spi_data <= std_logic_vector(to_unsigned(posrow*16+15,8));\r
+ when 10=> spi_dc <= '0'; spi_data <= x"2C";\r
+ end case;\r
+ end if;\r
+ else\r
+ state <= WRITEFONT;\r
+ spi_dc <= '1';\r
+ bytecnt<= 0;\r
+ pixcnt <= 0;\r
+ end if;\r
+\r
+ when WRITEWAIT =>\r
+ state <= WRITEFONT;\r
+ when WRITEFONT =>\r
+ if pixcnt = 8 and bytecnt = 1 and colcnt < 10 then --end of column\r
+ state <= SETWINDOW;\r
+ cnt <= 0;\r
+ poscol <= poscol + 1;\r
+ colcnt <= colcnt + 1;\r
+ fontpos <= fontpos + 1;\r
+ elsif pixcnt = 8 and bytecnt = 1 and colcnt = 10 then --end of character\r
+ state <= NEXTCHAR;\r
+ poscol <= poscol + 1;\r
+ elsif spi_idle = '1' then\r
+ if pixcnt < 8 then\r
+ state <= WRITESECONDBYTE;\r
+ if colcnt < 10 and curfont(pixcnt) = '1' then\r
+ if varcnt = 4 then\r
+ spi_data <= x"FD";\r
+ else\r
+ spi_data <= x"FF";\r
+ end if;\r
+ else\r
+ spi_data <= x"20";\r
+ end if;\r
+ spi_send <= '1';\r
+ pixcnt <= pixcnt + 1;\r
+ else\r
+ state <= WRITEWAIT;\r
+ fontpos <= fontpos + 1;\r
+ pixcnt <= 0;\r
+ bytecnt <= 1; \r
+ end if;\r
+ end if;\r
+ when WRITESECONDBYTE =>\r
+ if spi_idle = '1' then\r
+ spi_send <= '1';\r
+ if colcnt < 10 and curfont(pixcnt) = '1' then\r
+ if varcnt = 4 then\r
+ spi_data <= x"40";\r
+ else\r
+ spi_data <= x"FF";\r
+ end if;\r
+ else\r
+ spi_data <= x"8B";\r
+ end if;\r
+ state <= WRITEFONT;\r
+ end if;\r
+ \r
+ \r
+ end case;\r
+ if RESET = '1' then\r
+ state <= RSTIDLE;\r
+ datapos <= 0;\r
+ end if;\r
+end process;\r
+\r
+ram : process begin\r
+ wait until rising_edge(CLK);\r
+ curdata <= dataram(datapos);\r
+ curfont <= fontram(fontpos);\r
+end process;\r
+\r
+LED(1) <= spi_idle;\r
+LED(2) <= not spi_dc;\r
+LED(3) <= not spi_send;\r
+\r
+ \r
+end architecture;\r