Commit 07c4221b authored by Wesley W. Terpstra's avatar Wesley W. Terpstra

serial_lcd: WB interface to LCD displays with serial protocol

parent 2f75fcf8
......@@ -17,6 +17,7 @@ modules = { "local" :
"wb_xilinx_fpga_loader",
"wb_clock_crossing",
"wb_dma",
"wb_serial_lcd",
"wbgen2"
]};
......
files = [ "wb_serial_lcd.vhd" ]
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;
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment