URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 285 to Rev 286
- ↔ Reverse comparison
Rev 285 → Rev 286
/open8_urisc/trunk/VHDL/hd44780_4b.vhd
0,0 → 1,172
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_misc.all; |
|
entity hd44780_4b is |
generic( |
Tsu : integer := 40; -- ns |
Tpw : integer := 250; -- nS |
Tcyc : integer := 500; -- nS |
Clock_Frequency : real := 50000000.0; -- Hz |
Reset_Level : std_logic := '1' |
); |
port( |
Clock : in std_logic; |
Reset : in std_logic; |
-- |
Wr_Fnset : in std_logic; |
Wr_Data : in std_logic_vector(7 downto 0); |
Wr_Reg : in std_logic; |
Wr_En : in std_logic; |
-- |
IO_Done : out std_logic; |
-- |
LCD_RS : out std_logic; |
LCD_E : out std_logic; |
LCD_DQ : out std_logic_vector(7 downto 0) |
); |
end entity; |
|
architecture behave of hd44780_4b is |
|
-- The ceil_log2 function returns the minimum register width required to |
-- hold the supplied integer. |
function ceil_log2 (x : in natural) return natural is |
variable retval : natural; |
begin |
retval := 1; |
while ((2**retval) - 1) < x loop |
retval := retval + 1; |
end loop; |
return retval; |
end function; |
|
constant CONV_NANOSECS : real := 0.000000001; |
|
constant Tsu_r : real := CONV_NANOSECS * real(Tsu); |
constant Tpw_r : real := CONV_NANOSECS * real(Tpw); |
constant Tcyc_r : real := CONV_NANOSECS * real(Tcyc); |
|
constant TCYC_i : integer := integer(Clock_Frequency * Tcyc_r); |
constant TCYC_BITS : integer := ceil_log2(TCYC_i); |
|
constant TCYC_DELAY : std_logic_vector(TCYC_BITS-1 downto 0) := |
conv_std_logic_vector(TCYC_i-1, TCYC_BITS); |
signal tcyc_timer : std_logic_vector(TCYC_BITS - 1 downto 0) := |
(others => '0'); |
|
constant TPW_i : integer := integer(Clock_Frequency * Tpw_r); |
constant TPW_DELAY : std_logic_vector(TCYC_BITS-1 downto 0) := |
conv_std_logic_vector(TPW_i-1, TCYC_BITS); |
|
constant TSU_i : integer := integer(Clock_Frequency * Tsu_r); |
constant TSU_BITS : integer := ceil_log2(TSU_i); |
constant TSU_DELAY : std_logic_vector(TSU_BITS - 1 downto 0) := |
conv_std_logic_vector(TSU_i-1,TSU_BITS); |
signal tsnh_timer : std_logic_vector(TSU_BITS-1 downto 0) := |
(others => '0'); |
|
type IO_STATES is (IDLE, |
INIT_UB, TAS_UB, TPW_UB, TCYC_UB, |
INIT_LB, TPW_LB, TCYC_LB, |
DONE ); |
signal io_state : IO_STATES; |
signal fn_set : std_logic; |
|
signal Wr_Buffer : std_logic_vector(8 downto 0); |
alias Wr_Buffer_A is Wr_Buffer(8); |
alias Wr_Buffer_U is Wr_Buffer(7 downto 4); |
alias Wr_Buffer_L is Wr_Buffer(3 downto 0); |
|
alias LCD_DQ_U is LCD_DQ(7 downto 4); |
alias LCD_DQ_L is LCD_DQ(3 downto 0); |
|
begin |
|
LCD_IO_proc: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
io_state <= IDLE; |
fn_set <= '0'; |
tcyc_timer <= (others => '0'); |
tsnh_timer <= (others => '0'); |
Wr_Buffer <= (others => '0'); |
IO_Done <= '0'; |
LCD_RS <= '0'; |
LCD_E <= '0'; |
LCD_DQ <= (others => '0'); |
elsif( rising_edge(Clock) )then |
IO_Done <= '0'; |
LCD_E <= '0'; |
LCD_DQ_L <= (others => '0'); |
case( io_state )is |
when IDLE => |
if( Wr_En = '1' )then |
Wr_Buffer <= Wr_Reg & Wr_Data; |
fn_set <= Wr_Fnset; |
io_state <= INIT_UB; |
end if; |
|
when INIT_UB => |
tsnh_timer <= TSU_DELAY; |
tcyc_timer <= (others => '0'); |
LCD_RS <= Wr_Buffer_A; |
io_state <= TAS_UB; |
|
when TAS_UB => |
tsnh_timer <= tsnh_timer - 1; |
if( or_reduce(tsnh_timer) = '0' )then |
io_state <= TPW_UB; |
end if; |
|
when TPW_UB => |
tcyc_timer <= tcyc_timer + 1; |
LCD_E <= '1'; |
LCD_DQ_U <= Wr_Buffer_U; |
if( tcyc_timer = TPW_DELAY )then |
io_state <= TCYC_UB; |
end if; |
|
when TCYC_UB => |
tcyc_timer <= tcyc_timer + 1; |
if( tcyc_timer >= TCYC_DELAY )then |
io_state <= INIT_LB; |
end if; |
|
when INIT_LB => |
tcyc_timer <= (others => '0'); |
io_state <= TPW_LB; |
if( fn_set = '1' )then |
fn_set <= '0'; |
io_state <= TPW_UB; |
end if; |
|
when TPW_LB => |
tcyc_timer <= tcyc_timer + 1; |
LCD_E <= '1'; |
LCD_DQ_U <= Wr_Buffer_L; |
if( tcyc_timer = TPW_DELAY )then |
io_state <= TCYC_LB; |
end if; |
|
when TCYC_LB => |
tcyc_timer <= tcyc_timer + 1; |
if( tcyc_timer >= TCYC_DELAY )then |
io_state <= DONE; |
end if; |
|
when DONE => |
IO_Done <= '1'; |
LCD_RS <= '0'; |
LCD_DQ_U <= (others => '0'); |
io_state <= IDLE; |
|
when others => |
null; |
end case; |
end if; |
end process; |
|
end architecture; |
/open8_urisc/trunk/VHDL/hd44780_8b.vhd
0,0 → 1,138
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_misc.all; |
|
entity hd44780_8b is |
generic( |
Tsu : integer := 40; -- ns |
Tpw : integer := 250; -- nS |
Tcyc : integer := 500; -- nS |
Clock_Frequency : real := 50000000.0; -- Hz |
Reset_Level : std_logic := '1' |
); |
port( |
Clock : in std_logic; |
Reset : in std_logic; |
-- |
Wr_Data : in std_logic_vector(7 downto 0); |
Wr_Reg : in std_logic; |
Wr_En : in std_logic; |
-- |
IO_Done : out std_logic; |
-- |
LCD_RS : out std_logic; |
LCD_E : out std_logic; |
LCD_DQ : out std_logic_vector(7 downto 0) |
); |
end entity; |
|
architecture behave of hd44780_8b is |
|
-- The ceil_log2 function returns the minimum register width required to |
-- hold the supplied integer. |
function ceil_log2 (x : in natural) return natural is |
variable retval : natural; |
begin |
retval := 1; |
while ((2**retval) - 1) < x loop |
retval := retval + 1; |
end loop; |
return retval; |
end function; |
|
constant CONV_NANOSECS : real := 0.000000001; |
|
constant Tsu_r : real := CONV_NANOSECS * real(Tsu); |
constant Tpw_r : real := CONV_NANOSECS * real(Tpw); |
constant Tcyc_r : real := CONV_NANOSECS * real(Tcyc); |
|
constant TCYC_i : integer := integer(Clock_Frequency * Tcyc_r); |
constant TCYC_BITS : integer := ceil_log2(TCYC_i); |
|
constant TCYC_DELAY : std_logic_vector(TCYC_BITS-1 downto 0) := |
conv_std_logic_vector(TCYC_i-1, TCYC_BITS); |
signal tcyc_timer : std_logic_vector(TCYC_BITS - 1 downto 0) := |
(others => '0'); |
|
constant TPW_i : integer := integer(Clock_Frequency * Tpw_r); |
constant TPW_DELAY : std_logic_vector(TCYC_BITS-1 downto 0) := |
conv_std_logic_vector(TPW_i-1, TCYC_BITS); |
|
constant TSU_i : integer := integer(Clock_Frequency * Tsu_r); |
constant TSU_BITS : integer := ceil_log2(TSU_i); |
constant TSU_DELAY : std_logic_vector(TSU_BITS - 1 downto 0) := |
conv_std_logic_vector(TSU_i-1,TSU_BITS); |
signal tsnh_timer : std_logic_vector(TSU_BITS-1 downto 0) := |
(others => '0'); |
|
type IO_STATES is (IDLE, INIT, IO_TAS, IO_TPW, IO_TCYC, DONE ); |
signal io_state : IO_STATES; |
|
signal Wr_Buffer : std_logic_vector(8 downto 0); |
alias Wr_Buffer_A is Wr_Buffer(8); |
alias Wr_Buffer_D is Wr_Buffer(7 downto 0); |
|
begin |
|
LCD_IO_proc: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
io_state <= IDLE; |
tcyc_timer <= (others => '0'); |
tsnh_timer <= (others => '0'); |
Wr_Buffer <= (others => '0'); |
IO_Done <= '0'; |
LCD_RS <= '0'; |
LCD_E <= '0'; |
LCD_DQ <= (others => '0'); |
elsif( rising_edge(Clock) )then |
IO_Done <= '0'; |
LCD_E <= '0'; |
case( io_state )is |
when IDLE => |
if( Wr_En = '1' )then |
Wr_Buffer <= Wr_Reg & Wr_Data; |
io_state <= INIT; |
end if; |
|
when INIT => |
tsnh_timer <= TSU_DELAY; |
tcyc_timer <= (others => '0'); |
LCD_RS <= Wr_Buffer_A; |
io_state <= IO_TAS; |
|
when IO_TAS => |
tsnh_timer <= tsnh_timer - 1; |
if( or_reduce(tsnh_timer) = '0' )then |
io_state <= IO_TPW; |
end if; |
|
when IO_TPW => |
tcyc_timer <= tcyc_timer + 1; |
LCD_E <= '1'; |
LCD_DQ <= Wr_Buffer_D; |
if( tcyc_timer = TPW_DELAY )then |
io_state <= IO_TCYC; |
end if; |
|
when IO_TCYC => |
tcyc_timer <= tcyc_timer + 1; |
if( tcyc_timer >= TCYC_DELAY )then |
io_state <= DONE; |
end if; |
|
when DONE => |
IO_Done <= '1'; |
LCD_RS <= '0'; |
LCD_DQ <= (others => '0'); |
io_state <= IDLE; |
|
when others => |
null; |
end case; |
end if; |
end process; |
|
end architecture; |
/open8_urisc/trunk/VHDL/o8_hd44780_if.vhd
0,0 → 1,417
-- Copyright (c)2013, 2020 Jeremy Seth Henry |
-- All rights reserved. |
-- |
-- Redistribution and use in source and binary forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- * Redistributions of source code must retain the above copyright |
-- notice, this list of conditions and the following disclaimer. |
-- * Redistributions in binary form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution, |
-- where applicable (as part of a user interface, debugging port, etc.) |
-- |
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY |
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY |
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-- |
-- VHDL Entity: o8_hd44780_if |
-- Description: Provides low-level access to "standard" character LCDs using |
-- the ST/HD44780(U) control ASIC wired in either 8-bit or |
-- reduced (4-bit) mode. |
-- All low-level timing of the control signals are handled by this |
-- module, allowing client firmware to use a simple register |
-- interface to program the LCD panel. |
-- |
-- Register Map |
-- Address Function |
-- Offset Bitfield Description Read/Write |
-- 0x0 AAAAAAAA LCD Register Write (Read-Write*) |
-- 0x1 AAAAAAAA LCD Data Write (Read-Write*) |
-- 0x2 AAAAAAAA LCD Rearm Init Timer (Read-Write*) |
-- 0x3 AAAAAAAA LCD Backlight (Read-Write) |
-- |
-- Note: Reading 0x0, 0x1 or 0x2 will report whether the panel is ready or not |
-- in the MSB (bit 7). 0x00 = NOT READY / 0x80 = READY |
-- |
-------------------------------------------------------------------------------- |
-- LCD Controller |
-------------------------------------------------------------------------------- |
-- |
-- LCD Instruction Set (Hitachi Compatible) |
-- Instruction RS RW D7 D6 D5 D4 D3 D2 D1 D0 Time |
------------------------------------------------------------------------ |
-- Clear Display | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1.52mS |
-- Return Home | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | x | 1.52mS |
-- Entry Mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ID| S | 37uS |
-- Display Pwr | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B | 37uS |
-- Cursor/Display Shift | 0 | 0 | 0 | 0 | 0 | 1 | SC| RL| x | x | 37uS |
-- Function Set | 0 | 0 | 0 | 0 | 1 | DL| N | F | x | x | 37uS |
-- Set CGRAM Address | 0 | 0 | 0 | 1 | A | A | A | A | A | A | 37uS |
-- Set DDRAM Address | 0 | 0 | 1 | A | A | A | A | A | A | A | 37uS |
|
-- LCD Instruction Set (New Haven) |
-- Instruction RS RW D7 D6 D5 D4 D3 D2 D1 D0 Time |
------------------------------------------------------------------------ |
-- Clear Display | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2.00mS |
-- Return Home | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | x | 600uS |
-- Entry Mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ID| S | 600uS |
-- Display Pwr | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B | 600uS |
-- Cursor/Display Shift | 0 | 0 | 0 | 0 | 0 | 1 | SC| RL| x | x | 600uS |
-- Function Set | 0 | 0 | 0 | 0 | 1 | DL| N | F | T | T | 600uS |
-- Set CGRAM Address | 0 | 0 | 0 | 1 | A | A | A | A | A | A | 600uS |
-- Set DDRAM Address | 0 | 0 | 1 | A | A | A | A | A | A | A | 600uS |
-- |
-- Notes: |
-- ID = Increment/Decrement DDRAM Address (1 = increment, 0 = decrement) |
-- S = Shift Enable (1 = Shift display according to ID, 0 = Don't shift) |
-- D = Display On/Off (1 = on, 0 = off) |
-- C = Cursor On/Off (1 = on, 0 = off) |
-- B = Cursor Blink (1 = block cursor, 0 = underline cursor) |
-- SC / RL = Shift Cursor/Display Right/Left (see data sheet - not needed for init) |
-- F = Font (0 = 5x8, 1 = 5x11) Ignored on 2-line displays (N = 1) |
-- N = Number of Lines (0 = 1 lines, 1 = 2 lines) |
-- DL = Data Length (0 = 4-bit bus, 1 = 8-bit bus) This is fixed at 1 in this module |
-- A = Address (see data sheet for usage) |
-- T = New Haven Only - Changes the character set (see data sheet) |
-- |
-- Revision History |
-- Author Date Change |
------------------ -------- --------------------------------------------------- |
-- Seth Henry 04/12/13 Design Start |
|
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
|
library work; |
use work.open8_pkg.all; |
|
entity o8_hd44780_if is |
generic( |
Use_4Bit_IF : boolean := TRUE; |
-- Bus IF timing |
Tsu : integer := 40; -- ns |
Tpw : integer := 250; -- nS |
Tcyc : integer := 500; -- nS |
-- Panel command timing |
Tpwrdly : integer := 40000; -- uS |
Tcldsp : integer := 2000; -- uS |
Tbusy : integer := 50; -- uS |
-- Contrast/Backlight |
Use_Backlight : boolean := FALSE; |
Default_Brightness : std_logic_vector(7 downto 0) := x"00"; |
Clock_Frequency : real; |
Address : ADDRESS_TYPE |
); |
port( |
Open8_Bus : in OPEN8_BUS_TYPE; |
Write_Qual : in std_logic := '1'; |
Rd_Data : out DATA_TYPE; |
Interrupt : out std_logic; |
-- |
LCD_E : out std_logic; |
LCD_RW : out std_logic; |
LCD_RS : out std_logic; |
LCD_DQ : out std_logic_vector(7 downto 0); |
LCD_BL : out std_logic |
); |
end entity; |
|
architecture behave of o8_hd44780_if is |
|
alias Clock is Open8_Bus.Clock; |
alias Reset is Open8_Bus.Reset; |
alias uSec_Tick is Open8_Bus.uSec_Tick; |
|
constant User_Addr : std_logic_vector(15 downto 2) |
:= Address(15 downto 2); |
alias Comp_Addr is Open8_Bus.Address(15 downto 2); |
signal Addr_Match : std_logic; |
|
alias Reg_Sel_d is Open8_Bus.Address(1 downto 0); |
signal Reg_Sel_q : std_logic_vector(1 downto 0) := "00"; |
signal Wr_En_d : std_logic := '0'; |
signal Wr_En_q : std_logic := '0'; |
alias Wr_Data_d is Open8_Bus.Wr_Data; |
signal Wr_Data_q : DATA_TYPE := x"00"; |
signal Rd_En_d : std_logic := '0'; |
signal Rd_En_q : std_logic := '0'; |
|
signal Rearm_Init : std_logic := '0'; |
|
signal Reg_Valid : std_logic := '0'; |
signal Reg_Sel : std_logic := '0'; |
signal Reg_Data : std_logic_vector(7 downto 0) := x"00"; |
|
signal Tx_Ready : std_logic := '0'; |
|
constant HW_TMR_BITS : integer := ceil_log2(Tpwrdly); |
constant TPWR_DELAY : std_logic_vector(HW_TMR_BITS-1 downto 0) := |
conv_std_logic_vector(Tpwrdly,HW_TMR_BITS); |
|
constant CLDSP_DELAY : std_logic_vector(HW_TMR_BITS-1 downto 0) := |
conv_std_logic_vector(Tcldsp,HW_TMR_BITS); |
|
constant BUSY_DELAY : std_logic_vector(HW_TMR_BITS-1 downto 0) := |
conv_std_logic_vector(Tbusy, HW_TMR_BITS); |
|
signal hw_timer : std_logic_vector(HW_TMR_BITS-1 downto 0); |
|
type CTRL_STATES is (INIT, PWR_WAIT, IDLE, PREP_WR, ISSUE_WR, WR_WAIT, |
BUSY_WAIT, ISSUE_INT ); |
|
signal ctrl_state : CTRL_STATES := INIT; |
|
signal Wr_Fnset : std_logic := '0'; |
signal Wr_Data : DATA_TYPE := x"00"; |
signal Wr_Reg : std_logic := '0'; |
signal Wr_En : std_logic := '0'; |
|
signal IO_Done : std_logic := '0'; |
|
signal LCD_Data : DATA_TYPE := x"00"; |
signal LCD_Addr : std_logic := '0'; |
|
-------------------------------------------------------------------------------- |
-- Backlight signals |
-------------------------------------------------------------------------------- |
|
signal LCD_Bright : DATA_TYPE := x"00"; |
|
begin |
|
-------------------------------------------------------------------------------- |
-- Open8 Register interface |
-------------------------------------------------------------------------------- |
|
Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; |
Wr_En_d <= Addr_Match and Open8_Bus.Wr_En and Write_Qual; |
Rd_En_d <= Addr_Match and Open8_Bus.Rd_En; |
|
io_reg: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
Reg_Sel_q <= "00"; |
Wr_En_q <= '0'; |
Wr_Data_q <= x"00"; |
Rd_En_q <= '0'; |
Rd_Data <= OPEN8_NULLBUS; |
|
Rearm_Init <= '0'; |
|
Reg_Valid <= '0'; |
Reg_Sel <= '0'; |
Reg_Data <= x"00"; |
|
LCD_Bright <= Default_Brightness; |
elsif( rising_edge( Clock ) )then |
Reg_Sel_q <= Reg_Sel_d; |
|
Rearm_Init <= '0'; |
|
Wr_En_q <= Wr_En_d; |
Wr_Data_q <= Wr_Data_d; |
Reg_Valid <= '0'; |
if( Wr_En_q = '1' )then |
case( Reg_Sel_q )is |
when "00" | "01" => |
Reg_Valid <= '1'; |
Reg_Sel <= Reg_Sel_q(0); |
Reg_Data <= Wr_Data_q; |
when "10" => |
Rearm_Init <= '1'; |
when "11" => |
LCD_Bright <= Wr_Data_q; |
when others => null; |
end case; |
end if; |
|
Rd_En_q <= Rd_En_d; |
Rd_Data <= OPEN8_NULLBUS; |
if( Rd_En_q = '1' )then |
case( Reg_Sel_q )is |
when "00" | "01" | "10" => |
Rd_Data(7) <= Tx_Ready; |
when "11" => |
Rd_Data <= LCD_Bright; |
when others => null; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------------------------------------------------------- |
-- LCD and Register logic |
-------------------------------------------------------------------------------- |
|
LCD_RW <= '0'; -- Permanently wire the RW line low |
|
LCD_Ctrl_proc: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
ctrl_state <= INIT; |
hw_timer <= (others => '0'); |
Wr_Fnset <= '0'; |
Wr_Data <= x"00"; |
Wr_Reg <= '0'; |
Wr_En <= '0'; |
Tx_Ready <= '0'; |
Interrupt <= '0'; |
elsif( rising_edge(Clock) )then |
Wr_En <= '0'; |
Tx_Ready <= '0'; |
Interrupt <= '0'; |
hw_timer <= hw_timer - uSec_Tick; |
case( ctrl_state )is |
|
when INIT => |
hw_timer <= TPWR_DELAY; |
ctrl_state <= PWR_WAIT; |
|
when PWR_WAIT => |
if( hw_timer = 0 )then |
ctrl_state <= IDLE; |
end if; |
|
when IDLE => |
Tx_Ready <= '1'; |
if( Rearm_Init = '1' )then |
ctrl_state <= INIT; |
elsif( Reg_Valid = '1' )then |
Wr_Reg <= Reg_Sel; |
Wr_Data <= Reg_Data; |
ctrl_state <= PREP_WR; |
end if; |
|
when PREP_WR => |
Wr_Fnset <= '0'; |
-- Trap on Function Set if we are in 4-bit mode, so that we can issue |
-- the first nibble twice. |
if( Use_4Bit_IF and |
Wr_Reg = '0' and |
Wr_Data(7 downto 4) = "0010" )then |
Wr_Fnset <= '1'; |
end if; |
ctrl_state <= ISSUE_WR; |
|
when ISSUE_WR => |
Wr_En <= '1'; |
hw_timer <= BUSY_DELAY; |
if( Wr_Reg = '0' and Wr_Data = x"01" )then |
hw_timer <= CLDSP_DELAY; |
end if; |
ctrl_state <= WR_WAIT; |
|
when WR_WAIT => |
if( IO_Done = '1' )then |
ctrl_state <= BUSY_WAIT; |
end if; |
|
when BUSY_WAIT => |
if( hw_timer = 0 )then |
ctrl_state <= ISSUE_INT; |
end if; |
|
when ISSUE_INT => |
Interrupt <= '1'; |
ctrl_state <= IDLE; |
|
when others => null; |
|
end case; |
|
end if; |
end process; |
|
-------------------------------------------------------------------------------- |
-- Low-level I/O drivers |
-------------------------------------------------------------------------------- |
|
IF_Type_4bit: if( Use_4Bit_IF )generate |
|
U_IO : entity work.hd44780_4b |
generic map( |
Tsu => Tsu, |
Tpw => Tpw, |
Tcyc => Tcyc, |
Clock_Frequency => Clock_Frequency, |
Reset_Level => Reset_Level |
) |
port map( |
Clock => Clock, |
Reset => Reset, |
-- |
Wr_Fnset => Wr_Fnset, |
Wr_Data => Wr_Data, |
Wr_Reg => Wr_Reg, |
Wr_En => Wr_En, |
-- |
IO_Done => IO_Done, |
-- |
LCD_RS => LCD_RS, |
LCD_E => LCD_E, |
LCD_DQ => LCD_DQ |
); |
|
end generate; |
|
IF_Type_8bit: if( not Use_4Bit_IF )generate |
|
U_IO : entity work.hd44780_8b |
generic map( |
Tsu => Tsu, |
Tpw => Tpw, |
Tcyc => Tcyc, |
Clock_Frequency => Clock_Frequency, |
Reset_Level => Reset_Level |
) |
port map( |
Clock => Clock, |
Reset => Reset, |
-- |
Wr_Data => Wr_Data, |
Wr_Reg => Wr_Reg, |
Wr_En => Wr_En, |
-- |
IO_Done => IO_Done, |
-- |
LCD_RS => LCD_RS, |
LCD_E => LCD_E, |
LCD_DQ => LCD_DQ |
); |
|
end generate; |
|
-------------------------------------------------------------------------------- |
-- Backlight control logic (optional) |
-------------------------------------------------------------------------------- |
|
Backlight_Disabled: if( not Use_Backlight )generate |
LCD_BL <= '0'; |
end generate; |
|
Backlight_Enabled: if( Use_Backlight )generate |
|
U_BL : entity work.vdsm8 |
generic map( |
Reset_Level => Reset_Level |
) |
port map( |
Clock => Clock, |
Reset => Reset, |
DACin => LCD_Bright, |
DACout => LCD_BL |
); |
|
end generate; |
|
end architecture; |