8.
5
QUA UART
kí
terminal
Project BAI_801_FPGA_LCD_DEM_PC_UART
FPGA_LCD_DEM_PC_UART
a.
FPGA_LCD_DEM_PC_UART
UART_CONTROLLER LCD_KHOITAO_HIENTHI
uart_rx uart_recv_data
uart_rx
fifo_uart_rx_data_rd LCD_HANG_1
uart_ena_rd LCD_DB
fifo_uart_rx_rd
ckht
uart_rx_empty ena_rx LCD_RS
fifo_uart_rx_empty
ckht LCD_E
rst LCD_CK
rst LCD_WR
ckht LCD_RST
uart_tx
uart_tx uart_trans_data
fifo_uart_tx_data_wr ena_db
uart_ena_tx
fifo_uart_tx_wr
uart_tx_full sw0
fifo_uart_tx_full dem BELL
DEM_8BIT HEXTOBCD_8BIT
CHIA_10ENA
ckht
ckht ena5hz ena_db donvi H2_15
ckht dem chuc H2_14
btn_n0 rst
rst
sw0 tram H2_13
ena_ss
LCD_GAN_DULIEU_HIENTHI_H2
Hình 8-10.
377
b.
entity FPGA_LCD_DEM_PC_UART is
Port( CKHT: in STD_LOGIC;
BTN_N0: in STD_LOGIC;
SW0: in STD_LOGIC;
BELL: OUT STD_LOGIC;
UART_RX: in STD_LOGIC;
UART_TX: out STD_LOGIC;
LCD_E: out STD_LOGIC;
LCD_RS: out STD_LOGIC;
LCD_RW: out STD_LOGIC;
LCD_DB: out STD_LOGIC_VECTOR (7 downto 0));
end FPGA_LCD_DEM_PC_UART;
architecture Behavioral of FPGA_LCD_DEM_PC_UART is
SIGNAL RST: STD_LOGIC;
SIGNAL LCD_HANG_1_R: STD_LOGIC_VECTOR(127 DOWNTO 0);
SIGNAL LCD_HANG_1_N: STD_LOGIC_VECTOR(127 DOWNTO 0);
SIGNAL LCD_HANG_2: STD_LOGIC_VECTOR(127 DOWNTO 0);
signal UART_TX_FULL: STD_LOGIC;
signal UART_RX_EMPTY: STD_LOGIC;
signal UART_RECV_DATA: STD_LOGIC_VECTOR(7 downto 0);
signal UART_TRANS_DATA: STD_LOGIC_VECTOR(7 downto 0);
signal UART_ENA_TX: STD_LOGIC;
signal UART_ENA_RD: STD_LOGIC;
signal ENA_DB: STD_LOGIC;
signal ENA_RX: STD_LOGIC;
signal DEM: STD_LOGIC_VECTOR(7 downto 0);
SIGNAL DONVI: STD_LOGIC_VECTOR (3 downto 0);
SIGNAL CHUC: STD_LOGIC_VECTOR (3 downto 0);
SIGNAL TRAM: STD_LOGIC_VECTOR (3 downto 0);
begin
RST <= NOT BTN_N0;
BELL <= '1';
LCD_RW <= '0';
ENA_RX <= CKHT;
CHIA_10ENA: ENTITY WORK.CHIA_10ENA
PORT MAP( CKHT => CKHT,
ENA5HZ => ENA_DB );
UART_UNIT:entity WORK.UART_CONTROLLER
port map( CKHT => CKHT,
RST => RST,
378
UART_RX => UART_RX,
UART_TX => UART_TX,
FIFO_UART_RX_ENA_RD => UART_ENA_RD,
FIFO_UART_RX_DATA_RD => UART_RECV_DATA,
FIFO_UART_RX_EMPTY => UART_RX_EMPTY,
FIFO_UART_TX_ENA_WR => UART_ENA_TX,
FIFO_UART_TX_DATA_WR => UART_TRANS_DATA,
FIFO_UART_TX_FULL => UART_TX_FULL);
PROCESS(UART_TX_FULL, ENA_DB, SW0, DEM)
BEGIN
UART_TRANS_DATA <= DEM; -
- GAN DL GOI DI
IF UART_TX_FULL = '0' THEN
UART_ENA_TX <= ENA_DB AND SW0; --
TAO XUNG PHAT
ELSE UART_ENA_TX <= '0';
END IF;
END PROCESS;
UART_ENA_RD <= ENA_RX AND (NOT UART_RX_EMPTY); --
TAO XUNG DOC
PROCESS(CKHT, RST)
BEGIN
IF RST = '1' THEN
LCD_HANG_1_R <= X"20202020202020202020202020202020";
ELSIF FALLING_EDGE(CKHT) THEN
LCD_HANG_1_R <= LCD_HANG_1_N;
END IF;
END PROCESS;
LCD_HANG_1_N <=
UART_RECV_DATA & LCD_HANG_1_R(127 DOWNTO 8)
WHEN UART_ENA_RD = '1'
ELSE LCD_HANG_1_R;
DEM_8BIT: ENTITY WORK.DEM_8BIT
PORT MAP ( CKHT => CKHT,
RST => RST,
ENA_SS => SW0,
ENA_DB => ENA_DB,
DEM => DEM);
HEXTOBCD: ENTITY WORK.HEXTOBCD_8BIT
PORT MAP ( SOHEX8BIT => DEM,
DONVI => DONVI,
CHUC => CHUC,
TRAM => TRAM);
LCD_GAN_DULIEU_HIENTHI: ENTITY WORK.
LCD_GAN_DULIEU_HIENTHI_H2
PORT MAP( H2_13 => TRAM,
379
H2_14 => CHUC,
H2_15 => DONVI,
LCD_HANG_2 => LCD_HANG_2);
LCD_KHOITAO_HIENTHI: ENTITY WORK.
LCD_KHOITAO_HIENTHI
PORT MAP( LCD_DB => LCD_DB,
LCD_RS => LCD_RS,
LCD_E => LCD_E,
LCD_RST => RST,
LCD_CK => CKHT,
LCD_HANG_1 => LCD_HANG_1_R,
LCD_HANG_2 => LCD_HANG_2);
end Behavioral;
entity UART_CONTROLLER is
GENERIC( DBIT: integer:=8;
SB_TICK: integer:=16;
DVSR: integer:=163;--326cho 100MHz
DVSR_BIT: integer:=9;
FIFO_W: integer:=2);
Port( CKHT: in STD_LOGIC;
RST: in STD_LOGIC;
UART_RX: in STD_LOGIC;
UART_TX: out STD_LOGIC;
FIFO_UART_RX_ENA_RD: in STD_LOGIC;
FIFO_UART_RX_DATA_RD: out
STD_LOGIC_VECTOR (7 downto 0);
FIFO_UART_RX_EMPTY: out STD_LOGIC;
FIFO_UART_TX_ENA_WR: in STD_LOGIC;
FIFO_UART_TX_DATA_WR: in
STD_LOGIC_VECTOR (7 downto 0);
FIFO_UART_TX_FULL: out STD_LOGIC);
end UART_CONTROLLER;
architecture Behavioral of UART_CONTROLLER is
signal s_tick: std_logic;
signal UART_RX_FIFO_IN: STD_LOGIC_VECTOR (7 downto 0);
signal UART_RX_DONE_TICK: std_logic;
signal UART_TX_FIFO_OUT:STD_LOGIC_VECTOR (7 downto 0);
signal UART_TX_DONE_TICK: std_logic;
signal UART_TX_FIFO_NOT_EMPRY: std_logic;
signal FIFO_UART_TX_EMPTY: std_logic;
begin
baud_gen_unit: entity work.mod_m_counter(arch)
generic map( M => DVSR,
380
N => DVSR_BIT)
port map( CKHT => CKHT,
RST => RST,
TICK => S_TICK);
UART_RX_UNIT:entity work.UART_CONTROLLER_RX(arch)
generic map( DBIT => DBIT,
SB_TICK => SB_TICK)
port map( CKHT => CKHT,
RST => RST,
S_TICK => S_TICK,
UART_RX => UART_RX,
UART_RX_DATA => UART_RX_FIFO_IN,
UART_RX_DONE_TICK => UART_RX_DONE_TICK);
FIFO_RX_UNIT: entity work.FIFO_RX(arch)
generic map ( B => DBIT,
W => FIFO_W)
port map( CKHT => CKHT,
RST => RST,
DATA_WR => UART_RX_FIFO_IN,
WR => UART_RX_DONE_TICK,
RD => FIFO_UART_RX_ENA_RD,
DATA_RD => FIFO_UART_RX_DATA_RD,
EMPTY => FIFO_UART_RX_EMPTY);
UART_TX_UNIT:entity work.UART_CONTROLLER_TX(arch)
generic map( DBIT => DBIT,
SB_TICK => SB_TICK)
port map( CKHT => CKHT,
RST => RST,
S_TICK => S_TICK,
UART_TX => UART_TX,
UART_TX_DATA => UART_TX_FIFO_OUT,
UART_TX_DONE_TICK => UART_TX_DONE_TICK,
UART_TX_FIFO_NOT_EMPRY =>
UART_TX_FIFO_NOT_EMPRY);
UART_TX_FIFO_NOT_EMPRY <= NOT FIFO_UART_TX_EMPTY;
FIFO_TX_UNIT: entity work. FIFO_TX(arch)
generic map( B => DBIT,
W => FIFO_W)
port map( CKHT => CKHT,
RST => RST,
RD => UART_TX_DONE_TICK,
DATA_RD => UART_TX_FIFO_OUT,
EMPTY => FIFO_UART_TX_EMPTY,
WR => FIFO_UART_TX_ENA_WR,
DATA_WR => FIFO_UART_TX_DATA_WR,
FULL => FIFO_UART_TX_FULL);
end Behavioral;
381
entity MOD_M_COUNTER is
generic ( N: integer := 4;
M: integer := 10);
Port ( CKHT: in STD_LOGIC;
RST: in STD_LOGIC;
TICK: out STD_LOGIC);
end MOD_M_COUNTER;
architecture arch of MOD_M_COUNTER is
SIGNAL R_REG: UNSIGNED(N-1 DOWNTO 0);
SIGNAL R_NEXT: UNSIGNED(N-1 downto 0);
begin
PROCESS(CKHT,RST)
BEGIN
IF RST = '1' THEN R_REG <= (OTHERS => '0');
ELSIF FALLING_EDGE(CKHT) THEN
R_REG <= R_NEXT;
END IF;
END PROCESS;
R_NEXT <= (OTHERS => '0') WHEN R_REG =(M-1)
ELSE R_REG+1;
TICK <= '1' WHEN R_REG = (M-1) ELSE '0';
end arch;
entity UART_CONTROLLER_RX is
generic ( DBIT: INTEGER:=8;
SB_TICK: INTEGER:=16);
Port ( CKHT: in STD_LOGIC;
RST: in STD_LOGIC;
UART_RX: in STD_LOGIC;
S_TICK: in STD_LOGIC;
UART_RX_DONE_TICK: out STD_LOGIC;
UART_RX_DATA: out STD_LOGIC_VECTOR (7 downto 0));
end UART_CONTROLLER_RX;
architecture arch of UART_CONTROLLER_RX is
TYPE state_type is (idle,start,data,stop);
signal state_reg: state_type;
signal 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);
begin
process(CKHT,RST)
begin
if RST = '1' then state_reg <= idle;
s_reg <= (others=> '0');
n_reg <= (others=> '0');
b_reg <= (others=> '0');
382
elsif falling_edge(CKHT) 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,UART_RX)
begin
state_next <= state_reg;
s_next <= s_reg;
n_next <= n_reg;
b_next <= b_reg;
UART_RX_DONE_TICK <='0';
case state_reg is
when idle =>
if UART_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 <= UART_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;
UART_RX_DONE_TICK <= '1';
else s_next <= s_reg+1;
end if;
383
end if;
end case;
end process;
UART_RX_DATA <= b_reg;
end arch;
entity FIFO_RX is
generic ( B: natural:=8;
W: natural:=2);
Port ( CKHT: in STD_LOGIC;
RST: in STD_LOGIC;
RD: in STD_LOGIC;
WR: in STD_LOGIC;
DATA_WR: in STD_LOGIC_VECTOR (B-1 downto 0);
EMPTY: out STD_LOGIC;
DATA_RD: out STD_LOGIC_VECTOR (B-1 downto 0));
end FIFO_RX;
architecture arch of FIFO_RX 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: std_logic_vector(W-1 downto 0);
signal w_ptr_next: std_logic_vector(W-1 downto 0);
signal w_ptr_succ: std_logic_vector(W-1 downto 0);
signal r_ptr_reg: std_logic_vector(W-1 downto 0);
signal r_ptr_next: std_logic_vector(W-1 downto 0);
signal r_ptr_succ: std_logic_vector(W-1 downto 0);
signal full_reg: std_logic;
signal full_next: std_logic;
signal empty_reg: std_logic;
signal empty_nex: std_logic;
signal wr_op: std_logic_vector(1 downto 0);
signal wr_en: std_logic;
begin
process(ckht, rst)
begin
if (RST='1') then
array_reg <= (others=>(others=>'0'));
elsif falling_edge(ckht) then
if wr_en='1' then
array_reg(conv_integer(unsigned(w_ptr_reg))) <=
DATA_WR;
end if;
end if;
end process;
DATA_RD <=
384
array_reg(conv_integer(unsigned(r_ptr_reg)));
wr_en <= wr and (not full_reg);
process(ckht,rst)
begin
if rst='1' then w_ptr_reg <= (others=> '0');
r_ptr_reg <= (others=> '0');
full_reg <= '0';
empty_reg <= '1';
elsif falling_edge(ckht) 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;
w_ptr_succ <= w_ptr_reg + 1;
r_ptr_succ <= r_ptr_reg + 1;
wr_op <= WR & RD;
process(w_ptr_reg,w_ptr_succ,r_ptr_reg,r_ptr_succ,wr_op,emp
ty_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" =>
when "01" =>
if (empty_reg ='0') then
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" =>
if (full_reg ='0') then
w_ptr_next <= w_ptr_succ;
empty_next <= '0';
if (w_ptr_succ = r_ptr_reg) then
full_next <= '1';
end if;
end if;
when others => w_ptr_next <= w_ptr_succ;
r_ptr_next <= r_ptr_succ;
end case;
385
end process;
EMPTY <= empty_reg;
end arch;
entity UART_CONTROLLER_TX is
generic ( DBIT: INTEGER:=8;
SB_TICK: INTEGER:=16);
Port ( CKHT: in STD_LOGIC;
RST: in STD_LOGIC;
UART_TX_FIFO_NOT_EMPRY: in STD_LOGIC;
S_TICK: in STD_LOGIC;
UART_TX_DATA:in
STD_LOGIC_VECTOR (7 downto 0);
UART_TX_DONE_TICK: out STD_LOGIC;
UART_TX: out STD_LOGIC);
end UART_CONTROLLER_TX;
architecture arch of UART_CONTROLLER_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;
begin
process(CKHT, RST)
begin
if RST = '1' then state_reg <= idle;
s_reg <= (others=> '0');
n_reg <= (others=> '0');
b_reg <= (others=> '0');
tx_reg <= '1';
elsif falling_edge(CKHT) 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;
process(state_reg,s_reg,n_reg,b_reg,s_tick,tx_reg,UART_TX_F
IFO_NOT_EMPRY,UART_TX_DATA)
begin
state_next <= state_reg;
s_next <= s_reg;
n_next <= n_reg;
b_next <= b_reg;
tx_next <= tx_reg;
UART_TX_DONE_TICK <= '0';
386
case state_reg is
when idle => tx_next <= '1';
if UART_TX_FIFO_NOT_EMPRY ='1' then
state_next <= start;
s_next <= (others=>'0');
b_next <= UART_TX_DATA;
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;
UART_TX_DONE_TICK<='1';
else s_next<=s_reg+1;
end if;
end if;
end case;
end process;
UART_TX <=tx_reg;
end arch;
entity fifo_tx is
generic (B: natural:=8;
W: natural:=2);
Port ( Ckht : in STD_LOGIC;
Rst: in STD_LOGIC;
387
RD: in STD_LOGIC;
WR: in STD_LOGIC;
DATA_WR: in STD_LOGIC_VECTOR (B-1 downto 0);
EMPTY: out STD_LOGIC;
FULL : out STD_LOGIC;
DATA_RD:out STD_LOGIC_VECTOR (B-1 downto 0));
end fifo_tx;
architecture arch of fifo_tx 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: std_logic_vector(W-1 downto 0);
signal w_ptr_next: std_logic_vector(W-1 downto 0);
signal w_ptr_succ: std_logic_vector(W-1 downto 0);
signal r_ptr_reg: std_logic_vector(W-1 downto 0);
signal r_ptr_next: std_logic_vector(W-1 downto 0);
signal r_ptr_succ: std_logic_vector(W-1 downto 0);
signal full_reg: std_logic;
signal full_next: std_logic;
signal empty_reg: std_logic;
signal empty_next: std_logic;
signal wr_op: std_logic_vector(1 downto 0);
signal wr_en: std_logic;
begin
process(ckht, rst)
begin
if (rst='1') then
array_reg <= (others=>(others=>'0'));
elsif falling_edge(ckht) then
if wr_en = '1' then
array_reg(conv_integer(unsigned(w_ptr_reg))) <=
DATA_WR;
end if;
end if;
end process;
DATA_RD <=
array_reg(conv_integer(unsigned(r_ptr_reg)));
wr_en <= wr and (not full_reg);
process(ckht, rst)
begin
if rst='1' then w_ptr_reg <= (others=> '0');
r_ptr_reg <= (others=> '0');
full_reg <= '0';
empty_reg <= '1';
elsif falling_edge(ckht) then
388
w_ptr_reg <= w_ptr_next;
r_ptr_reg <= r_ptr_next;
full_reg <= full_next;
empty_reg <= empty_next;
end if;
end process;
w_ptr_succ <= w_ptr_reg + 1;
r_ptr_succ <= r_ptr_reg + 1;
wr_op <= wr & rd;
process(w_ptr_reg,w_ptr_succ,r_ptr_reg,r_ptr_succ,wr_op,emp
ty_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" =>
when "01" =>
if empty_reg ='0' then
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" =>
if (full_reg ='0') then
w_ptr_next <= w_ptr_succ;
empty_next <= '0';
if (w_ptr_succ = r_ptr_reg) then
full_next <= '1';
end if;
end if;
when others => w_ptr_next <= w_ptr_succ;
r_ptr_next <= r_ptr_succ;
end case;
end process;
full <= full_reg;
empty <= empty_reg;
end arch;
389