URL
https://opencores.org/ocsvn/graphicallcd/graphicallcd/trunk
Subversion Repositories graphicallcd
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/test.vhd
0,0 → 1,69
|
-- VHDL Test Bench Created from source file test_lcd.vhd -- 14:39:34 12/15/2003 |
-- |
-- Notes: |
-- This testbench has been automatically generated using types std_logic and |
-- std_logic_vector for the ports of the unit under test. Xilinx recommends |
-- that these types always be used for the top-level I/O of a design in order |
-- to guarantee that the testbench will bind correctly to the post-implementation |
-- simulation model. |
-- |
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.numeric_std.ALL; |
|
ENTITY testbench IS |
END testbench; |
|
ARCHITECTURE behavior OF testbench IS |
|
COMPONENT test_lcd |
PORT( |
clk : IN std_logic; |
rst : IN std_logic; |
db : INOUT std_logic_vector(7 downto 0); |
done : OUT std_logic; |
e : OUT std_logic; |
r_w : OUT std_logic; |
cs1 : OUT std_logic; |
cs2 : OUT std_logic; |
d_i : OUT std_logic; |
ram_dis : OUT std_logic |
); |
END COMPONENT; |
|
SIGNAL done : std_logic; |
SIGNAL e : std_logic; |
SIGNAL r_w : std_logic; |
SIGNAL cs1 : std_logic; |
SIGNAL cs2 : std_logic; |
SIGNAL d_i : std_logic; |
SIGNAL db : std_logic_vector(7 downto 0); |
SIGNAL clk : std_logic; |
SIGNAL rst : std_logic; |
SIGNAL ram_dis : std_logic; |
|
BEGIN |
|
uut: test_lcd PORT MAP( |
done => done, |
e => e, |
r_w => r_w, |
cs1 => cs1, |
cs2 => cs2, |
d_i => d_i, |
db => db, |
clk => clk, |
rst => rst, |
ram_dis => ram_dis |
); |
|
|
-- *** Test Bench - User Defined Section *** |
tb : PROCESS |
BEGIN |
wait; -- will wait forever |
END PROCESS; |
-- *** End Test Bench - User Defined Section *** |
|
END; |
/trunk/graphical_lcd_tb.vhd
0,0 → 1,134
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_arith.all; |
use IEEE.std_logic_unsigned.all; |
|
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
------------------------------------------------------------------------------- |
|
entity graphical_lcd_tb is |
|
end graphical_lcd_tb; |
|
------------------------------------------------------------------------------- |
architecture testbench of graphical_lcd_tb is |
component graphical_lcd |
port ( |
E : out std_logic; |
R_W : out std_logic; |
CS1 : out std_logic; |
CS2 : out std_logic; |
D_I : out std_logic; |
DB : inout std_logic_vector(7 downto 0); |
CLK_I : in std_logic; |
RST_I : in std_logic; |
DAT_I : in std_logic_vector(7 downto 0); |
DAT_O : out std_logic_vector; |
ACK_O : out std_logic; |
STB_I : in std_logic; |
WE_I : in std_logic; |
TGD_I : in std_logic_vector(2 downto 0)); |
end component; |
|
signal E_i : std_logic; |
signal R_W_i : std_logic; |
signal CS1_i : std_logic; |
signal CS2_i : std_logic; |
signal D_I_i : std_logic; |
signal DB_i : std_logic_vector(7 downto 0); |
signal CLK_I_i : std_logic; |
signal RST_I_i : std_logic; |
signal DAT_I_i : std_logic_vector(7 downto 0); |
signal DAT_O_i : std_logic_vector(7 downto 0); |
signal ACK_O_i : std_logic; |
signal STB_I_i : std_logic; |
signal WE_I_i : std_logic; |
signal TGD_I_i : std_logic_vector(2 downto 0); |
|
constant clock_period : delay_length := 20 ns; |
|
begin -- testbench |
|
-- Unit under test |
UUT: graphical_lcd |
port map ( |
E => E_i, |
R_W => R_W_i, |
CS1 => CS1_i, |
CS2 => CS2_i, |
D_I => D_I_i, |
DB => DB_i, |
CLK_I => CLK_I_i, |
RST_I => RST_I_i, |
DAT_I => DAT_I_i, |
DAT_O => DAT_O_i, |
ACK_O => ACK_O_i, |
STB_I => STB_I_i, |
WE_I => WE_I_i, |
TGD_I => TGD_I_i); |
|
-- Simulate fake data reads |
DB_i <= "ZZZZZZZZ" when R_W_i = '0' else |
"00001111"; |
|
-- Reset driver |
RST_I_i <= '1', '0' after 2.5 * clock_period; |
|
-- Generate the testbench clock |
clk_gen: process |
begin -- process clk_gen |
CLK_I_i <= '0'; |
wait for clock_period/2; |
loop |
CLK_I_i <= '1'; |
wait for clock_period/2; |
CLK_I_i <= '0'; |
wait for clock_period/2; |
end loop; -- clock_period/2; |
end process clk_gen; |
|
stimulus: process |
begin -- process stimulus |
wait until RST_I_i = '0'; |
|
wait until CLK_I_i = '1'; |
-- Turn the display on |
DAT_I_i <= "00111111"; |
TGD_I_i <= "000"; |
WE_I_i <= '1'; |
wait until CLK_I_i = '1'; |
STB_I_i <= '1'; |
wait until ACK_O_i = '1'; |
wait until CLK_I_i = '1'; |
STB_I_i <= '0'; |
|
-- Read until the busy is gone |
wait until CLK_I_i = '1'; |
TGD_I_i <= "100"; |
WE_I_i <= '0'; |
wait until CLK_I_i = '1'; |
STB_I_i <= '1'; |
wait until ACK_O_i = '1'; |
wait until CLK_I_i = '1'; |
STB_I_i <= '0'; |
-- Send some data |
wait until CLK_I_i = '1'; |
DAT_I_i <= "10101100"; |
TGD_I_i <= "011"; |
WE_I_i <= '1'; |
wait until CLK_I_i = '1'; |
STB_I_i <= '1'; |
wait until ACK_O_i = '1'; |
wait until CLK_I_i = '1'; |
STB_I_i <= '0'; |
wait; |
|
end process stimulus; |
|
end testbench; |
|
|
/trunk/test_lcd.vhd
0,0 → 1,281
------------------------------------------------------------------------------- |
-- This tests the graphical lcd code |
------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_arith.all; |
use IEEE.std_logic_unsigned.all; |
|
entity test_lcd is |
|
port ( |
DONE : out std_logic; |
E : out std_logic; |
R_W : out std_logic; |
CS1 : out std_logic; |
CS2 : out std_logic; |
D_I : out std_logic; |
DB : inout std_logic_vector(7 downto 0); |
CLK : in std_logic; |
RST : in std_logic; |
RAM_DIS : out std_logic); |
|
end test_lcd; |
|
architecture behavioral of test_lcd is |
component graphical_lcd |
port ( |
E : out std_logic; |
R_W : out std_logic; |
CS1 : out std_logic; |
CS2 : out std_logic; |
D_I : out std_logic; |
DB : inout std_logic_vector(7 downto 0); |
CLK_I : in std_logic; |
RST_I : in std_logic; |
DAT_I : in std_logic_vector(7 downto 0); |
DAT_O : out std_logic_vector(7 downto 0); |
ACK_O : out std_logic; |
STB_I : in std_logic; |
WE_I : in std_logic; |
TGD_I : in std_logic_vector(2 downto 0)); |
end component; |
|
signal E_i : std_logic; |
signal R_W_i : std_logic; |
signal CS1_i : std_logic; |
signal CS2_i : std_logic; |
signal D_I_i : std_logic; |
signal DB_i : std_logic_vector(7 downto 0); |
signal CLK_i : std_logic; |
signal RST_i : std_logic; |
signal DAT_O_i : std_logic_vector(7 downto 0); |
signal DAT_I_i : std_logic_vector(7 downto 0); |
signal ACK_i : std_logic; |
signal STB_i : std_logic; |
signal WE_i : std_logic; |
signal TGD_i : std_logic_vector(2 downto 0); |
|
signal page : std_logic_vector(3 downto 0); |
signal addr : std_logic_vector(6 downto 0); |
signal lcd_wr : std_logic; |
signal lcd_rd : std_logic; |
|
type lcd_state_type is (LCD_IDLE, LCD_DO_WR, LCD_DO_RD, LCD_WR_DONE, LCD_RD_DONE, LCD_READ_STATUS, LCD_STATUS_DONE, LCD_CHK_BUSY, LCD_WAIT_CLEAR); |
type state_type is (IDLE, TURN_ON, SET_PAGE, SET_ADDR, DRAW_DATA, WAIT_COMPLETE, HALT); |
|
signal cur_state : state_type; |
signal next_state : state_type; |
signal lcd_state : lcd_state_type; |
signal d_i_int : std_logic; |
signal cs1_int : std_logic; |
signal cs2_int : std_logic; |
begin -- behavioral |
|
-- Map all the signals to the proper ports |
E <= E_i; |
R_W <= R_W_i; |
CS1 <= CS1_i; |
CS2 <= CS2_i; |
D_I <= D_I_i; |
CLK_i <= CLK; |
RST_i <= RST; |
DONE <= '1' when (cur_state = HALT) else '0'; |
RAM_DIS <= '1'; -- disable 'Flash RAM' |
TGD_i(1) <= cs1_int; |
TGD_i(2) <= cs2_int; |
|
lcd_op: process (CLK_i, RST_i) |
begin -- process |
if RST_i = '1' then -- asynchronous reset (active low) |
lcd_state <= LCD_IDLE; |
STB_i <= '0'; |
WE_i <= '0'; |
TGD_i(0) <= '0'; |
elsif CLK_i'event and CLK_i = '1' then -- rising clock edge |
case lcd_state is |
when LCD_IDLE => |
STB_i <= '0'; |
WE_i <= '0'; |
TGD_i(0) <= d_i_int; |
if lcd_wr = '1' then |
lcd_state <= LCD_DO_WR; |
elsif lcd_rd = '1' then |
lcd_state <= LCD_DO_RD; |
else |
lcd_state <= LCD_IDLE; |
end if; |
|
when LCD_DO_WR => |
STB_i <= '1'; |
WE_i <= '1'; |
TGD_i(0) <= d_i_int; |
if (ACK_i = '1') then |
lcd_state <= LCD_WR_DONE; |
end if; |
|
when LCD_WR_DONE => |
STB_i <= '0'; |
WE_i <= '0'; |
TGD_i(0) <= d_i_int; |
if (ACK_i = '0') then |
lcd_state <= LCD_READ_STATUS; |
end if; |
|
when LCD_DO_RD => |
STB_i <= '1'; |
WE_i <= '0'; |
TGD_i(0) <= '0'; |
if (ACK_i = '1') then |
lcd_state <= LCD_RD_DONE; |
end if; |
|
when LCD_RD_DONE => |
STB_i <= '0'; |
WE_i <= '0'; |
TGD_i(0) <= '0'; |
if (ACK_i = '0') then |
lcd_state <= LCD_READ_STATUS; |
end if; |
|
when LCD_READ_STATUS => |
STB_i <= '1'; |
WE_i <= '0'; |
TGD_i(0) <= '0'; |
if (ACK_i = '1') then |
lcd_state <= LCD_STATUS_DONE; |
end if; |
|
when LCD_STATUS_DONE => |
STB_i <= '0'; |
WE_i <= '0'; |
TGD_i(0) <= '0'; |
if (ACK_i = '0') then |
lcd_state <= LCD_CHK_BUSY; |
end if; |
|
when LCD_CHK_BUSY => |
if (DAT_O_i(7) = '0') then |
lcd_state <= LCD_WAIT_CLEAR; |
else |
lcd_state <= LCD_READ_STATUS; |
end if; |
|
when LCD_WAIT_CLEAR => |
if (lcd_wr = '0') and (lcd_rd = '0') and (ACK_i = '0') then |
lcd_state <= LCD_IDLE; |
else |
lcd_state <= LCD_WAIT_CLEAR; |
end if; |
|
when others => null; |
end case; |
end if; |
end process; |
|
-- Draw lines on the lcd |
draw: process (CLK_i, RST_i) |
begin -- process draw |
if RST_i = '1' then |
cur_state <= IDLE; |
next_state <= IDLE; |
d_i_int <= '0'; |
cs1_int <= '1'; |
cs2_int <= '1'; |
DAT_I_i <= "00000000"; |
lcd_wr <= '0'; |
lcd_rd <= '0'; |
page <= "0000"; |
addr <= "0000000"; |
elsif CLK_i'event and CLK_i = '1' then |
case cur_state is |
when IDLE => |
lcd_wr <= '0'; |
lcd_rd <= '0'; |
d_i_int <= '0'; |
cs1_int <= '1'; |
cs2_int <= '1'; |
cur_state <= TURN_ON; |
|
when TURN_ON => |
DAT_I_i <= "00111111"; |
d_i_int <= '0'; |
cs1_int <= '0'; |
cs2_int <= '0'; |
lcd_wr <= '1'; |
next_state <= SET_PAGE; |
cur_state <= WAIT_COMPLETE; |
|
when SET_PAGE => |
DAT_I_i <= "10111" & page(2 downto 0); |
d_i_int <= '0'; |
cs1_int <= '0'; |
cs2_int <= '0'; |
lcd_wr <= '1'; |
addr <= "0000000"; |
if (page /= "1000") then |
next_state <= SET_ADDR; |
else |
next_state <= HALT; |
end if; |
cur_state <= WAIT_COMPLETE; |
|
when SET_ADDR => |
DAT_I_i <= "01" & addr(5 downto 0); |
d_i_int <= '0'; |
cs1_int <= '0'; |
cs2_int <= '0'; |
lcd_wr <= '1'; |
next_state <= DRAW_DATA; |
cur_state <= WAIT_COMPLETE; |
|
when DRAW_DATA => |
DAT_I_i <= "01011010"; |
d_i_int <= '1'; |
cs1_int <= '0'; |
cs2_int <= '0'; |
lcd_wr <= '1'; |
if (addr /= "1000000") then |
addr <= addr + 1; |
next_state <= DRAW_DATA; |
else |
page <= page + 1; |
next_state <= SET_PAGE; |
end if; |
cur_state <= WAIT_COMPLETE; |
|
when WAIT_COMPLETE => |
lcd_wr <= '0'; |
lcd_rd <= '0'; |
if lcd_state = LCD_WAIT_CLEAR then |
cur_state <= next_state; |
end if; |
|
when HALT => |
cur_state <= HALT; |
|
when others => null; |
end case; |
end if; |
end process draw; |
|
lcd_cntrl: graphical_lcd |
port map ( |
E => E_i, |
R_W => R_W_i, |
CS1 => CS1_i, |
CS2 => CS2_i, |
D_I => D_I_i, |
DB => DB, |
CLK_I => CLK_i, |
RST_I => RST_i, |
DAT_I => DAT_I_i, |
DAT_O => DAT_O_i, |
ACK_O => ACK_i, |
STB_I => STB_i, |
WE_I => WE_i, |
TGD_I => TGD_i); |
|
|
end behavioral; |
|
/trunk/test_lcd_tb.vhd
0,0 → 1,76
------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.numeric_std.ALL; |
|
------------------------------------------------------------------------------- |
|
entity test_lcd_tb is |
end test_lcd_tb; |
|
------------------------------------------------------------------------------- |
|
architecture behavioral of test_lcd_tb is |
component test_lcd |
port ( |
DONE : out std_logic; |
E : out std_logic; |
R_W : out std_logic; |
CS1 : out std_logic; |
CS2 : out std_logic; |
D_I : out std_logic; |
DB : inout std_logic_vector(7 downto 0); |
CLK : in std_logic; |
RST : in std_logic; |
RAM_DIS : out std_logic); |
end component; |
|
signal DONE_i : std_logic; |
signal E_i : std_logic; |
signal R_W_i : std_logic; |
signal CS1_i : std_logic; |
signal CS2_i : std_logic; |
signal D_I_i : std_logic; |
signal DB_i : std_logic_vector(7 downto 0); |
signal CLK_i : std_logic; |
signal RST_i : std_logic; |
signal RAM_DIS_i : std_logic; |
|
constant clock_period : delay_length := 20 ns; |
|
begin -- testbench |
UUT: test_lcd |
port map ( |
DONE => DONE_i, |
E => E_i, |
R_W => R_W_i, |
CS1 => CS1_i, |
CS2 => CS2_i, |
D_I => D_I_i, |
DB => DB_i, |
CLK => CLK_i, |
RST => RST_i, |
RAM_DIS => RAM_DIS_i); |
|
-- Simulate the LCD |
DB_i <= "ZZZZZZZZ" when (R_W_i = '0') else "00000000"; |
|
-- Generate the testbench clock |
clk_gen: process |
begin -- process clk_gen |
CLK_i <= '0'; |
wait for clock_period/2; |
loop |
CLK_i <= '1'; |
wait for clock_period/2; |
CLK_i <= '0'; |
wait for clock_period/2; |
end loop; -- clock_period/2; |
end process clk_gen; |
|
-- Reset driver |
RST_i <= '1', '0' after 2.5 * clock_period; |
|
end behavioral; |
|
/trunk/graphical_lcd.vhd
0,0 → 1,191
------------------------------------------------------------------------------- |
-- WISHBONE DATASHEET |
-- WISHBONE SoC Architecture Specification, Revision B.3 |
-- |
-- General Description : graphical LCD interface for KS0108b controllers |
-- |
-- Supported Cycles : SLAVE, READ/WRITE |
-- |
-- Data Port Size : 8-bit |
-- Data Port Granularity : 8-bit |
-- Data Port Max Operand Size : 8-bit |
-- Data Transfer Ordering : Big endian and/or little endian |
-- Data Transfer Sequence : Undefined |
-- |
-- Supported Signal List |
-- Signal Name WISHBONE Equiv |
-- ACK_O ACK_O |
-- CLK_I CLK_I |
-- DAT_I(7 downto 0) DAT_I() |
-- DAT_O(7 downto 0) DAT_O() |
-- RST_I RST_I |
-- STB_I STB_I |
-- WE_I WE_I |
-- D/I_F TGD(0) |
-- CS1 TGD(1) |
-- CS2 TGD(2) |
------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.std_logic_arith.all; |
use IEEE.std_logic_unsigned.all; |
|
entity graphical_lcd is |
port ( |
-- LCD interface |
E : out std_logic; -- enable signal |
R_W : out std_logic; -- Read High / Write Low |
CS1 : out std_logic; -- CS1 |
CS2 : out std_logic; -- CS2 |
D_I : out std_logic; -- data high / instruction low |
DB : inout std_logic_vector(7 downto 0); -- data byte |
-- Wishbone interface |
CLK_I : in std_logic; -- The Sytem Clock |
RST_I : in std_logic; -- Async. Reset |
DAT_I : in std_logic_vector(7 downto 0); |
DAT_O : out std_logic_vector(7 downto 0); |
ACK_O : out std_logic; |
STB_I : in std_logic; |
WE_I : in std_logic; |
TGD_I : in std_logic_vector(2 downto 0)); |
end graphical_lcd; |
|
------------------------------------------------------------------------------- |
-- ARCHITECTURE |
------------------------------------------------------------------------------- |
architecture ks0108b of graphical_lcd is |
type state is (IDLE, WR_SETUP, WR_HOLD, RD_SETUP, RD_HOLD, ACK); |
|
signal DB_en : std_logic := '0'; -- enable the DB lines |
signal cur_state : state := idle; -- current state |
|
signal data_in : std_logic_vector(7 downto 0) := "XXXXXXXX"; |
signal data_out : std_logic_vector(7 downto 0) := "XXXXXXXX"; |
|
signal e_cnt : std_logic_vector(7 downto 0); |
signal e_int : std_logic; |
signal e_en : std_logic; |
begin -- behavioral |
|
----------------------------------------------------------------------------- |
-- WISHBONE STUFF |
----------------------------------------------------------------------------- |
DAT_O <= data_out; |
|
ACK_O <= '1' when (cur_state = ACK) else |
'0'; |
|
wishbone_dat_in: process (CLK_I, RST_I) |
begin -- process wishbone_dat_in |
if RST_I = '1' then -- asynchronous reset |
data_in <= "00000000"; |
elsif CLK_I'event and CLK_I = '1' then -- rising clock edge |
if (STB_I = '1') and (WE_I = '1') then |
data_in <= DAT_I; |
end if; |
else |
data_in <= data_in; |
end if; |
end process wishbone_dat_in; |
|
----------------------------------------------------------------------------- |
-- LCD STUFF |
----------------------------------------------------------------------------- |
|
E <= e_int; |
|
D_I <= TGD_I(0); |
|
CS1 <= TGD_I(1); |
|
CS2 <= TGD_I(2); |
|
R_W <= '0' when (cur_state = WR_SETUP) or (cur_state = WR_HOLD) else |
'1' when (cur_state = RD_SETUP) or (cur_state = RD_HOLD) else |
'1'; |
|
e_en <= '1' when (cur_state = WR_SETUP) or (cur_state = WR_HOLD) else |
'1' when (cur_state = RD_SETUP) or (cur_state = RD_HOLD) else |
'0'; |
|
DB <= data_in when (cur_state = WR_SETUP) or (cur_state = WR_HOLD) else |
"ZZZZZZZZ"; |
|
data_out <= DB when (e_int'event) and (e_int = '0') else |
data_out; |
|
-- purpose: creates the enable signal which is at least a 500ns period clock |
e_gen: process (CLK_I, RST_I, e_en) |
begin -- process e_gen |
if (RST_I = '1') or (e_en = '0') then |
e_cnt <= "00000000"; |
e_int <= '0'; |
elsif CLK_I'event and CLK_I = '1' then |
e_cnt <= e_cnt + 1; |
if (e_cnt = X"19") then |
e_cnt <= "00000000"; |
e_int <= not e_int; |
end if; |
end if; |
end process e_gen; |
|
state_machine: process (CLK_I, RST_I) |
begin -- process state_machine |
if RST_I = '1' then |
cur_state <= idle; |
elsif CLK_I'event and CLK_I = '1' then |
case cur_state is |
when IDLE => |
if (STB_I = '1') then |
if (WE_I = '1') then |
cur_state <= WR_SETUP; |
else |
cur_state <= RD_SETUP; |
end if; |
else |
cur_state <= IDLE; |
end if; |
|
when WR_SETUP => |
if (e_int = '1') then |
cur_state <= WR_HOLD; |
else |
cur_state <= WR_SETUP; |
end if; |
|
when WR_HOLD => |
if (e_int = '0') and (e_cnt = X"03") then |
cur_state <= ACK; |
else |
cur_state <= WR_HOLD; |
end if; |
|
when RD_SETUP => |
if (e_int = '1') then |
cur_state <= RD_HOLD; |
else |
cur_state <= RD_SETUP; |
end if; |
|
when RD_HOLD => |
if (e_int = '0') and (e_cnt = X"03") then |
cur_state <= ACK; |
else |
cur_state <= RD_HOLD; |
end if; |
|
when ACK => |
if (STB_I = '0') then |
cur_state <= IDLE; |
end if; |
|
when others => null; |
|
end case; |
end if; |
end process state_machine; |
|
end ks0108b; |
|
|
|