FILES DOWNLOAD
MASTER UART CONTROLLER:
Library ieee;
use ieee. std_logic_1164.all ;
use ieee . numeric_std.all ;
entity uart_test is
port (
clk, reset: in std_logic;
btn: std_logic_vector ( 2 downto 0 ) ;
rx: in std_logic;
tx: out std_logic;
sseg : out std_logic_vector ( 6 downto 0) ;
an: out std_logic_vector (3 downto 0 );
led: out std_logic_vector ( 7 downto 0 )
) ;
end uart_test;
architecture arch of uart_test is
signal tx_full , rx_empty : std_logic;
signal rec_data ,rec_data1 : std_logic_vector ( 7 downto 0 ) ;
signal btn_tick: std_logic;
-- i n s t a n t i a t e u a r t
begin
uart_unit: entity work.uart(str_arch)
port map(clk=>clk, reset=>reset , rd_uart=>btn_tick,
wr_uart=>btn_tick, rx=>rx, w_data=>rec_data1,tx_full=>tx_full,
rx_empty=>rx_empty,
r_data=>rec_data, tx=>tx);
-- i n s t a n t i a t e d e b o u n c e c i r c u i t
btn_db_unit : entity work.debounce(exp_fsmd_arch)
port map(clk=>clk, reset=>reset , sw=>btn(0),
db_level=>open, db_tick=>btn_tick);
-- i n c r e m e n t e d d a t a l o o p b a c k
rec_data1 <= std_logic_vector(unsigned(rec_data)+1);
-- l e d d is p l a y
led <= rec_data;
process(rx_empty)
begin
if rx_empty = '1' then
sseg <= "1000000";
else
sseg <="0001110";
--sseg <= '0' & ( not tx_full) & "00" & ( rx_empty) & "000";
end if;
end process;
an <= "0001";
end arch; --6542130
--"0001000" when "1110",--e
--"0001110" when others;--f
-------------------------------------------------
-- Encoder
-------------------------------------------------
-- HEX-to-seven-segment decoder
-- segment encoding
-- 0
-- ---
-- 5 | | 1
-- --- <------6
-- 4 | | 2
-- ---
-- 3
UART 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
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;
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 TX
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 ;
DEBOUNCING MODULE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity debounce is
port(
clk,reset : in std_logic;
sw:in std_logic;
db_level, db_tick: out std_logic
);
end debounce ;
architecture exp_fsmd_arch of debounce is--20ms is typically used to debounce --666.7hz -- 3Mhz
constant N : integer :=21; -- f i l t e r of (2 ^ N) * 1.49 ms = 40ms debounce interval -------1.49ms is the period of my clock with frequency 666.7 ----1/666.7=1.49ms (2^X) * 1.49ms =40ms ----2^X = 40ms/1.49ms--- 2^X= 27.97----- log2 (27.97)= X --- X= 4.80--- 2^5 * 1.49ms= 40ms
type state_type is ( zero , wait0 , one , wait1); --the signals below we create can have 4 states
signal state_reg , state_next : state_type; -- these signals
signal q_reg , q_next : unsigned ( N-1 downto 0 ) ;
signal q_load , q_dec , q_zero : std_logic ; --we use these signals as markers to go to the next stage in the design
begin
-- FSMD s t a t e C? d a t a r e g is t e r s
process (clk ,reset)
begin
if reset = '1' then -- if we reset we clear everything and wait for inputs
state_reg <= zero ; -- this is the state of the input
q_reg <= ( others => '0' ) ; --this is the state of the design which will progress depending of what happens with the input
elsif( clk'event and clk = '1' ) then --if rising edge of the clock
state_reg <= state_next ; -- state_next which is the signal that will be changing goes to the signal that wont change for the moment and that will be used for display until updated
q_reg <= q_next ; -- we update state of the design in q reg (nosrmally anything that is _next is the one that changes and stored in the one that doesnt change)
end if ;
end process ;
-- FSMD d a t a p a t h ( c o u n t e r ) n e x t - s t a t e
q_next<= (others => '1') when q_load = '1' else ---we decremetnt the states of the FSM if conditions met
q_reg - 1 when q_dec = '1' else
q_reg ;
q_zero<= '1' when q_next = 0 else '0' ;
--FSMD c o n t r o l p a t h n e x t - s t a t e
process ( state_reg ,sw,q_zero)
begin
q_load <= '0' ; --load the value of actual voltage state
q_dec <= '0' ; --decrement states
db_tick <= '0' ;-- if there has been a debounce 1
state_next <= state_reg ;
case state_reg is
--from 0 to 1
when zero => -- when is a 0
db_level <= '0' ; --voltage level is 0 transition to 1 below
if ( sw = '1') then -- if there is an input
state_next <= wait1; --wait some time until 1 hs been there for a while
q_load <= '1'; --load a 1
end if ;
when wait1=>
db_level <= '0' ; -- voltage level 0 as there has not been a real input
if ( sw = '1' ) then
q_dec <= '1'; -- decrement states
if ( q_zero = '1' ) then
state_next <= one ;
db_tick <= '1'; -- debounced
end if ;
else -- sw = '0'
state_next<= zero ; -- --REMAIN AS 0
end if ;
-- from 1 to 0
when one => --transition from 1 to 0
db_level <= '1'; -- if voltage level is 1 then wait until 0 is confirmed
if ( sw = '0' ) then
state_next <= wait0 ;
q_load <= '1';
end if ;
when wait0 =>
db_level <= '1'; -- voltage level set as 1 as input has been stable for a while
if ( sw = '0' ) then
q_dec <= '1';
if( q_zero = '1' ) then
state_next<= zero ;
end if ;
else
state_next<= one ;
end if ;
end case ;
end process ;
end exp_fsmd_arch ;
CONSTRAINT FILE
#8I/Os_2 (Input)
NET "reset" LOC = "p94" ;
#16I/Os_1 (output)
NET "led[0]" LOC = "p126" ;
NET "led[1]" LOC = "p125" ;
NET "led[2]" LOC = "p124" ;
NET "led[3]" LOC = "p123" ;
NET "led[4]" LOC = "p122" ;
NET "led[5]" LOC = "p117" ;
NET "led[6]" LOC = "p116" ;
NET "led[7]" LOC = "p113" ;
#8I/Os_2 (Input)
NET "btn[0]" LOC = "p93" ;
NET "btn[1]" LOC = "p92" ;
NET "btn[2]" LOC = "p91" ;
#8I/Os_1
NET "rx" LOC = "p54" ;
NET "tx" LOC = "p58" ;
NET "an[0]" LOC = "p71" ;
NET "an[1]" LOC = "p75" ;
NET "an[2]" LOC = "p77" ;
NET "an[3]" LOC = "p82" ;
#16I/Os_2
#NET "sseg[7]" LOC = "p60" ;
NET "sseg[6]" LOC = "p63" ;
NET "sseg[5]" LOC = "p67" ;
NET "sseg[4]" LOC ="p70" ;
NET "sseg[3]" LOC ="p74" ;
NET "sseg[3]" LOC = "p76" ;
NET "sseg[2]" LOC = "p81" ;
NET "sseg[0]" LOC = "p83" ;
#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%;
TUTORIAL ON HOW TO ADD CLOCK TIMING CONSTRAINTS IN A MODULE
No comments:
Post a Comment