-- ========================================== -- | DK_21 ... Radic pro desku Disp_Kbd_2. | -- ========================================== -- -- Treti upravena verze. -- Pridano vkladani cekacich taktu do cyklu displeje. -- ---------------------------------------------------------- -- Rizeni LCD displeje je upraveno pro alfanumericky displej -- Batron BT 42005. -- -- IOB je programovatelne obousmerny, -- IOC0 a IOC1 jsou vstupy, -- IOC2 a IOC3 jsou vystupy. -- ---------------------------------------------------------- -- Adresovani: -- -- 011x.xxxx.xxxx.xxxx.xxxx.xaaa -- |_| |_| -- CPU DK_2 -- -- -- aaa vyznam -- _________________________ -- -- 000 -- 001 -- 010 -- 011 -- 100 -- 101 -- 110 -- 111 -- ---------------------------------------------------------- -- Generovani cekacich taktu -- -- Pro pripojeni displeje BT 42005 se musi prodlouzit zapisovy -- a cteci cykl vlozenim cekacich taktu. H8S musi byt na- -- programovan tak, aby reagoval na vnejsi signal /WAIT. Pocet -- programove vlozenych TW neni vyznamny. -- -- TACT_C 0 1 2 3 4 5 6 7 8 9 A B C D -- : T1: T2: Tw: Tw: Tw: Tw: Tw: Tw: Tw: Tw: Tw: Tw: Tw: T3: -- CLOCK |-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|- -- -- DISP_CS _|-------------------------------------------------------|_ -- -- /WAIT ----|___________________________________________|---------- -- -- EN_DISP ________________|---------------------------------------|__ -- ------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; entity DK_2 is port ( -- Sbernice Hitachi ADDR: in STD_LOGIC_VECTOR (2 downto 0); CPU_DATA: inout STD_LOGIC_VECTOR (7 downto 0); RD: in STD_LOGIC; HWR: in STD_LOGIC; CS3: in STD_LOGIC; CLOCK: in STD_LOGIC; WAITX: out STD_LOGIC; RESET: in STD_LOGIC; -- Klavesnice KBD_ROW: out STD_LOGIC_VECTOR (3 downto 0); KBD_COLUMN: in STD_LOGIC_VECTOR (7 downto 0); -- Displej DISP_PORT: inout STD_LOGIC_VECTOR (7 downto 0); EN_DISP: buffer STD_LOGIC; -- aktivni je H ( -|_ ) RS_DISP: out STD_LOGIC; -- L = ctrl, H = data RW_DISP: buffer STD_LOGIC; -- L = WR, H = RD -- IO porty a LED LED1: buffer STD_LOGIC; LED2: buffer STD_LOGIC; IOB: inout STD_LOGIC_VECTOR (7 downto 0); IOCI: in STD_LOGIC_VECTOR (1 downto 0); IOCO: buffer STD_LOGIC_VECTOR (1 downto 0) ); -- Pomocne signaly - vyber registru signal DISP_CS: STD_LOGIC; -- Pro displej je platna adresa a CS3 signal KBD_WR: STD_LOGIC; -- Zapis radku klavesnice signal KBD_RD: STD_LOGIC; -- Cteni radku klavesnice signal IOC_WR: STD_LOGIC; -- Zapis IOC portu signal IOC_RD: STD_LOGIC; -- Cteni IOC portu signal IOB_WR: STD_LOGIC; -- Zapis IOB portu signal IOB_RD: STD_LOGIC; -- Cteni IOB portu signal IOB_DIR_WR: STD_LOGIC; -- Zapis IOC portu signal IOB_REG: STD_LOGIC_VECTOR(7 downto 0); -- Registr IOB signal IOB_DIR: STD_LOGIC_VECTOR(7 downto 0); -- Smer IOB: 0 = Out, 1 = In -- signal CTRL_WR: STD_LOGIC; -- Zapis do ridiciho registru -- signal CTRL_RD: STD_LOGIC; -- Cteni ridiciho registru end DK_2; -- ----------------------------------------------------------------------------- architecture DK_2_arch of DK_2 is begin -- CS pro jednotlive obvody - vse aktivni v 0 KBD_WR <= '0' when ADDR = "010" and CS3 = '0' and HWR = '0' else '1'; KBD_RD <= '0' when ADDR = "010" and CS3 = '0' and RD = '0' else '1'; IOB_WR <= '0' when ADDR = "100" and CS3 = '0' and HWR = '0' else '1'; IOB_RD <= '0' when ADDR = "100" and CS3 = '0' and RD = '0' else '1'; IOB_DIR_WR <= '0' when ADDR = "110" and CS3 = '0' and HWR = '0' else '1'; IOC_WR <= '0' when ADDR = "101" and CS3 = '0' and HWR = '0' else '1'; IOC_RD <= '0' when ADDR = "101" and CS3 = '0' and RD = '0' else '1'; DISP_CS <= '1' when ADDR(2 downto 1) = "00" and CS3 = '0' else '0'; -- aktivni je H !! -- IOB_DIR_RD <= '0' when ADDR = "011" and CS3 = '0' and RD = '0' else -- '1'; -- CTRL_RD <= '0' when ADDR = "101" and CS3 = '0' and RD = '0' else -- '1'; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Vystupni signaly R/W a RS pro displej RS_DISP <= ADDR(0); LED1 <= NOT EN_DISP; -- sviti pri praci s displejem LED2 <= '0'; -- trvale sviti -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Cteni dat z klavesnice, displeje, status a control CPU_DATA <= -- Displej: DISP_PORT when DISP_CS = '1' and RD = '0' else -- Klavenice - sloupce: KBD_COLUMN when KBD_RD = '0' else -- IOB: IOB when IOB_RD = '0' else -- IOC: "0000" & IOCO(1 downto 0) & IOCI(1 downto 0) when IOC_RD = '0' else -- Kdyz neni cteni: "ZZZZZZZZ"; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Vystup dat na port displeje process(CPU_DATA, DISP_CS, CLOCK, HWR) begin if DISP_CS = '1' and HWR = '0' then -- dokud je aktivni zapis DISP_PORT <= CPU_DATA; else -- presah dat az do _|- hodin if CLOCK'EVENT and CLOCK = '1' then DISP_PORT <= "ZZZZZZZZ"; end if; end if; end process; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Generovani signalu RW_DISP. Je zpozden k sestupne hrane CLOCK. process(CLOCK, RD) begin if CLOCK'EVENT and CLOCK = '0' then RW_DISP <= not RD; end if; end process; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Zapis do registru KBD. Zapisuje se pri koncove hrane KBD_WR. process(KBD_WR, CPU_DATA) begin if KBD_WR'EVENT and KBD_WR = '1' then -- Zapis na vystupni port klavesnice KBD_ROW <= CPU_DATA(3 downto 0); end if; end process; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Zapis do registru IOCO. process(IOC_WR, CPU_DATA) begin if IOC_WR'EVENT and IOC_WR = '1' then -- Zapis do registru IOCO IOCO(1 downto 0) <= CPU_DATA(3 downto 2); end if; end process; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Zapis do registru prepinani smeru IOB. process(IOB_DIR_WR, CPU_DATA, IOB_DIR, RESET) begin if RESET = '0' then IOB_DIR <= "11111111"; -- vstup elsif IOB_DIR_WR'EVENT and IOB_DIR_WR = '1' then -- Zapis do registru smeru IOB IOB_DIR <= CPU_DATA; end if; end process; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Zapis do registru IOB_REG. process(IOB_WR, CPU_DATA, RESET) begin if RESET = '0' then IOB_REG <= "00000000"; elsif IOB_WR'EVENT and IOB_WR = '1' then IOB_REG <= CPU_DATA; end if; end process; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Vystup dat na IOB. process(IOB_REG, IOB_DIR) begin for ii in 0 to 7 loop if IOB_DIR(ii) = '0' then IOB(ii) <= IOB_REG(ii); -- vystupni bit else IOB(ii) <= 'Z'; -- vstupni bit end if; end loop; end process; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Generovani signalu WAIT a EN_DISP. process(DISP_CS, CLOCK) -- tact inserted je cislo taktu pred kterym se zrusi WAITX constant TACT_W_CLEAR: natural range 0 to 15 := 12; variable TACT_COUNTER: natural range 0 to 15; begin if CLOCK'EVENT and CLOCK = '1' then if DISP_CS = '1' then -- pocitaji se takty v cyklu displeje TACT_COUNTER := TACT_COUNTER + 1; else -- konec cyklu displej TACT_COUNTER := 0; end if; -- nastaveni EN_DISP. Zrusi se 2 takty po WAITX (posledni TW a T3). if TACT_COUNTER > 3 and TACT_COUNTER < TACT_W_CLEAR+2 and DISP_CS = '1' then EN_DISP <= '1'; else EN_DISP <= '0'; end if; -- nastaveni WAITX (WAIT pro CPU prochazi na desce pres invertor) if TACT_COUNTER > 0 and TACT_COUNTER < TACT_W_CLEAR then WAITX <= '1'; else WAITX <= '0'; end if; end if; end process; end DK_2_arch; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --