Transcript WHYP
RS-232 Port
Discussion D12.1
RS-232 voltage levels: +5.5 V (logic 0) -5.5 V (logic 1)
Loop feedback
PC:
DTE female connector
Spartan-3 board:
DCE male connector
Straight-through cable
Note: TxD (pin 2) on Spartan-3 DCE connector is connected
to RD (pin 2) on the PC DTE connector
9 Pin Connector on a DTE device (PC connection)
Male RS232
DB9
Pin Number
Direction of signal:
1
Carrier Detect (CD) (from DCE) Incoming signal from a modem
2
Received Data (RD) Incoming Data from a DCE
3
Transmitted Data (TD) Outgoing Data to a DCE
4
Data Terminal Ready (DTR) Outgoing handshaking signal
5
Signal Ground Common reference voltage
6
Data Set Ready (DSR) Incoming handshaking signal
7
Request To Send (RTS) Outgoing flow control signal
8
Clear To Send (CTS) Incoming flow control signal
9
Ring Indicator (RI) (from DCE) Incoming signal from a modem
D0
MARK
D1
D2
D3
D4
D5
D6
D7
STOP
SPACE
START
PARITY
ASCII code 54H = 1010100 ("T") sent with odd parity
Common Asynchronous Serial Baud Rates
Baud rate
110
300
600
1200
2400
4800
9600
14400
19200
28800
38400
Bit time
(msec)
9.09
3.33
1.67
0.833
0.417
0.208
0.104
0.069
0.052
0.035
0.026
No. of STOP
bits
2
1
1
1
1
1
1
1
1
1
1
Char. time
(msec.)
100.00
33.3 3
16.67
8.33
4.17
2.08
1.04
0.69
0.52
0.35
0.26
Char./sec.
10
30
60
120
240
480
960
1440
1920
2880
3840
UART clock frequency = 16 x Baud rate or 64 x Baud rate
Standard ASCII Codes
Table 9.2
Standard ASCII codes
Dec
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Hex
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
0
16
32
48
64
80
96
112
0
1
2
3
4
5
6
7
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
FF
CR
SO
SI
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
blank
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
!
"
#
$
%
&
'
(
)
*
+
,
.
/
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
DEL
How would you make the following hardware Tx UART?
clk
clr
tx_data(7:0)
TxD
uart_tx
ready
tdre
8-bit parallel data comes in tx_data(7:0) and is loaded into a
transmit buffer txbuff when tdre is high.
When ready goes high the contents of txbuff is sent out TxD as
asynchronous serial data.
When txbuff is empty, tdre is set to 1.
UART Transmit State Diagram
!ready
bit_count <= "0000";
tdre <= ‘1’
mark
ready
TxD <= ‘1’;
tdre <= ‘0’;
baud_count < bit time
stop
baud_count >= bit time
and
bit_count >= 8
start
baud_count <= X"000";
TxD <= '0';
tdre <= '0';
tdre <= ‘0’;
delay
baud_count < bit time
baud_count <= X"000";
baud_count >= bit time
and
bit_count < 8
shift
tdre <= '0';
TxD <= txbuff(0);
txbuff(6 downto 0) <= txbuff(7 downto 1);
bit_count <= bit_count + 1;
VHDL
Canonical Sequential Network
s(t+1)
next
state
State Register
x(t)
present
input
Combinational
Network
init
process(clk, init)
clk
process(present_state, x)
s(t)
present
state
present
z(t) output
VHDL
Mealy Machine
process(present_state, x)
s(t+1)
C1
x(t)
present
input
next
state
State Register
init
s(t)
present
state
process(present_state, x)
clk
process(clk, init)
z(t)
C2
VHDL
Moore Machine
s(t+1)
C1
next
state
x(t)
present
input process(present_state, x)
State Register
init
z(t)
s(t)
present
state
C2
process(present_state)
clk
process(clk, init)
VHDL
Canonical Sequential Network
s(t+1)
next
state
Combine
into a single
process
process(present_state, x)
State Register
x(t)
present
input
Combinational
Network
init
s(t)
present
state
process(clk, init)
clk
present
z(t) output
UART Transmit State Diagram
!ready
bit_count <= "0000";
tdre <= ‘1’
mark
ready
TxD <= ‘1’;
tdre <= ‘0’;
baud_count < bit time
stop
baud_count >= bit time
and
bit_count >= 8
start
baud_count <= X"000";
TxD <= '0';
tdre <= '0';
tdre <= ‘0’;
delay
baud_count < bit time
baud_count <= X"000";
baud_count >= bit time
and
bit_count < 8
shift
tdre <= '0';
TxD <= txbuff(0);
txbuff(6 downto 0) <= txbuff(7 downto 1);
bit_count <= bit_count + 1;
clk
clr
tx_data(7:0)
TxD
uart_tx
ready
tdre
entity uart_tx is
port(
clk : in STD_LOGIC;
clr : in STD_LOGIC;
tx_data : in STD_LOGIC_VECTOR(7 downto 0);
ready : in STD_LOGIC;
tdre : out STD_LOGIC;
TxD : out STD_LOGIC
);
end uart_tx;
architecture uart_tx of uart_tx is
type state_type is (mark, start, delay, shift, stop);
signal state: state_type;
signal txbuff: STD_LOGIC_VECTOR (7 downto 0);
signal baud_count: STD_LOGIC_VECTOR (11 downto 0);
signal bit_count: STD_LOGIC_VECTOR (3 downto 0);
constant bit_time: STD_LOGIC_VECTOR (11 downto 0) := X"A28";
begin
9600 baud
!ready
bit_count <= "0000";
tdre <= ‘1’
mark
ready
TxD <= ‘1’;
tdre <= ‘0’;
uart2: process(clk, clr, ready)
begin
if clr = '1' then
state <= mark;
txbuff <= "00000000";
baud_count <= X"000";
bit_count <= "0000";
TxD <= '1';
elsif (clk'event and clk = '1') then
case state is
when mark =>
-- wait for ready
bit_count <= "0000";
tdre <= '1';
if ready = '0' then
state <= mark;
txbuff <= tx_data;
else
baud_count <= X"000";
state <= start;
-go to start
end if;
baud_count < bit time
stop
baud_count >= bit time
and
bit_count >= 8
start
baud_count <= X"000";
TxD <= '0';
tdre <= '0';
tdre <= ‘0’;
delay
baud_count < bit time
baud_count <= X"000";
baud_count < bit time
and
bit_count < 8
shift
tdre <= '0';
TxD <= txbuff(0);
txbuff(6 downto 0) <= txbuff(7 downto 1);
bit_count <= bit_count + 1;
!ready
bit_count <= "0000";
tdre <= ‘1’
mark
ready
TxD <= ‘1’;
tdre <= ‘0’;
baud_count < bit time
stop
start
when start =>
-- output start bit
baud_count <= X"000";
TxD <= '0';
tdre <= '0';
state <= delay;
-go to delay
when delay =>
-- wait bit time
tdre <= '0';
if baud_count >= bit_time then
baud_count <= X"000";
if bit_count < 8 then
-- if not done
state <= shift;
-go to shift
else
-- else
state <= stop;
-go to stop
end if;
else
baud_count <= baud_count + 1;
state <= delay;
-stay in delay
end if;
baud_count >= bit time
and
bit_count >= 8
baud_count <= X"000";
TxD <= '0';
tdre <= '0';
tdre <= ‘0’;
delay
baud_count < bit time
baud_count <= X"000";
baud_count < bit time
and
bit_count < 8
shift
tdre <= '0';
TxD <= txbuff(0);
txbuff(6 downto 0) <= txbuff(7 downto 1);
bit_count <= bit_count + 1;
when shift =>
-- get next bit
tdre <= '0';
TxD <= txbuff(0);
txbuff(6 downto 0) <= txbuff(7 downto 1);
bit_count <= bit_count + 1;
state <= delay;
when stop =>
-- stop bit
tdre <='0';
TxD <= '1';
if baud_count >= bit_time then
baud_count <= X"000";
state <= mark;
else
baud_count <= baud_count + 1;
state <= stop;
end if;
end case;
end if;
end process uart2;
end uart_tx;
!ready
bit_count <= "0000";
tdre <= ‘1’
mark
ready
TxD <= ‘1’;
tdre <= ‘0’;
baud_count < bit time
stop
baud_count >= bit time
and
bit_count >= 8
start
baud_count <= X"000";
TxD <= '0';
tdre <= '0';
tdre <= ‘0’;
delay
baud_count < bit time
baud_count <= X"000";
baud_count < bit time
and
bit_count < 8
shift
tdre <= '0';
TxD <= txbuff(0);
txbuff(6 downto 0) <= txbuff(7 downto 1);
bit_count <= bit_count + 1;
Test Transmit UART
Set slide switches to some ASCII code and then press
button 0 to send ASCII code out serial port.
clk
clr
!btn
ready <= ‘0’
SW tx_data(7:0)
wtbtndn
TxD
uart_tx
btn
!btn
ready
tdre
btn
clk
wttdre
wtbtnup
clr
ready <= ‘0’
ready <= ‘0’
BTN(0)
tdre
btn
Test_tx_ctrl
ready
!tdre
load
tdre
ready <= ‘1’
entity tx_tst_ctrl is
port(
clk : in STD_LOGIC;
clr : in STD_LOGIC;
btn : in STD_LOGIC;
tdre : in STD_LOGIC;
ready : out STD_LOGIC
);
end tx_tst_ctrl;
clk
clr
btn
Test_tx_ctrl
tdre
ready
architecture tx_tst_ctrl of tx_tst_ctrl is
type state_type is (wtbtndn, wttdre, load, wtbtnup);
!btn
signal state: state_type;
ready <= ‘0’
wtbtndn
begin
!btn
ctrl: process(clk, clr, btn, tdre)
begin
btn
wtbtnup
if clr = '1' then
state <= wtbtndn;
ready <= ‘0’
ready <= '0';
elsif (clk'event and clk = '1') then
load
case state is
when wtbtndn =>
-- wait for btn ready <= ‘1’
if btn = '0' then
-- if bnt up
state <= wtbtndn;
-stay in wtbtndo
ready <= '0';
else
ready <= '0';
state <= wttdre;
-- else go to wttdre
end if;
btn
wttdre
!tdre
ready <= ‘0’
tdre
when wttdre =>
if tdre = '0' then
state <= wttdre;
ready <= '0';
else
state <= load;
ready <= '0';
end if;
when load =>
ready <= '1';
state <= wtbtnup;
-- wait for tdre = 1
-- if tdre = 0
-stay in wtdone
-- else go to load
-- output ready
-- go to wtbtnup
!btn
ready <= ‘0’
wtbtndn
btn
!btn
btn
wtbtnup
wttdre
ready <= ‘0’
!tdre
ready <= ‘0’
tdre
load
ready <= ‘1’
when wtbtnup =>
if btn = '1' then
state <= wtbtnup;
ready <= '0';
else
ready <= '0';
state <= wtbtndn;
end if;
end case;
end if;
end process ctrl;
end tx_tst_ctrl;
-- wait for btn up
-- if btn down
-stay in wtbtnup
--
else go to wtbtndn
!btn
ready <= ‘0’
wtbtndn
btn
!btn
btn
wttdre
wtbtnup
!tdre
ready <= ‘0’
ready <= ‘0’
tdre
load
ready <= ‘1’
Test Transmit UART
Top-level design
entity uart_tx_test is
port (
mclk : in STD_LOGIC;
sw : in STD_LOGIC_VECTOR(7 downto 0);
btn : in STD_LOGIC_VECTOR(3 downto 0);
ld : out STD_LOGIC_VECTOR(7 downto 0);
TxD : out STD_LOGIC
);
end uart_tx_test;
Pin "R13"
architecture uart_tx_test_arch of uart_tx_test is
component uart_tx
port(
clk : in STD_LOGIC;
clr : in STD_LOGIC;
tx_data : in STD_LOGIC_VECTOR(7 downto 0);
ready : in STD_LOGIC;
clk
clr
tdre : out STD_LOGIC;
TxD : out STD_LOGIC
);
tx_data(7:0)
uart_tx
end component;
ready
component tx_tst_ctrl
port(
clk : in STD_LOGIC;
clr : in STD_LOGIC;
btn : in STD_LOGIC;
tdre : in STD_LOGIC;
ready : out STD_LOGIC
);
end component;
TxD
tdre
clk
clr
btn
Test_tx_ctrl
tdre
ready
outp
inp
delay1
delay2
delay3
cclk
component debounce4
port(
clk : in std_logic;
clr : in std_logic;
inp : in std_logic_vector(3 downto 0);
outp : out std_logic_vector(3 downto 0));
end component;
signal
signal
signal
signal
begin
clr, clk, cclk: std_logic;
tdre, ready: std_logic;
clkdiv : std_logic_vector(23 downto 0);
btnd : std_logic_vector(3 downto 0);
-- Divide the master clock (50Mhz) down to a lower frequency.
process (mclk)
begin
if clr = '1' then
clkdiv <= "000000000000000000000000";
elsif mclk = '1' and mclk'Event then
clkdiv <= clkdiv + 1;
end if;
end process;
clk <= clkdiv(0);
cclk <= clkdiv(17);
ld(7)
ld(6)
ld(5)
ld(4)
ld(3)
ld(2)
ld(1)
<=
<=
<=
<=
<=
<=
<=
btnd(1);
btnd(2);
btnd(1);
btnd(2);
btnd(1);
btnd(2);
btnd(1);
ld(0) <= tdre;
clr <= btnd(3);
-- 25 MHz
-- 190 Hz
U1: uart_tx port map
(TxD => TxD, clk => clk, clr => clr, ready => ready, tx_data => sw,
tdre => tdre);
U2: tx_tst_ctrl port map
(clk => clk, clr => clr, btn => btnd(0), tdre => tdre, ready => ready);
U3 : debounce4
port map(
clk => cclk,
clr => clr,
inp => btn,
outp => btnd
);
outp
end uart_tx_test_arch;
clk
btn(0)
clr
inp
delay1
cclk
clk
sw
tx_data(7:0)
clr
TxD
uart_tx
ready
delay2
tdre
btn
Test_tx_ctrl
tdre
ready
delay3
How would you make the following hardware Rx UART?
data_rx(7:0)
RxD
uart_rx
clrflg
rdrf
FE
8-bit asynchronous serial data comes in RxD and fills up the shift
register data_rx.
When data_rx is full, rdrf is set to 1.
rdrf is cleared to zero by bringing clrflg high.
The framing error flag FE is set to 1 if the stop bit is not 1.
UART Receive State Diagram
RxD
mark
!RxD
stop
start
baud_count < 0.5 bit time
baud_count >= 0.5 bit time
baud_count >= bit time
and
bit_count >= 8
delay
baud_count < bit time
baud_count < bit time
and
bit_count < 8
shift
clr
rx_data(7:0)
clk
RxD
rdrf_clr
uart_rx
rdrf
FE
entity uart_rx is
port(
RxD : in STD_LOGIC;
clk : in STD_LOGIC;
clr : in STD_LOGIC;
rdrf_clr : in STD_LOGIC;
rdrf : out STD_LOGIC;
FE : out STD_LOGIC;
rx_data : out STD_LOGIC_VECTOR(7 downto 0)
);
end uart_rx;
architecture uart_rx of uart_rx is
type state_type is (mark, start, delay, shift, stop);
signal state: state_type;
signal rxbuff: STD_LOGIC_VECTOR (7 downto 0);
signal baud_count: STD_LOGIC_VECTOR (11 downto 0);
signal bit_count: STD_LOGIC_VECTOR (3 downto 0);
signal rdrf_set, fe_set, cclr, cclr8, rxload: STD_LOGIC;
constant bit_time: STD_LOGIC_VECTOR (11 downto 0) := X"A28";
constant half_bit_time: STD_LOGIC_VECTOR (11 downto 0) := X"514";
begin
9600 baud
RxD
uart2: process(clk, clr, rdrf_clr)
mark
begin
!RxD
if clr = '1' then
state <= mark;
stop
start
baud_count < 0.5 bit time
rxbuff <= "00000000";
baud_count >= 0.5 bit time
baud_count <= X"000";
baud_count >= bit time
and
delay
baud_count < bit time
bit_count >= 8
bit_count <= "0000";
FE <= '0';
baud_count < bit time
and
elsif rdrf_clr = '1' then
bit_count < 8
rdrf <= '0';
shift
elsif (clk'event and clk = '1') then
case state is
when mark =>
-- wait for start bit
baud_count <= X"000";
bit_count <= "0000";
if RxD = '1' then
state <= mark;
else
FE <= '0';
state <= start;
-go to start
end if;
when start =>
-- check for start bit
if baud_count >= half_bit_time then
baud_count <= X"000";
state <= delay;
else
RxD
baud_count <= baud_count + 1;
state <= start;
mark
!RxD
end if;
when delay =>
if baud_count >= bit_time then
stop
start
baud_count < 0.5 bit time
baud_count <= X"000";
baud_count >= 0.5 bit time
if bit_count < 8 then
baud_count >= bit time
and
state <= shift;
delay
baud_count < bit time
bit_count >= 8
else
baud_count < bit time
state <= stop;
and
bit_count < 8
end if;
else
shift
baud_count <= baud_count + 1;
state <= delay;
end if;
when shift =>
-- get next bit
rxbuff(7) <= RxD;
rxbuff(6 downto 0) <= rxbuff(7 downto 1);
bit_count <= bit_count + 1;
state <= delay;
when stop =>
RxD
rdrf <= '1';
if RxD = '0' then
mark
FE <= '1';
!RxD
else
FE <= '0';
stop
start
baud_count < 0.5 bit time
end if;
state <= mark;
baud_count >= 0.5 bit time
baud_count >= bit time
end case;
and
delay
baud_count < bit time
bit_count >= 8
end if;
end process uart2;
baud_count < bit time
and
bit_count < 8
rx_data <= rxbuff;
end uart_rx;
shift
Test of UART
clk
clr
clr
rx_data(7:0)
clk
RxD
tx_data(7:0)
uart_rx
uart_tx
rdrf
rdrf_clr
TxD
ready
tdre
FE
clk
clr
clk
rdrf
Test_rx_ctrl
rdrf_clr
clr
btn
Test_tx_ctrl
tdre
ready
Test Receive UART
Receive ASCII code sent from terminal program on PC
when key is pressed and display on LEDs.
!rdrf
clr
RxD
rdrf_clr <= ‘0’
rx_data(7:0)
clk
wtrdrf
uart_rx
rdrf
rdrf_clr
FE
rdrf
clk
clr
load
rdrf
Test_rx_ctrl
rdrf_clr
rdrf_clr <= ‘1’
Test Transmit UART
Echo back ASCII code sent from PC.
clk
clr
!btn
ready <= ‘0’
tx_data(7:0)
wtbtndn
TxD
uart_tx
btn
!btn
ready
tdre
btn
clk
wttdre
wtbtnup
clr
ready <= ‘0’
ready <= ‘0’
rdrf_clr
tdre
btn
Test_tx_ctrl
ready
!tdre
load
tdre
ready <= ‘1’
clk
entity test2_rx_ctrl is
rdrf
port(
clk : in STD_LOGIC;
clr : in STD_LOGIC;
rdrf : in STD_LOGIC;
rdrf_clr : out STD_LOGIC
);
end test2_rx_ctrl;
clr
Test_rx_ctrl
architecture test2_rx_ctrl of test2_rx_ctrl is
type state_type is (wtrdrf, load);
signal state: state_type;
rdrf_clr
begin
ctrl: process(clk, clr, rdrf)
begin
if clr = '1' then
state <= wtrdrf;
rdrf_clr <= '0';
elsif (clk'event and clk = '1') then
case state is
when wtrdrf =>
rdrf_clr <= '0';
if rdrf = '0' then
state <= wtrdrf;
else
state <= load;
end if;
when load =>
rdrf_clr <= '1';
state <= wtrdrf;
end case;
end if;
end process ctrl;
end test2_rx_ctrl;
!rdrf
rdrf_clr <= ‘0’
wtrdrf
rdrf
load
rdrf_clr <= ‘1’
entity uart_test2 is
Top-level test of UART
port (
mclk : in STD_LOGIC;
BTN3 : in STD_LOGIC;
RxD : in STD_LOGIC;
LD : out STD_LOGIC_VECTOR(7 downto 0);
TxD : out STD_LOGIC
);
end uart_test2;
clk
clr
architecture uart_test2_arch of uart_test2 is
tx_data(7:0)
component uart_tx
uart_tx
port(
ready
clk : in STD_LOGIC;
clr : in STD_LOGIC;
tx_data : in STD_LOGIC_VECTOR(7 downto 0);
ready : in STD_LOGIC;
tdre : out STD_LOGIC;
TxD : out STD_LOGIC
);
end component;
TxD
tdre
component tx_tst_ctrl
port(
clk : in STD_LOGIC;
clr : in STD_LOGIC;
btn : in STD_LOGIC;
tdre : in STD_LOGIC;
ready : out STD_LOGIC
);
end component;
clk
clr
btn
Test_tx_ctrl
ready
tdre
component uart_rx
clr
port(
clk
uart_rx
RxD : in STD_LOGIC;
RxD
clk : in STD_LOGIC;
rdrf_clr
clr : in STD_LOGIC;
rdrf_clr : in STD_LOGIC;
rdrf : out STD_LOGIC;
FE : out STD_LOGIC;
rx_data : out STD_LOGIC_VECTOR(7 downto 0)
);
end component;
rx_data(7:0)
rdrf
FE
clk
component test2_rx_ctrl
port(
clk : in STD_LOGIC;
clr : in STD_LOGIC;
rdrf : in STD_LOGIC;
rdrf_clr : out STD_LOGIC
);
end component;
signal
signal
signal
signal
rdrf
clr
Test_rx_ctrl
clr, clk, cclk: std_logic;
tdre, rdrf, rdrf_clr, FE, ready, btn: std_logic;
clkdiv : std_logic_vector(23 downto 0);
data : std_logic_vector(7 downto 0);
rdrf_clr
begin
-- Divide the master clock (50Mhz) down to a lower frequency.
process (mclk)
begin
if clr = '1' then
clkdiv <= "000000000000000000000000";
elsif mclk = '1' and mclk'Event then
clkdiv <= clkdiv + 1;
end if;
end process;
clk <= clkdiv(0);
-- 25 MHz
cclk <= clkdiv(17); -- 190 Hz
clk
clr
LD <= data;
clk
clr
clr <= BTN3;
btn <= rdrf_clr;
rdrf
Test_rx_ctrl
rdrf_clr btn
Test_tx_ctrl
tdre
ready
U1: uart_tx port map
(TxD => TxD, clk => clk, clr => clr, ready => ready,
tx_data => data,tdre => tdre);
U2: uart_rx port map
(RxD => RxD, clk => clk, clr => clr, rdrf_clr => rdrf_clr,
rx_data => data,rdrf => rdrf, FE => FE);
U3: tx_tst_ctrl port map
(clk => clk, clr => clr, tdre => tdre, btn => btn,
ready => ready);
U4: test2_rx_ctrl port map
(clk => clk, clr => clr, rdrf => rdrf, rdrf_clr => rdrf_clr);
clk
end uart_test2_arch;
clr
clk
clr
rdrf_clr
TxD
uart_rx
rdrf
rdrf
FE
btn
Test_tx_ctrl
uart_tx
ready
clr
rx_data(7:0)
clk
RxD
tx_data(7:0)
clk
tdre
clr
tdre
ready
Test_rx_ctrl
rdrf_clr