diff --git a/modules/wishbone/Manifest.py b/modules/wishbone/Manifest.py
index 8be1f73113d1dc364ad37150aa9517c7310ce710..0fefbad32bd0032d63c0da1f5c48c1bb4774a029 100644
--- a/modules/wishbone/Manifest.py
+++ b/modules/wishbone/Manifest.py
@@ -17,6 +17,7 @@ modules =  { "local" :
 						"wb_xilinx_fpga_loader",
 						"wb_clock_crossing",
 						"wb_dma",
+						"wb_serial_lcd",
 						"wbgen2"
 						 ]};
 
diff --git a/modules/wishbone/wb_serial_lcd/Manifest.py b/modules/wishbone/wb_serial_lcd/Manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..08aebb35c6b571b14835ef104f24ab325ec983e6
--- /dev/null
+++ b/modules/wishbone/wb_serial_lcd/Manifest.py
@@ -0,0 +1 @@
+files = [ "wb_serial_lcd.vhd" ]
diff --git a/modules/wishbone/wb_serial_lcd/wb_serial_lcd.vhd b/modules/wishbone/wb_serial_lcd/wb_serial_lcd.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..9c1e28f5111599ede01cd945224209a4d9b602b5
--- /dev/null
+++ b/modules/wishbone/wb_serial_lcd/wb_serial_lcd.vhd
@@ -0,0 +1,158 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.wishbone_pkg.all;
+use work.genram_pkg.all;
+
+entity wb_serial_lcd is
+  generic(
+    g_cols : natural := 40;
+    g_rows : natural := 24;
+    g_wait : natural := 1); -- How many cycles per state change
+  port(
+    slave_clk_i  : in  std_logic;
+    slave_rstn_i : in  std_logic;
+    slave_i      : in  t_wishbone_slave_in;
+    slave_o      : out t_wishbone_slave_out;
+    
+    di_clk_i     : in  std_logic;
+    di_scp_o     : out std_logic;
+    di_lp_o      : out std_logic;
+    di_flm_o     : out std_logic;
+    di_dat_o     : out std_logic);
+end entity;
+
+architecture rtl of wb_serial_lcd is
+  type t_state is (CLK_HIGH, FLM_HIGH, LP_HIGH, SLEEP1,  SLEEP2, 
+                   CLK_LOW,  SLEEP3,   LP_LOW,  FLM_LOW, SET_DATA);
+  
+  constant c_lo : natural := f_ceil_log2((g_cols+31)/32);
+  constant c_hi : natural := f_ceil_log2(g_rows);
+  constant c_bits : natural := c_lo+c_hi;
+  
+  signal r_state : t_state                     := SET_DATA;
+  signal r_row   : integer range 0 to g_rows-1 := 0;
+  signal r_col   : integer range 0 to g_cols-1 := 0;
+  signal r_wait  : integer range 0 to g_wait-1 := 0;
+  signal r_lp    : std_logic                   := '0';
+  signal r_flm   : std_logic                   := '0';
+  signal r_ack   : std_logic                   := '0';
+  
+  signal s_wea : std_logic;
+  signal s_qa  : std_logic_vector(31 downto 0);
+  signal s_qb  : std_logic_vector(31 downto 0);
+  signal s_ab  : std_logic_vector(c_bits-1 downto 0);
+  
+begin
+
+  slave_o.rty   <= '0';
+  slave_o.err   <= '0';
+  slave_o.stall <= '0';
+  
+  s_wea <= slave_i.cyc and slave_i.stb and slave_i.we;
+  s_ab(c_bits-1 downto c_lo) <= std_logic_vector(to_unsigned(r_row, c_hi));
+  s_ab(c_lo  -1 downto    0) <= std_logic_vector(to_unsigned(r_col, c_lo+5)(c_lo+4 downto 5));
+  
+  mem : generic_dpram
+    generic map(
+      g_data_width       => 32,
+      g_size             => 2**c_bits,
+      g_with_byte_enable => true,
+      g_dual_clock       => false)
+    port map(
+      clka_i => slave_clk_i,
+      bwea_i => slave_i.sel,
+      wea_i  => s_wea,
+      aa_i   => slave_i.adr(c_bits+1 downto 2),
+      da_i   => slave_i.dat,
+      qa_o   => s_qa,
+      clkb_i => di_clk_i,
+      bweb_i => (others => '0'),
+      web_i  => '0',
+      ab_i   => s_ab,
+      db_i   => (others => '0'),
+      qb_o   => s_qb);
+  
+  -- Provide WB access to the frame buffer
+  wb : process(slave_clk_i) is
+  begin
+    if rising_edge(slave_clk_i) then
+      r_ack <= slave_i.cyc and slave_i.stb;
+      slave_o.ack <= r_ack;
+      slave_o.dat <= s_qa;
+    end if;
+  end process;
+
+  -- Draw the frame buffer to the display
+  main : process(di_clk_i) is
+  begin
+    if rising_edge(di_clk_i) then
+      if r_wait /= g_wait-1 then
+        r_wait <= r_wait + 1;
+      else
+        r_wait <= 0;
+      
+        case r_state is
+        
+          when CLK_HIGH =>
+            di_scp_o <= '1';
+            r_state  <= FLM_HIGH;
+            
+          when FLM_HIGH =>
+            di_flm_o <= r_flm;
+            r_state <= LP_HIGH;
+          
+          when LP_HIGH =>
+            di_lp_o  <= r_lp;
+            r_state  <= SLEEP1;
+          
+          when SLEEP1 =>
+            r_state <= SLEEP2;
+            
+          when SLEEP2 =>
+            r_state <= CLK_LOW;
+            
+          when CLK_LOW =>
+            di_scp_o <= '0';
+            r_state <= SLEEP3;
+          
+          when SLEEP3 =>
+            r_state  <= LP_LOW;
+          
+          when LP_LOW =>
+            di_lp_o  <= '0';
+            r_state  <= FLM_LOW;
+            
+          when FLM_LOW =>
+            di_flm_o <= '0';
+            r_state <= SET_DATA;
+          
+          when SET_DATA =>
+            di_dat_o <= s_qb(to_integer(31 - to_unsigned(r_col, c_lo+5)(4 downto 0)));
+            r_state  <= CLK_HIGH;
+            
+            if r_col /= g_cols-1 then
+              r_lp  <= '0';
+              r_flm <= '0';
+              r_col <= r_col + 1;
+              r_row <= r_row;
+            elsif r_row /= g_rows-1 then
+              r_lp  <= '1';
+              r_flm <= '0';
+              r_col <= 0;
+              r_row <= r_row + 1;
+            else
+              r_lp  <= '1';
+              r_flm <= '1';
+              r_col <= 0;
+              r_row <= 0;
+            end if;
+          
+        end case;
+      end if;
+    end if;
+  end process;
+  
+end rtl;
diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd
index 4c0c081d390607e5433e2163d31a0dbb85f0ded0..b37d1566c474003ec9478993fd27e0098dfc54b7 100644
--- a/modules/wishbone/wishbone_pkg.vhd
+++ b/modules/wishbone/wishbone_pkg.vhd
@@ -658,6 +658,39 @@ package wishbone_pkg is
       irqs_i       : in  std_logic_vector(g_num_interrupts-1 downto 0);
       irq_master_o : out std_logic);
   end component;
+
+  constant c_wb_serial_lcd_sdb : t_sdb_device := (
+    abi_class     => x"0000", -- undocumented device
+    abi_ver_major => x"01",
+    abi_ver_minor => x"00",
+    wbd_endian    => c_sdb_endian_big,
+    wbd_width     => x"7", -- 8/16/32-bit port granularity
+    sdb_component => (
+    addr_first    => x"0000000000000000",
+    addr_last     => x"00000000000000ff",
+    product => (
+    vendor_id     => x"0000000000000651", -- GSI
+    device_id     => x"b77a5045",
+    version       => x"00000001",
+    date          => x"20130222",
+    name          => "SERIAL-LCD-DISPLAY ")));
+  component wb_serial_lcd
+    generic(
+      g_cols : natural := 40;
+      g_rows : natural := 24;
+      g_wait : natural := 1);
+    port(
+      slave_clk_i  : in  std_logic;
+      slave_rstn_i : in  std_logic;
+      slave_i      : in  t_wishbone_slave_in;
+      slave_o      : out t_wishbone_slave_out;
+      di_clk_i     : in  std_logic;
+      di_scp_o     : out std_logic;
+      di_lp_o      : out std_logic;
+      di_flm_o     : out std_logic;
+      di_dat_o     : out std_logic);
+  end component;
+
 end wishbone_pkg;
 
 package body wishbone_pkg is