UART异步通信收发9600Bit,收发大于4字节,串行通信。有奇偶校验位 顶层文件: library IEEE;
use IEEE.STD_LOGIC_11.all; use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all; entity uart is
port(clk0,reset00,reset2,reset3:in std_logic; inbuf:in std_logic_vector(7 downto 0); fready:out std_logic; rready:out std_logic; data1:out std_logic; data2:in std_logic; data3:out std_logic; data4:in std_logic; errors:out std_logic; outbuf1:out std_logic_vector(3 downto 0); outbuf2:out std_logic_vector(3 downto 0); outin1:out std_logic_vector(3 downto 0); outin2:out std_logic_vector(3 downto 0)); end uart;
architecture behavior of uart is component clock_div
port(clk2,reset0:in std_logic; bclk2:out std_logic); end component; component baud port(clk:in std_logic; bclk:out std_logic); end component; component transfer
port(bclkt,resett,xmit,erro:in std_logic; txdb:in std_logic_vector(7 downto 0); txddone:out std_logic; datat:out std_logic; txd:out std_logic); end component; component reciever
port(bclkr,resetr,rxdr,datar:in std_logic; r_ready:out std_logic; err_sync:out std_logic; rbuf:out std_logic_vector(7 downto 0)); end component;
signal bclk0,mirs,bclk22,data11,data22:std_logic;
signal output:std_logic_vector(7 downto 0); begin
process(clk0,reset00,reset2,reset3,inbuf) begin
outbuf1(3 downto 0)<=output(3 downto 0); outbuf2(3 downto 0)<=output(7 downto 4); outin1(3 downto 0)<=inbuf(3 downto 0); outin2(3 downto 0)<=inbuf(7 downto 4); errors<=mirs; end process;
u1:clock_div port map(clk2=>clk0,reset0=>reset00,bclk2=>bclk22); u2:baud port map(clk=>clk0,bclk=>bclk0); u3:transfer port map(bclkt=>bclk0,resett=>reset2,xmit=>bclk22,erro=>mirs,txdb=>inbuf,txddone=>fready,txd=>data1,datat=>data3); u4:reciever port map(bclkr=>bclk0,resetr=>reset3,rxdr=>data2,datar=>data4,r_ready=>rready,err_sync=>mirs,rbuf=>output); end behavior; 发送端: library IEEE;
use IEEE.STD_LOGIC_11.ALL; use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; entity transfer is
generic(framlent:integer:=8);
port(bclkt,resett,xmit,erro:in std_logic; txdb:in std_logic_vector(7 downto 0); txddone:out std_logic; datat:out std_logic; txd:out std_logic); end transfer;
architecture behavior of transfer is
type states is(x_idle,x_start,x_wait,x_shift,x_odd,x_stop); signal state:states:=x_idle; signal tcnt:integer:=0;
signal txdbuf:std_logic_vector(7 downto 0); begin
process(bclkt,resett,xmit,txdbuf)
variable xcnt16:std_logic_vector(4 downto 0):=\"00000\"; variable xbitcnt:integer:=0; variable txds:std_logic; variable odds:std_logic:='0'; begin
if resett='1' then state<=x_idle;
txddone<='0';txds:='1';txdbuf(7 downto 0)<=txdb(7 downto 0); elsif bclkt' event and bclkt='1' then case state is when x_idle=>
if xmit='1' then state<=x_start;txddone<='0';odds:='0'; else state<=x_idle; end if;
when x_start=>
if xcnt16=\"01111\" then state<=x_shift;xcnt16:=\"00000\"; else xcnt16:=xcnt16+1;txds:='0';state<=x_start; end if;
when x_wait=>
if xcnt16>=\"01110\"then
if xbitcnt=framlent then state<=x_odd;xbitcnt:=0;xcnt16:=\"00000\"; else state<=x_shift; end if;
xcnt16:=\"00000\";
else xcnt16:=xcnt16+1;state<=x_wait; end if;
when x_shift=>
txds:=txdbuf(xbitcnt);
odds:=not(odds xor(not txds)); xbitcnt:=xbitcnt+1; state<=x_wait; when x_odd=>
if xcnt16>=\"01111\" then state<=x_stop;xcnt16:=\"00000\"; else xcnt16:=xcnt16+1; txds:=not(odds); state<=x_odd; end if;
when x_stop=>
if xcnt16>=\"01111\" then
if xmit='0' then state<=x_idle; xcnt16:=\"00000\";
else xcnt16:=xcnt16;state<=x_stop; end if;
txddone<='1';
else xcnt16:=xcnt16+1;txds:='1';
if erro='0' then txdbuf(7 downto 0)<=txdb(7 downto 0); else txdbuf(7 downto 0)<=txdbuf(7 downto 0); end if;
state<=x_stop; end if;
when others=>state<=x_idle; end case; end if; txd<=txds; datat<=txds; end process; end behavior; 接收端: library IEEE;
use IEEE.STD_LOGIC_11.all; use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all; entity reciever is
generic(framlenr:integer:=8);
port(bclkr,resetr,rxdr,datar:in std_logic; r_ready:out std_logic; err_sync:out std_logic; rbuf:out std_logic_vector(7 downto 0)); end reciever;
architecture behavior of reciever is
type states is(r_start,r_center,r_wait,r_sample,r_odd,r_stop); signal state:states:=r_start; signal rxd_sync:std_logic; begin
pro1:process(rxdr) begin
if rxdr='0' then rxd_sync<='0'; else rxd_sync<='1'; end if;
end process;
pro2:process(bclkr,resetr,rxd_sync)
variable count:std_logic_vector(3 downto 0); variable rcnt:integer:=0;
variable rbufs:std_logic_vector(7 downto 0); variable rodds:std_logic:='0'; variable err:std_logic; begin
if resetr='1' then state<=r_start;count:=\"0000\";err:='0';err_sync<='0';r_ready<='0';rodds:='0'; elsif bclkr' event and bclkr='1' then case state is when r_start=>
if rxd_sync='0' then err:='0';err_sync<='0';rodds:='0';state<=r_center; r_ready<='0';rcnt:=0;
else state<=r_start;r_ready<='0';
end if;
when r_center=> if rxd_sync='0' then
if count=\"0100\" then state<=r_wait;count:=\"0000\"; else count:=count+1;state<=r_center; end if;
else state<=r_start; end if;
when r_wait=>
if count>=\"1110\" then
if rcnt=framlenr then state<=r_odd; else state<=r_sample; end if;
count:=\"0000\";
else count:=count+1;state<=r_wait; end if;
when r_sample=> rbufs(rcnt):=rxd_sync;
rodds:=not(rodds xor (not rxd_sync)); rcnt:=rcnt+1; state<=r_wait; when r_odd=>
if count>=\"1110\" then state<=r_stop; count:=\"0000\"; else count:=count+1;
err:=rxd_sync xor (not rodds); err_sync<=err; state<=r_odd; end if;
when r_stop=>
if count>=\"1110\" then
if rxd_sync='0' then state<=r_start;count:=\"0000\"; else count:=count;state<=r_stop; end if;
else count:=count+1;r_ready<='1'; rbuf<=rbufs; end if;
when others=> state<=r_start; end case; end if;
end process; end behavior;
分频: library IEEE;
use IEEE.STD_LOGIC_11.all; use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all; entity clock_div is
generic(framlenr:integer:=125000); port(clk2,reset0:in std_logic; bclk2:out std_logic); end clock_div;
architecture behavior of clock_div is begin
process(clk2,reset0) variable cnt:integer; begin
if reset0='1' then cnt:=0;bclk2<='0'; elsif clk2' event and clk2='1' then
if cnt>=framlenr then cnt:=0;bclk2<='1'; else cnt:=cnt+1;bclk2<='0'; end if; end if;
end process; end behavior; 波特率: library IEEE;
use IEEE.STD_LOGIC_11.ALL; use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; entity baud is
generic(framlenr: integer:=33); port(clk:in std_logic; bclk:out std_logic); end baud;
architecture behavior of baud is begin
process(clk)
variable cnt:integer; begin
if clk' event and clk='1' then
if cnt>=framlenr then cnt:=0;bclk<='1'; else cnt:=cnt+1;bclk<='0'; end if; end if;
end process;
end behavior;