FONT SIZE : AAA
Introduction
The basic approach of RS-232 serial transmission is that of a UART. UART stands for Universal Asynchronous Receiver/Transmitter. It is the standard method of translating a serial communication stream into the parallel form used by computers. RS-232 is a UART that has a specific standard defined for start, stop, break, data, parity, and pin names.
RS-232 Baud Rate Generator
The RS-232 is an asynchronous transmission scheme and so the correct clock rate must be defined prior to transmission to ensure that the data is transmitted and received correctly. The RS-232 baud rate can range from 1200 baud up to 115200 baud. This is based on a standard clock frequency of 14.7456 MHz, and this is then divided down by 8, 16, 28, 48, 96, 192, 384, and 768 to get the correct baud rates. We therefore need to define a clock divider circuit that can output the correct baud rate configured by a control word. We have obviously got 8 different ratios, and so we can use a 3-bit control word (baud[2:0]) plus a clock and reset to create the correct frequencies, assuming that the basic clock frequency is 14.7456 MHz (Figure 15.3).
The VHDL for this controller is given as follows and uses a single process to select the correct baud rate and another to divide down the input clock accordingly:
1 library ieee; 2 use ieee.std_logic_1164.all; 3 use ieee.std_logic_unsigned.all; 45 entity baudcontroller is 6 port(
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_unsigned.all;
4
5 entity baudcontroller is
6 port(
Figure 15.3
Baud rate generator.
7 clk : in std_logic;
8 rst : in std_logic;
9 baud : in std_logic_vector(0 to 2);
10 clkout : out std_logic;
11 end baudcontroller;
12
13 architecture simple of baudcontroller is
14 signal clkdiv : integer := 0;
15 signal count : integer := 0;
16 begin
17 div: process (rst, clk)
18 begin
19 if rst=’0’ then
20 clkdiv <= 0;
21 count <= 0;
22 elsif rising_edge(clk) then
23 case baud is
24 when "000" => clkdiv <= 7; −− 115200
25 when "001" => clkdiv <= 15; −− 57600
26 when "010" => clkdiv <= 23; −− 38400
27 when "011" => clkdiv <= 47; −− 19200
28 when "100" => clkdiv <= 95; −− 9600
29 when "101" => clkdiv <= 191; −− 4800
30 when "110" => clkdiv <= 383; −− 2400
31 when "111" => clkdiv <= 767; −− 1200
32 when others => clkdiv <= 7;
33 end case;
34 end if;
35 end process;
36
37 clockdivision: process (clk, rst)
38 begin
39 if rst=’0’ then
40 clkdiv <= 0;
41 count <= 0;
42 elsif rising_edge(clk) then
43 count <= count + 1;
44 if (count > clkdiv) then
45 clkout <= not clkout;
46 count <= 0;
47 end if;
48 end if;
49 end process;
50 end simple;
The Verilog equivalent for this baud rate controller is given as follows and uses separate code to select the correct baud rate and another to divide down the input clock accordingly:
1 module baudcontroller (
2 clk, / clock
3 rst, / reset
4 clkout / baud rate output
5 );
67 input clk;
8 input rst;
9 output clkout;
10 reg clkout;
11
12 parameter baudrate = 9600;
13
14 always_init
15 case baudrate
16 115200: clkdiv = 7;
17 57600: clkdiv = 15;
18 38400: clkdiv = 23;
19 19200: clkdiv = 47;
20 9600: clkdiv = 95;
21 4800: clkdiv = 191;
22 2400: clkdiv = 383;
23 1200: clkdiv = 767;
24
25
26 when "000" => clkdiv <= 7; −− 115200
27 when "001" => clkdiv <= 15; −− 57600
28 when "010" => clkdiv <= 23; −− 38400
29 when "011" => clkdiv <= 47; −− 19200
30 when "100" => clkdiv <= 95; −− 9600
31 when "101" => clkdiv <= 191; −− 4800
32 when "110" => clkdiv <= 383; −− 2400
33 when "111" => clkdiv <= 767; −− 1200
34 when others => clkdiv <= 7;
35
36 always @(CharIn)
37 case (CharIn)
38 4’h0: HexOut = 7’b1000000;
39 4’h1: HexOut = 7’b1111001;
40 4’h2: HexOut = 7’b0100100;
41 4’h3: HexOut = 7’b0110000;
42 4’h4: HexOut = 7’b0011001;
43 4’h5: HexOut = 7’b0010010;
44 4’h6: HexOut = 7’b0000010;
45 4’h7: HexOut = 7’b1111000;
46 4’h8: HexOut = 7’b0000000;
47 4’h9: HexOut = 7’b0011000;
48 4’hA: HexOut = 7’b0001000;
49 4’hB: HexOut = 7’b0000011;
50 4’hC: HexOut = 7’b1000110;
51 4’hD: HexOut = 7’b0100001;
52 4’hE: HexOut = 7’b0000110;
53 4’hF: HexOut = 7’b0001110;
54 default: HexOut = 7’b0110110;
55 endcase
56
57 architecture simple of baudcontroller is
58 signal clkdiv : integer := 0;
59 signal count : integer := 0;
60 begin
61 div: process (rst, clk)
62 begin
63 if rst=’0’ then
64 clkdiv <= 0;
65 count <= 0;
66 elsif rising_edge(clk) then
67 case baud is
68 when "000" => clkdiv <= 7; −− 115200
69 when "001" => clkdiv <= 15; −− 57600
70 when "010" => clkdiv <= 23; −− 38400
71 when "011" => clkdiv <= 47; −− 19200
72 when "100" => clkdiv <= 95; −− 9600
73 when "101" => clkdiv <= 191; −− 4800
74 when "110" => clkdiv <= 383; −− 2400
75 when "111" => clkdiv <= 767; −− 1200
76 when others => clkdiv <= 7;
77 end case;
78 end if;
79 end process;
80
81 clockdivision: process (clk, rst)
82 begin
83 if rst=’0’ then
84 clkdiv <= 0;
85 count <= 0;
86 elsif rising_edge(clk) then
87 count <= count + 1;
88 if (count > clkdiv) then
89 clkout <= not clkout;
90 count <= 0;
91 end if;
92 end if;
93 end process;
94 end simple;
RS-232 Receiver
The RS-232 receiver must wait for data to arrive on the RX line and has a specification defined as follows: <number of bits><parity><stop bits>. So, for example an 8-bit, No parity, 1 stop bit specification would be given as 8N1. The RS-232 voltage levels are between −12V and +12V, and so we will assume that an interface chip has translated these to standard logic levels (0-5 V or 0-3.3 V, for example). A sample bit stream would be of the format shown in Figure 15.4.
The idle state for RS-232 is high, and in this figure, after the stop bit, the line is shown as going low, when in fact that only happens when another data word is coming. If the data transmission has finished, then the line will go high (idle) again. We can in fact model this as a simple state machine as shown in Figure 15.5.
Figure 15.4
Example serial data bit stream.
Figure 15.5
Basic serial data receiver state machine.
We can implement this simple state machine in VHDL using the following model:
1 library ieee;
2 use ieee.std_logic_1164.all; 3 use ieee.std_logic_unsigned.all; 45 entity serialrx is
6 port( 7 clk : in std_logic;
8 rst : in std_logic;
9 rx : in std_logic;
10 dout : out std_logic_vector (7 downto 0)
11 );
12 end serialrx;
13
14 architecture simple of serialrx is
15 type state is (idle, s0, s1, s2, s3, s4, s5, s6, s7, stop);
16 signal current_state, next_state : state;
17 signal databuffer : std_logic_vector(7 downto 0);
18 begin
19 receive: process (rst, clk)
20 begin
21 if rst=’0’ then
22 current_state <= idle;
23 for i in 7 downto 0 loop
24 dout(i) <= ’0’;
25 end loop;
26 elsif rising_edge(clk) then
27
28 case current_state is
29 when idle =>
30 if rx = ’0’ then
31 next_state <= s0;
32 else
33 next_state <= idle;
34 end if;
35 when s0 =>
36 next_state <= s1;
37 databuffer(0) <= rx;
38 when s1 =>
39 next_state <= s2;
40 databuffer(1) <= rx;
41 when s2 =>
42 next_state <= s3;
43 databuffer(2) <= rx;
44 when s3 =>
45 next_state <= s4;
46 databuffer(3) <= rx;
47 when s4 =>
48 next_state <= s5;
49 databuffer(4) <= rx;
50 when s5 =>
51 next_state <= s6;
52 databuffer(5) <= rx;
53 when s6 =>
54 next_state <= s7;
55 databuffer(6) <= rx;
56 when s7 =>
57 next_state <= stop;
58 databuffer(7) <= rx;
59 when stop =>
60 if rx = ’0’ then
61 next_state <= s0;
62 else
63 next_state <= idle;
64 end if;
65 dout <= databuffer;
66 end case;
67 current_state <= next_state;
68 end if;
69 end process;
70 end;
In turn, the same approach of a state machine can be used in Verilog, with the model as shown below:
1 module serial_rx (
2 dout, / Output Value
3 clk, / Clock
4 rst, / Reset
5 rx / Input receiver value
6 );
789 output [3:0] dout;
10 input clk;
11 input rst;
12 input rx;
13
14 reg [3:0] dout;
15
16 reg [3:0] current_state, next_state; / state variable
17
224 Chapter 15
18 parameter idle=0,s0=1, s1=2, s2=3, s3=4,s4=5,s5=6,s6=7,s7=8,stop=9;
19
20 always @(state)
21 begin
22 case (state)
23 s0:
24 dout[0] = rx;
25 s1:
26 dout[1] = rx;
27 s2:
28 dout[2] = rx;
29 s3:
30 dout[3] = rx;
31 s4:
32 dout[4] = rx;
33 s5:
34 dout[5] = rx;
35 s6:
36 dout[6] = rx;
37 s7:
38 dout[7] = rx;
39 endcase
40 end
41
42 always @(posedge clk)
43 begin
44 if (rst == 0)
45 state = idle;
46 else
47 case (state)
48 idle:
49 state = s0;
50 s0:
51 state = s1;
52 s1:
53 state = s2;
54 s2:
55 state = s3;
56 s3:
57 state = s4;
58 s4:
59 state = s5;
60 s5:
61 state = s6;
62 s7:
63 state = stop;
64 stop:
65 state = idle;
66 default:
67 state=idle;
68 endcase
69 end
70
71 endmodule
Manufacturer:Xilinx
Product Categories: FPGAs (Field Programmable Gate Array)
Lifecycle:Obsolete -
RoHS:
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS: -
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS: No RoHS
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS: No RoHS
Manufacturer:Xilinx
Product Categories: FPGAs
Lifecycle:Obsolete -
RoHS:
Support