⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex_7_1_uart.vhd

📁 This is the course for VHDL programming
💻 VHD
字号:
library ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;entity tx_datapath is	port(	din 		: in std_logic_vector (7 downto 0) ;		state 	: in std_logic_vector (3 downto 0) ;		rst,wrn,clk1x: in std_logic;		sdo,tsre	: out std_logic	    );end tx_datapath;architecture a of tx_datapath is	signal tsr : std_logic_vector (7 downto 0) ;	--Tx shift reg	signal tbr : std_logic_vector (7 downto 0) ;	--Tx buffer regbegin	--TBR process - load tbr with wrn	process (rst,wrn,din)	begin		if rst = '1' then			tbr <= (others => '0') ;		elsif wrn'event and wrn = '0' then			tbr <= din ;		end if ;	end process ;	--Main shifter process	process (rst,clk1x,state,tbr)	begin		if rst = '1' then 			sdo <= '1' ;--serial data out(sdo)=1 in idle state			tsre <= '1' ;			tsr <= "00000000" ;		elsif clk1x'event and clk1x = '1' then			if 	state = "0001" then				tsr <= tbr ;--trans tbr to tsr				tsre <= '0' ;--tsr is not empty now			elsif 	state = "0010" then				sdo <= '0' ;--send start bit			elsif 	state >= "0011" and state <= "1011" then				--between count 3 to 11, shift left tsr				tsr <= '1' & tsr(7 downto 1);				sdo <= tsr(0) ;--rightmost bit is output			elsif 	state = "1100" then				tsre <= '1' ;			end if ;		end if ;	end process ;end a;library ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;use ieee.std_logic_unsigned.all ;entity tx_clockgen is	port(	state 		: in std_logic_vector (3 downto 0) ;		rst,wrn,clk16x 	: in std_logic;		clk1x,clk1x_enable,tbre: out std_logic	    );end tx_clockgen;architecture a of tx_clockgen is	signal clkdiv : std_logic_vector (3 downto 0) ;	signal clk_enable,wrn1,wrn2,tbre_int:std_logic;begin	process (rst,clk16x,clk_enable)	begin		if rst = '1' then			clkdiv <=  "0000" ;		elsif clk16x'event and clk16x = '1' then			if clk_enable = '1' then				clkdiv <= clkdiv + 1 ;			end if ;		end if ;	end process ;	clk1x <= clkdiv(3) ;--MSB of Divide counter is clk1x	clk1x_enable<=clk_enable;	--Clock enable process	--Neg edge of wrn sets clk1x_enable and bit counter --reaching 1101 resets it	process (rst,clk16x,wrn,wrn1,wrn2,tbre_int)	begin		if rst = '1' then			clk_enable <= '0' ;--Initially div cntr is disabled			tbre_int <= '1' ;			--Initial tbr is empty			wrn1<='1';wrn2<='1';		elsif clk16x'event and clk16x = '1' then			wrn1<=wrn;wrn2<=wrn1;		--Produce delayed wrn			if wrn1 = '0' and wrn2 = '1' then --fall edge of wrn				tbre_int <= '0' ;		  --Make tbr not empty				clk_enable <= '1' ;	  --Enable div clk			elsif std_logic_vector(state) = "0010" then				tbre_int <= '1' ;					--After sending 2 bits, tbr is ready			elsif std_logic_vector(state) = "1101" then				clk_enable <= '0' ;  --stop clk after 13 pulses			elsif (state = 0) and (tbre_int='0') then				clk_enable <= '1' ;			end if ;		end if ;		tbre<=tbre_int;	end process ;	end a;library ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;use ieee.std_logic_unsigned.all ;entity tx_control is	port(	state 	: out std_logic_vector (3 downto 0) ;		rst	 	: in std_logic;		clk1x,clk1x_enable: in std_logic	    );end tx_control;architecture a of tx_control is	signal state_cntr : std_logic_vector (3 downto 0) ;begin	--state counter logic	process (rst,clk1x,clk1x_enable)	begin		if rst = '1' or clk1x_enable = '0' then			state_cntr <= "0000" ;		elsif clk1x'event and clk1x = '1' then			if clk1x_enable = '1' then				state_cntr <= state_cntr + 1 ;			end if ;		end if ;	end process ;	state<=state_cntr;end a;library ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;entity txmit1 isport (rst,clk16x,wrn : in std_logic ;--wrn is write enable bar	din : in std_logic_vector(7 downto 0) ;--Parallel data in	tbre : out std_logic ;--Tx buffer empty	tsre : out std_logic ;--Tx shift reg empty	sdo  : out std_logic  --serial data out     ) ;end txmit1 ;architecture v1 of txmit1 is	component tx_datapath		port(	din 		: in std_logic_vector (7 downto 0) ;			state 	: in std_logic_vector (3 downto 0) ;			rst,wrn,clk1x 	: in std_logic;			sdo,tsre	: out std_logic	    	    );	end component;	component tx_clockgen		port(	state 	: in std_logic_vector (3 downto 0) ;			rst,wrn,clk16x 	: in std_logic;			clk1x,clk1x_enable,tbre: out std_logic	    	    );	end component;	component tx_control		port(	state 	: out std_logic_vector (3 downto 0) ;			rst	 	: in std_logic;			clk1x,clk1x_enable: in std_logic	    	    );	end component;	signal state: std_logic_vector (3 downto 0) ;	signal clk1x,clk1x_enable  :std_logic;begin	dat:tx_datapath port map(din,state,rst,wrn,clk1x,sdo,tsre);	cgn:tx_clockgen port map(state,rst,wrn,clk16x,clk1x,clk1x_enable,tbre);	ctr:tx_control  port map(state,rst,clk1x,clk1x_enable);end v1;--UART receiver--************************library ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;use ieee.std_logic_unsigned.all ;entity rcvr_ctrl is	port (	rst,clk16x,rxd,rdn : in std_logic ;		no_bits_rcvd:out std_logic_vector (3 downto 0);		clk1x,data_ready : out std_logic 	      ) ;end rcvr_ctrl ;architecture a of rcvr_ctrl is	signal rxd1,rxd2 : std_logic ;--delayed rxd	signal clk1x_enable : std_logic ;--twice delayed rxd	signal bits_rcvd : std_logic_vector(3 downto 0) ;	signal clkdiv : std_logic_vector(3 downto 0) ;begin	--Clock generator logic	process (rst,clk16x,rxd1,rxd2,rxd,bits_rcvd,clkdiv)	begin		if rst = '1' or bits_rcvd = 12 then			rxd1 <= '1' ; rxd2 <= '1' ;			clk1x_enable <= '0';clkdiv <= "0000" ;		elsif clk16x'event and clk16x = '1' then			rxd2 <= rxd1 ; rxd1 <= rxd ;			if rxd1 = '0' and rxd2 = '1' then				clk1x_enable <= '1' ;			end if ;			if clk1x_enable = '1' then				clkdiv <= clkdiv + "0001" ;			end if ;		end if ;		clk1x <= clkdiv(3);	end process ;	--bit counting logic	process (rst,clkdiv,clk1x_enable,bits_rcvd)	beginif rst = '1' or (bits_rcvd = 12 and clk1x_enable = '0')       then			bits_rcvd <= "0000" ;		elsif clkdiv(3)'event and clkdiv(3) = '1' then			if clk1x_enable = '1' then				bits_rcvd <= bits_rcvd + 1 ;			end if ;		end if ;	end process ;		--data ready logic - data_ready =1 when no_bits_rcvd = "1100"	process (rst,clkdiv,rdn,bits_rcvd)	begin		if rst = '1' or rdn = '0' then			data_ready <= '0' ;		elsif clkdiv(3)'event and clkdiv(3) = '1'  then			if bits_rcvd = 10 then	data_ready <= '1' ;			end if ;		end if ;	end process ;	no_bits_rcvd <= bits_rcvd;end a;--receiver shift registerslibrary ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;use ieee.std_logic_unsigned.all ;entity rcvr_regs is	port (	rst,clk1x,rdn,rxd : in std_logic ;		no_bits_rcvd:in std_logic_vector (3 downto 0);		dout : out std_logic_vector (7 downto 0)	      ) ;end rcvr_regs ;architecture a of rcvr_regs is	signal rsr : std_logic_vector (7 downto 0) ;--rcv shift reg	signal rbr : std_logic_vector (7 downto 0) ;--rcv buf regbegin	--rbr and rsr logic	process (clk1x,rst)	begin		if rst = '1' then			rsr <= "00000000" ; rbr <= "00000000" ;		elsif clk1x'event and clk1x = '1' then			if no_bits_rcvd >= 1 and no_bits_rcvd <= 8 then				rsr(7) <= rxd ;				rsr(6 downto 0) <= rsr(7 downto 1) ;			elsif no_bits_rcvd = 10 then rbr <= rsr ;			end if ;		end if ;	end process ;	dout <= rbr;end a;library ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;entity rcvr is	port (	rst,clk16x,rxd,rdn : in std_logic ;		dout : out std_logic_vector (7 downto 0) ;		data_ready : out std_logic 	      ) ;end rcvr ;architecture v2 of rcvr is	component rcvr_ctrl	port (	rst,clk16x,rxd,rdn : in std_logic ;		no_bits_rcvd:out std_logic_vector (3 downto 0);		clk1x,data_ready : out std_logic 	      ) ;	end component;	component rcvr_regs		port (	rst,clk1x,rdn,rxd : in std_logic ;		no_bits_rcvd:in std_logic_vector (3 downto 0);		dout : out std_logic_vector (7 downto 0)	        ) ;		end component;	signal no_bits_rcvd: std_logic_vector (3 downto 0);	signal dout_int: std_logic_vector (7 downto 0);	signal clk1x : std_logic ;begin	ctrl:rcvr_ctrl port map(rst,clk16x,rxd,rdn,no_bits_rcvd,clk1x,data_ready);	regs:rcvr_regs port map(rst,clk1x,rdn,rxd,no_bits_rcvd,dout_int);	dout <= dout_int when rdn = '0' else "ZZZZZZZZ" ;end v2;--UART--************************library ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;entity uart is	port (	rst,clk16x,rxd,rdn,wrn : in std_logic ;		dout : out std_logic_vector (7 downto 0) ;		din  : in  std_logic_vector (7 downto 0) ;		data_ready,tbre,tsre,sdo : out std_logic 	      ) ;end uart ;architecture a of uart is	component txmit1		port (rst,clk16x,wrn : in std_logic ;--wrn is wr enable bar		din : in std_logic_vector(7 downto 0) ;--Parallel data in		tbre : out std_logic ;--Tx buffer empty		tsre : out std_logic ;--Tx shift reg empty		sdo  : out std_logic  --serial data out     		) ;	end component;	component rcvr		port (	rst,clk16x,rxd,rdn : in std_logic ;		dout : out std_logic_vector (7 downto 0) ;		data_ready : out std_logic 	      ) ;	end component;begin	r:rcvr port map(rst,clk16x,rxd,rdn,dout,data_ready);	t:txmit1 port map(rst,clk16x,wrn,din,tbre,tsre,sdo);end a;library ieee ;use ieee.std_logic_1164.all ;entity uart_tb is end uart_tb;architecture beh of uart_tb is   signal rst,clk16x,rdn,wrn: std_logic ;	signal dout: std_logic_vector (7 downto 0);	signal din : std_logic_vector (7 downto 0);	signal data_ready,tbre,tsre:std_logic;	signal run:std_logic:='0';	signal rxd_sdo:std_logic;begin    clk16X <= not clk16X after 10 ns              when run = '1' else '0';    U:entity work.UART port map       (	rst, clk16x, rxd_sdo, rdn, wrn,		   dout,  din,		   data_ready,tbre,tsre,rxd_sdo	     ) ;	 process	 begin	     rst <='1';din <= "11110101";rdn<='1';	     wrn <= '1';	     wait for 10 ns;	     rst <='0';wait for 10 ns;	     run <= '1';	     wrn <='0';wait for 10 ns;	     wrn <='1';wait for 10 ns;	     wait until tsre = '1';	     report "Byte transmitted";	     wait until data_ready = '1';	     report "Byte received";	     wait;	 end process;end beh;	        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -