FILES DOWNLOAD
PS2 MASTER MODULE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity kb_test is
port (
clk, reset: in std_logic;
ps2d, ps2c: in std_logic;
tx : out std_logic
) ;
end kb_test;
architecture arch of kb_test is
signal scan_data, w_data: std_logic_vector ( 7 downto 0) ;
signal kb_not_empty , kb_buf_empty : std_logic;
signal key_code , ascii_code : std_logic_vector (7 downto 0 ) ;
begin
kb_code_unit : entity work.kb_code(arch)
port map(clk=>clk, reset=>reset , ps2d=>ps2d, ps2c=>ps2c,
rd_key_code=>kb_not_empty, key_code=>key_code,
kb_buf_empty=>kb_buf_empty);
uart_unit : entity work.uart (str_arch)
port map(clk=>clk, reset=>reset , rd_uart=>'0',
wr_uart=>kb_not_empty, rx=>'1',
w_data=> ascii_code , tx_full =>open ,
rx_empty=>open, r_data=>open, tx=>tx);
key2a_unit : entity work. key2ascii(arch)
port map(key_code=>key_code, ascii_code=>ascii_code);
kb_not_empty <= not kb_buf_empty;
end arch;
PS2 KEYBOARD FSM MODULE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity kb_code is
generic (W_SIZE : integer :=2) ; -- 2 A W_SIZE w o rd s i n FIFO
port (
clk, reset: in std_logic;
ps2d, ps2c: in std_logic;
rd_key_code : in std_logic ;
kb_buf_empty: out std_logic;
key_code : out std_logic_vector (7 downto 0 )
) ;
end kb_code;
architecture arch of kb_code is
constant BRK : std_logic_vector ( 7 downto 0 ):= "11110000";
-- FO ( b r e a k c o d e )
type statetype is (wait_brk, get_code) ;
signal state_reg , state_next : statetype;
signal scan_done_tick , got_code_tick: std_logic;
signal scan_out , w_data: std_logic_vector (7 downto 0 ) ;
begin
-- i n s t a n t i a t i o n
ps2_rx_unit: entity work.ps2_rx(arch)
port map ( clk => clk , reset => reset , rx_en => '1' ,
ps2d => ps2d , ps2c => ps2c ,
rx_done_tick=>scan_done_tick,
dout => scan_out ) ;
ggfifo_key_unit : entity work.fifo ( arch )
generic map(B=>8, W=>W_SIZE)
port map( clk => clk , reset => reset , rd => rd_key_code ,
wr => got_code_tick , w_data => scan_out ,
empty=>kb_buf_empty, full => open ,
r_data => key_code ) ;
-- FSM t o g e t t h e s c a n c o d e a f t e r FO r e c e i v e d
process ( clk , reset )
begin
if reset = '1' then
state_reg <= wait_BRK ;
elsif ( clk'event and clk = '1' ) then
state_reg <= state_next ;
end if ;
end process ;
process ( state_reg , scan_done_tick ,scan_out)
begin
got_code_tick <= '0' ;
state_next <= state_reg ;
case state_reg is
when wait_BRK => -- wait f o r F0 of brak code
if scan_done_tick = '1' and scan_out= BRK then
state_next <= get_code;
end if ;
when get_code => -- g e t t h e following scan code
if scan_done_tick = '1' then
got_code_tick <= '1' ;
state_next <= wait_BRK ;
end if ;
end case ;
end process ;
end arch ;
PS2 TRANSMITTER MODULE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity ps2_rx is
port (
clk, reset: in std_logic;
ps2d, ps2c: in std_logic; -- k e y d a t a , k e y c l o c k
rx_en : in std_logic ;
rx_done_tick: out std_logic;
dout: out std_logic_vector (7 downto 0)
) ;
end ps2_rx;
architecture arch of ps2_rx is
type statetype is (idle, dps, load);
signal state_reg , state_next : statetype;
signal filter_reg , filter_next : std_logic_vector (7 downto 0 ) ;
signal f_ps2c_reg, f_ps2c_next : std_logic ;
signal n_reg , n_next : unsigned (3 downto 0) ;
signal fall_edge : std_logic ;
signal b_reg , b_next : std_logic_vector (10 downto 0 ) ;
begin
--______________________________________________________________________________________-_-_--_-_--_ __
-- f i l t e r and f a l l i n g e d g e t i c k g e n e r a t i o n f o r ps2c
process ( clk , reset )
begin
if reset = '1' then
filter_reg <= ( others => '0' ) ;
f_ps2c_reg <= '0' ;
elsif ( clk'event and clk = '1' ) then
filter_reg <= filter_next ;
f_ps2c_reg <= f_ps2c_next ;
end if ;
end process ;
filter_next <= ps2c & filter_reg ( 7 downto 1);
f_ps2c_next <= '1' when filter_reg = "11111111" else
'0' when filter_reg = "00000000" else
f_ps2c_reg ;
fall_edge <= f_ps2c_reg and ( not f_ps2c_next ) ;
--______-_______-_-_-_-_-_-_-__-_---_--_------_--_--- --------------
--45 -- f s m d t o e x t r a c t t h e 8 - b i t d a t a
--____ _-______-______-_-________________________-_-______-____-_-__-_--------------- ---------_-_------
---_ r e g is t e r s
process ( clk , reset )
begin
if reset = '1' then
state_reg <= idle ;
n_reg <= ( others => '0' ) ;
b_reg <= ( others => '0' ) ;
elsif ( clk'event and clk = '1' ) then
state_reg <= state_next ;
n_reg <= n_next ;
b_reg <= b_next ;
end if ;
end process ;
-- n e x t - s t a t e l o g i c
process ( state_reg , n_reg,b_reg, fall_edge , rx_en , ps2d )
begin
rx_done_tick <= '0' ;
state_next <= state_reg ;
n_next <= n_reg ;
b_next <= b_reg ;
case state_reg is
when idle =>
if fall_edge = '1' and rx_en = '1' then
--s h if t i n s t a r t b i t
b_next <= ps2d & b_reg ( 10 downto 1);
n_next <= "1001" ;
state_next <= dps ;
end if ;
when dps => -- 8 d a t a + I p a r i t y + 1 s t o p
if fall_edge = '1' then
b_next <= ps2d & b_reg ( 10 downto 1 ) ;
if n_reg = 0 then
state_next <= load ;
else
n_next <= n_reg - 1;
end if ;
end if ;
when load =>
-- I e x t r a c l o c k t o c o m p l e t e f h e l a s t s h if t
state_next <= idle ;
rx_done_tick <='1';
end case ;
end process ;
-- o u t p u t
dout <= b_reg ( 8 downto 1); -- d a t a b i t s
end arch ;
FIFO BUFFER
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all ;
entity fifo is
generic (
B: natural:=8; -- number of b i t s
W: natural:=4 -- number o f a d d r e s s b i t s
);
port (
clk, reset: in std_logic;
rd, wr: in std_logic;
w_data: in std_logic_vector ( B - 1 downto 0) ;
empty, full : out std_logic;
r_data: out std_logic_vector ( B - 1 downto 0 )
);
end fifo;
architecture arch of fifo is
type reg_file_type is array (2**W-1 downto 0) of std_logic_vector ( B - 1 downto 0) ;
signal array_reg : reg_file_type ;
signal w_ptr_reg , w_ptr_next , w_ptr_succ : std_logic_vector (W-1 downto 0 ) ;
signal r_ptr_reg , r_ptr_next , r_ptr_succ:std_logic_vector ( W - 1 downto 0) ;
signal full_reg , empty_reg , full_next , empty_next :std_logic;
signal wr_op: std_logic_vector (1 downto 0 ) ;
signal wr_en : std_logic ;
begin
-- r e g is t e r f i l e
process (clk, reset)
begin
if (reset='1' ) then
array_reg <= ( others => ( others => '0' ) ) ;
elsif (clk'event and clk='1') then
if wr_en='1' then
array_reg(to_integer(unsigned(w_ptr_reg)))
<= w_data;
end if ;
end if ;
end process ;
-- r e a d p o r t
r_data <= array_reg(to_integer(unsigned(r_ptr_reg)));
--w r i t e e n a b l e d o n l y when FIFO is not f u l l
wr_en <= wr and ( not full_reg);
--
-- f if o c o n t r o l l o g i c
-- r e g is t e r f o r r e a d and w r i t e p o in t e r s
process (clk , reset)
begin
if (reset='1') then
w_ptr_reg <= ( others => '0' ) ;
r_ptr_reg <= ( others => '0' ) ;
full_reg <= '0' ;
empty_reg <= '1' ;
elsif(clk'event and clk='1') then
w_ptr_reg <= w_ptr_next ;
r_ptr_reg <= r_ptr_next ;
full_reg <= full_next;
empty_reg <= empty_next ;
end if ;
end process ;
-- s u c c e s s i v e p o in t e r v a l u e s
w_ptr_succ <= std_logic_vector (unsigned(w_ptr_reg)+1) ;
r_ptr_succ <= std_logic_vector(unsigned(r_ptr_reg)+1);
-- n e x t - s t a t e logic f o r r e a d and w r i t e p o in t e r s
wr_op <= wr & rd;
process (w_ptr_reg, w_ptr_succ ,r_ptr_reg ,r_ptr_succ ,wr_op,empty_reg , full_reg)
begin
w_ptr_next <= w_ptr_reg;
r_ptr_next <= r_ptr_reg;
full_next <= full_reg;
empty_next <= empty_reg ;
case wr_op is
when "00" => -- no op
when "01" => -- r e a d
if (empty_reg /= '1') then -- not e m p t y
r_ptr_next <= r_ptr_succ;
full_next <= '0' ;
if (r_ptr_succ=w_ptr_reg) then
empty_next <='1';
end if ;
end if ;
when "10" => -- w r i t e
if (full_reg /= '1' ) then -- if fifo not f u l l we write values
w_ptr_next <= w_ptr_succ;
empty_next <= '0' ;
if (w_ptr_succ=r_ptr_reg) then-- otherwise stop writing because is full, write pointer and read pointer point to the same place
full_next <='1';
end if ;
end if ;
when others => -- w r i t e / r e a d ;
w_ptr_next <= w_ptr_succ ;
r_ptr_next <= r_ptr_succ ;
end case ;
end process ;
-- out p u t
full <= full_reg;
empty <= empty_reg;
end arch;
UART FSM MODULE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity uart is
generic (
-- D e f a u l t s e t t in g :
-- 1 9 2 0 0 b a u d , 8 d a t a b i t s , 1 s t o p b i t , 2 ^ 2 FIFO
DBIT : integer :=8; -- # d a t a b i t s
SB_TICK: integer:=16; -- # t i c k s f o r s t o p b i t s , 1 6 / 2 4 / 3 2
DVSR: integer:= 163; -- baud r a t e d i v i s o r
DVSR_BIT: integer:=8; -- # b i t s of DVSR
FIFO_W: integer:=2 -- # a d d r b i t s of FIFO
-- for 1 / 1 . 5 / 2 s t o p b i t s
-- DVSR = 5 0 M / ( 1 6 * b a u d r a t e )
-- # w o r d s in FIFO=2^FIFO_W
) ;
port (
clk, reset: in std_logic;
rd_uart , wr_uart : in std_logic ;
rx: in std_logic;
w_data: in std_logic_vector ( 7 downto 0 ) ;
tx_full, rx_empty: out std_logic;
r_data: out std_logic_vector ( 7 downto 0) ;
tx: out std_logic
) ;
end uart;
architecture str_arch of uart is
signal rx_done_tick: std_logic;
signal tick: std_logic ;
signal tx_fifo_out : std_logic_vector ( 7 downto 0) ;
signal rx_data_out : std_logic_vector ( 7 downto 0) ;
signal tx_empty , tx_fifo_not_empty : std_logic ;
signal tx_done_tick : std_logic ;
begin
baud_gen_unit: entity work.mod_m_counter(arch)
generic map(M=>DVSR , N=>DVSR_BIT)
port map(clk=>clk, reset=>reset ,
q=>open , max_tick=>tick) ;
uart_rx_unit: entity work.uart_rx(arch)
generic map(DBIT=>DBIT, SB_TICK=>SB_TICK)
port map(clk=>clk, reset=>reset , rx=>rx,
s_tick=>tick, rx_done_tick=>rx_done_tick,
dout=>rx_data_out) ;
fifo_rx_unit: entity work.fifo(arch)
generic map(B=>DBIT , W=>FIFO_W)
port map(clk=>clk, reset=>reset , rd=>rd_uart ,
wr=>rx_done_tick , w_data=>rx_data_out ,
empty=>rx_empty, full=>open, r_data=>r_data);
fifo_tx_unit: entity work.fifo(arch)
generic map(B=>DBIT , W=>FIFO_W)
port map(clk=>clk, reset=>reset, rd=>tx_done_tick,
wr=>wr_uart, w_data=>w_data, empty=>tx_empty,
full=>tx_full, r_data=>tx_fifo_out);
uart_tx_unit : entity work.uart_tx(arch)
generic map ( DBIT => DBIT , SB_TICK => SB_TICK )
port map(clk=>clk, reset=>reset ,
tx_start=>tx_fifo_not_empty,
s_tick=>tick, din=>tx_fifo_out,
tx_done_tick=> tx_done_tick, tx=>tx);
tx_fifo_not_empty <= not tx_empty;
end str_arch;
MOD M COUNTER MODULE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity mod_m_counter is
generic (
N: integer := 4; -- number o f b i t s
M : integer := 10); -- m o d 4
port (
clk, reset: in std_logic;
max_tick: out std_logic;
q: out std_logic_vector ( N - 1 downto 0);
an: out std_logic_vector(3 downto 0);
sseg: out std_logic_vector ( 7 downto 0)
);
end mod_m_counter ;
architecture arch of mod_m_counter is
signal cath,off: std_logic ;
signal r_reg : unsigned ( N - 1 downto 0 ) ;
signal r_next : unsigned ( N - 1 downto 0 ) ;
begin
--enabling the fir
process (clk, reset)
begin
if (reset='1') then
r_reg <= ( others => '0' ) ;
elsif (clk'event and clk='1') then
r_reg <= r_next;
end if ;
end process ;
--n e x t - s t a t e l o g i c
r_next <= ( others => '0' ) when r_reg=(M-1) else
r_reg + 1;
-- o u t p u t l o g i c
q <= std_logic_vector(r_reg);
max_tick <= '1' when r_reg=(M-1) else '0' ;
end arch;
UART RECEIVER
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity uart_rx is
generic (
DBIT : integer := 8 ; -- # data b i t s
SB_TICK: integer := 16 -- # t i c k s f o r stop b i t s
) ;
port (
clk , reset : in std_logic ;
rx : in std_logic ;
s_tick : in std_logic ;
rx_done_tick : out std_logic ;
dout : out std_logic_vector ( 7 downto 0)
) ;
end uart_rx ;
architecture arch of uart_rx is
type state_type is ( idle , start , data , stop ) ;
signal s_reg , s_next : unsigned ( 3 downto 0) ;
signal n_reg , n_next : unsigned ( 2 downto 0) ;
signal b_reg , b_next : std_logic_vector ( 7 downto 0) ;
signal state_reg , state_next : state_type ;
begin
-- FSMD s t a t e & data r e g is t e r s
process ( clk , reset )
begin
if reset = '1' then
state_reg <= idle ;
s_reg <= ( others => '0' ) ;
n_reg <= ( others => '0' ) ;
b_reg <= ( others => '0' ) ;
elsif ( clk'event and clk = '1' ) then
state_reg <= state_next ;
s_reg <= s_next ;
n_reg <= n_next ;
b_reg <= b_next ;
end if ;
end process ;
process ( state_reg , s_reg , n_reg , b_reg , s_tick, rx )
begin
-- n e x t - s t a t e l o g i c & data p a t h f u n c t i o n a l u n i t s / r o u t i n g
state_next <= state_reg ;
s_next <= s_reg ;
n_next <= n_reg ;
b_next <= b_reg ;
rx_done_tick <= '0' ;
case state_reg is
when idle =>
if rx = '0' then
state_next <= start ;
s_next <= ( others => '0' ) ;
end if ;
when start =>
if ( s_tick = '1') then
if s_reg = 7 then
state_next <= data ;
s_next <= ( others => '0' ) ;
n_next <= ( others => '0' ) ;
else
s_next <= s_reg + 1 ;
end if ;
end if ;
when data =>
if ( s_tick = '1') then
if s_reg = 15 then
s_next <= ( others => '0' ) ;
b_next <= rx & b_reg ( 7 downto 1) ;
if n_reg = (DBIT - 1) then
state_next <= stop ;
else
n_next <= n_reg + 1 ;
end if ;
else
s_next <= s_reg + 1;
end if ;
end if ;
when stop =>
if ( s_tick = '1') then
if s_reg=(SB_TICK - 1) then
state_next <= idle;
rx_done_tick <='1';
else
s_next <= s_reg + 1 ;
end if ;
end if ;
end case ;
end process ;
dout <= b_reg ;
end arch;
UART TRANSMITTER
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity uart_tx is
generic(
DBIT : integer :=8 ; -- # data b i t s
SB_TICK: integer :=16 -- # t i c k s f o r stop b i t s
);
port (
clk, reset: in std_logic;
tx_start : in std_logic;
s_tick: in std_logic ;
din: in std_logic_vector ( 7 downto 0) ;
tx_done_tick: out std_logic;
tx: out std_logic
) ;
end uart_tx ;
architecture arch of uart_tx is
type state_type is (idle, start, data, stop);
signal state_reg, state_next : state_type;
signal s_reg , s_next : unsigned (3 downto 0) ;
signal n_reg , n_next : unsigned (2 downto 0) ;
signal b_reg , b_next : std_logic_vector (7 downto 0 ) ;
signal tx_reg , tx_next : std_logic ;
-- FSMD s t a t e C? data r e g is t e r s
begin
process (clk, reset)
begin
if reset= '1' then
state_reg <= idle;
s_reg <= ( others => '0' ) ;
n_reg <= ( others => '0' ) ;
b_reg <= ( others => '0' ) ;
tx_reg <= '1';
elsif ( clk'event and clk = '1' ) then
state_reg <= state_next;
s_reg <= s_next;
n_reg <= n_next;
b_reg <= b_next;
tx_reg <= tx_next;
end if ;
end process ;
-- n e x t - s t a t e l o g i c & data p a t h f u n c t i o n a l u n i t s / r o u t i n g
process (state_reg , s_reg ,n_reg ,b_reg, s_tick,tx_reg,tx_start,din)
begin
state_next <= state_reg;
s_next <= s_reg;
n_next <= n_reg;
b_next <= b_reg;
tx_next <= tx_reg ;
tx_done_tick <= '0' ;
case state_reg is
when idle =>
tx_next <= '1' ;
if tx_start = '1' then
state_next <= start ;
s_next <= ( others => '0' ) ;
b_next <= din ;
end if ;
when start =>
tx_next <= '0' ;
if ( s_tick = '1') then
if s_reg = 15 then
state_next <= data ;
s_next <= ( others => '0' ) ;
n_next <= ( others => '0' ) ;
else
s_next <= s_reg + 1 ;
end if ;
end if ;
when data =>
tx_next <= b_reg(0);
if ( s_tick = '1') then
if s_reg = 15 then
s_next <= ( others => '0' ) ;
b_next <= '0' & b_reg ( 7 downto 1) ;
if n_reg = ( DBIT -1) then
state_next <= stop ;
else
n_next <= n_reg + 1 ;
end if ;
else
s_next <= s_reg + 1;
end if ;
end if ;
when stop =>
tx_next <= '1' ;
if ( s_tick = '1') then
if s_reg = (SB_TICK -1) then
state_next <= idle ;
tx_done_tick <= '1';
else
s_next <= s_reg + 1;
end if ;
end if ;
end case ;
end process ;
tx <= tx_reg ;
end arch ;
KEYBOARS TO ASCII MODULE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity key2ascii is
port(
key_code : in std_logic_vector ( 7 downto 0 ) ;
ascii_code : out std_logic_vector ( 7 downto 0)
);
end key2ascii ;
architecture arch of key2ascii is
begin
with key_code select
ascii_code <=
"00110000"when"01000101",--0
"00110001"when"00010110",--1
"00110010"when"00011110",--2
"00110011"when"00100110",--3
"00110100"when"00100101",--4
"00110101"when"00101110",--5
"00110110"when"00110110",--6
"00110111"when"00111101",--7
"00111000"when"00111110",--8
"00111001"when"01000110",--9
"01000001"when"00011100",--A
"01000010"when"00110010",--B
"01000011"when"00100001",--C
"01000100"when"00100011",--D
"01000101"when"00100100",--E
"01000110"when "00101011",--F
"01000111"when "00110100",--G
"01001000"when "00110011",--H
"01001001"when "01000011",--I
"01001010"when "00111011",--J
"01001011"when "01000010",--K
"01001100"when "01001011",--L
"01001101"when "00111010",--M
"01001110"when "00110001",--N
"01001111"when "01000100",--0
"01010000"when "01001101",--P
"01010001"when "00010101",--Q
"01010010"when "00101101",--R
"01010011"when "00011011",--S
"01010100"when "00101100",--T
"01010101"when "00111100",--U
"01010110"when "00101010",--V
"01010111"when "00011101",--W
"01011000"when "00100010",--X
"01011001"when "00110101",--Y
"01011010"when "00011010",--Z
"10110000"when "00001110",--'
"00101101"when "01001110",---
"00111101"when "01010101",--=
"01011011"when "01010100",--[
"01011101"when "01011011",--]
"01011100"when "01011101",--\
"00111011"when "01001100",--;
"10010011"when "01010010",--"
"00101100"when "01000001",--,
"00101110"when "01001001",--.
"00101111"when "01001010",--/
"00100000"when "00101001",--(space)
"00001101"when "01011010",--(enter, cr)
"00001000"when "01100110",--(backspace)
"00101010"when others;
end arch;
CONSTRAINT FILE
#Created by Constraints Editor (xc3s250e-tq144-4) - 2017/07/29
NET "clk" LOC = "P129"; #TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 50 MHz HIGH 50%;
#8I/Os_2 (Input)
NET "reset" LOC = "p94" ;
#16I/Os_1 (output)
NET "ps2d" LOC = "p126" ;
NET "ps2c" LOC = "p125" ;
NET "tx" LOC = "p58" ; # to the tx in the rs232 module
TUTORIAL ON HOW TO ADD CLOCK TIMING CONSTRAINTS IN A MODULE
No comments:
Post a Comment