]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
added lcd lib for padiwa incl. design
authorJan Michel <jan@mueschelsoft.de>
Thu, 2 Jan 2014 18:44:34 +0000 (19:44 +0100)
committerJan Michel <jan@mueschelsoft.de>
Thu, 2 Jan 2014 18:44:34 +0000 (19:44 +0100)
base/panda_dirc_wasa1.lpf
padiwa/padiwalcd.vhd [new file with mode: 0644]
padiwa/project/padiwa.ldf [new file with mode: 0644]
wasa/source/lcd.vhd [new file with mode: 0644]

index c8fa92a68342a7ac8518dcbc131145efc38971e2..ef66b13ae198eef9d06cc7fa064cb3f94eec00e4 100644 (file)
@@ -150,4 +150,4 @@ LOCATE COMP "TEST_LINE_13"   SITE "F16";
 LOCATE COMP "TEST_LINE_14"   SITE "F12"; 
 LOCATE COMP "TEST_LINE_15"   SITE "G13"; 
 DEFINE PORT GROUP "TEST_group" "TEST*" ;
-IOBUF GROUP  "TEST_group" IO_TYPE=LVCMOS33 DRIVE=8;
+IOBUF GROUP  "TEST_group" IO_TYPE=LVCMOS33 DRIVE=8  PULLMODE=UP ;
diff --git a/padiwa/padiwalcd.vhd b/padiwa/padiwalcd.vhd
new file mode 100644 (file)
index 0000000..0b6c7b0
--- /dev/null
@@ -0,0 +1,170 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+
+
+library machxo2;
+use machxo2.all;
+
+
+entity panda_dirc_wasa is
+  generic(
+    PADIWA_FLAVOUR : integer := 3;
+    TEMP_CORRECTION: integer := c_YES;
+    TDCTEST        : integer := c_NO
+    );
+  port(
+    CON        : out std_logic_vector(16 downto 1);
+    INP        : in  std_logic_vector(16 downto 1);
+    PWM        : out std_logic_vector(16 downto 1);
+    SPARE_LINE : out std_logic_vector(3 downto 0);
+    SPARE_LVDS : out std_logic;
+    LED_GREEN  : out std_logic;
+    LED_ORANGE : out std_logic;
+    LED_RED    : out std_logic;
+    LED_YELLOW : out std_logic;
+    SPI_CLK    : in  std_logic;
+    SPI_CS     : in  std_logic;
+    SPI_IN     : in  std_logic;
+    SPI_OUT    : out std_logic;
+    TEMP_LINE  : inout std_logic;
+    TEST_LINE  : inout std_logic_vector(15 downto 0)
+    );
+end entity;
+
+architecture panda_dirc_wasa_arch of panda_dirc_wasa is
+
+component OSCH
+-- synthesis translate_off
+  generic (NOM_FREQ: string := "133.00");
+-- synthesis translate_on
+  port (
+    STDBY :IN std_logic;
+    OSC   :OUT std_logic;
+    SEDSTDBY :OUT std_logic
+    );
+end component;
+
+component pll
+    port (
+        CLKI: in  std_logic; 
+        CLKOP: out  std_logic; 
+        CLKOS: out  std_logic; 
+        LOCK: out  std_logic);
+end component;
+
+
+attribute NOM_FREQ : string;
+attribute NOM_FREQ of clk_source : label is "133.00";
+signal clk_i  : std_logic;
+
+signal onewire_reset   : std_logic := '1';
+signal id_data_i : std_logic_vector(15 downto 0);
+signal id_addr_i : std_logic_vector(2 downto 0);
+signal id_write_i: std_logic;
+signal temperature_i : std_logic_vector(11 downto 0);
+signal timer    : unsigned(31 downto 0) := (others => '0');
+
+type idram_t is array(0 to 7) of std_logic_vector(15 downto 0);
+signal idram : idram_t;
+
+signal pll_lock : std_logic;
+signal clk_26 : std_logic;
+signal clk_osc : std_logic;
+signal input_i : std_logic_vector(255 downto 0);
+
+begin
+
+
+THE_PLL : pll
+    port map(
+        CLKI   => clk_osc,
+        CLKOP  => clk_26, --33
+        CLKOS  => clk_i, --133
+        LOCK   => pll_lock  --no lock available!
+        );
+
+---------------------------------------------------------------------------
+-- Clock
+---------------------------------------------------------------------------
+clk_source: OSCH
+-- synthesis translate_off
+  generic map ( NOM_FREQ => "133.00" )
+-- synthesis translate_on
+  port map (
+    STDBY    => '0',
+    OSC      => clk_osc,
+    SEDSTDBY => open
+  );
+
+  
+THE_LCD : entity work.lcd 
+  port map(
+    CLK   => clk_26,
+    RESET => onewire_reset,
+    
+    MOSI  => TEST_LINE(4),
+    SCK   => TEST_LINE(5),
+    DC    => TEST_LINE(3),
+    CS    => TEST_LINE(1),
+    RST   => TEST_LINE(2),
+    
+    INPUT => input_i,
+    LED   => open
+    
+    );
+  
+onewire_reset <= not TEST_LINE(15);  
+
+input_i( 15 downto   0) <= idram(0);
+input_i( 31 downto  16) <= idram(1);
+input_i( 47 downto  32) <= idram(2);
+input_i( 63 downto  48) <= idram(3);
+input_i( 79 downto  64) <= idram(4);
+input_i(223 downto  80) <= (others => '0');
+input_i(255 downto 224) <= std_logic_vector(timer);
+
+---------------------------------------------------------------------------
+-- Temperature Sensor
+---------------------------------------------------------------------------  
+THE_ONEWIRE : trb_net_onewire
+  generic map(
+    USE_TEMPERATURE_READOUT => 1,
+    PARASITIC_MODE => c_NO,
+    CLK_PERIOD => 33
+    )
+  port map(
+    CLK      => clk_26,
+    RESET    => onewire_reset,
+    READOUT_ENABLE_IN => '1',
+    ONEWIRE  => TEMP_LINE,
+    MONITOR_OUT => open,
+    --connection to id ram, according to memory map in TrbNetRegIO
+    DATA_OUT => id_data_i,
+    ADDR_OUT => id_addr_i,
+    WRITE_OUT=> id_write_i,
+    TEMP_OUT => temperature_i,
+    ID_OUT   => open,
+    STAT     => open
+    );
+
+PROC_IDMEM : process begin
+  wait until rising_edge(clk_i);
+  if id_write_i = '1' then
+    idram(to_integer(unsigned(id_addr_i))) <= id_data_i;
+  else
+    idram(4) <= "0000" & temperature_i;
+  end if;
+end process;
+
+PROC_TIMER : process begin
+  wait until rising_edge(clk_26);
+  timer <= timer + 1;
+end process;
+
+
+end architecture;
diff --git a/padiwa/project/padiwa.ldf b/padiwa/project/padiwa.ldf
new file mode 100644 (file)
index 0000000..1dfa49f
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<BaliProject version="2.0" title="padiwalcd" device="LCMXO2-4000HC-6FTG256C" synthesis="synplify" default_implementation="padiwalcd">
+    <Options/>
+    <Implementation title="padiwalcd" dir="padiwalcd" description="padiwalcd" default_strategy="Strategy1">
+        <Source name="../padiwalcd.vhd" type="VHDL" type_short="VHDL">
+            <Options top_module="panda_dirc_wasa"/>
+        </Source>
+        <Source name="../source/ffarray.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../source/pwm.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../source/spi_slave.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../cores/efb_define_def.v" type="Verilog" type_short="Verilog">
+            <Options/>
+        </Source>
+        <Source name="../cores/fifo_1kx8.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../cores/flash.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../cores/flashram.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../cores/pll_shifted_clocks.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../cores/pll.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../cores/UFM_WB.v" type="Verilog" type_short="Verilog">
+            <Options/>
+        </Source>
+        <Source name="../../trbnet/trb_net_std.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../../trbnet/trb_net_components.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../../trbnet/trb_net_onewire.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../lcd.vhd" type="VHDL" type_short="VHDL">
+            <Options/>
+        </Source>
+        <Source name="../panda_dirc_wasa.lpf" type="Logic Preference" type_short="LPF">
+            <Options/>
+        </Source>
+        <Source name="padiwa/padiwa.xcf" type="Programming Project File" type_short="Programming">
+            <Options/>
+        </Source>
+    </Implementation>
+    <Strategy name="Strategy1" file="padiwalcd.sty"/>
+</BaliProject>
diff --git a/wasa/source/lcd.vhd b/wasa/source/lcd.vhd
new file mode 100644 (file)
index 0000000..dbe3119
--- /dev/null
@@ -0,0 +1,498 @@
+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