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

📄 uart transmitter.txt

📁 UART Transmitter. VHDL code and its testbench.
💻 TXT
字号:
library	ieee;
use ieee.std_logic_1164.all;

package my_package is

    FUNCTION parity(inputs: std_logic_vector(7 downto 0)) RETURN std_logic;

end my_package;

PACKAGE body my_package is
	
    FUNCTION parity(inputs: std_logic_vector(7 downto 0)) RETURN std_logic is
    variable temp: std_logic;
    begin
	temp:='0';
	for i in 7 downto 0 loop
	    temp:=temp xor inputs(i);
	end loop;
	    return temp;
	end parity;		

end my_package;

--------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;	 
use ieee.std_logic_unsigned.all;
use work.my_package.all;
--------------------------------------------------------------------------
entity trans is							
port(	TRC:		in std_logic;
	MR:		in std_logic;
	TBRL:		in std_logic;
	SFD:		in std_logic;
	CRL:		in std_logic;
	CTRLWORD:	in std_logic_vector(4 downto 0);
	TBR:		in std_logic_vector(7 downto 0);
	TRE:		out std_logic;
	TBRE:		out std_logic;
	TRO:		out std_logic
);	
end trans;
------------------------------------------------------------------------
architecture behv of trans is			 

    constant C0: unsigned(4 downto 0):="00001";
    constant CI: unsigned(4 downto 0):="01000";
    constant CM: unsigned(4 downto 0):="10000";
    constant MM: unsigned(3 downto 0):="1111";
    signal trans_reg: std_logic_vector(11 downto 0);
    signal trans_reg_temp: std_logic_vector(11 downto 0);
    signal TBR_sig: std_logic_vector(7 downto 0);
    signal old_tbr_sig: std_logic_vector(7 downto 0);
    signal delay: std_logic_vector(0 downto 0);	  
    signal go: std_logic;
    signal t_pari: std_logic;
    signal clk: std_logic;
    signal i: unsigned(3 downto 0);
    signal ctrl_word: std_logic_vector(4 downto 0);

begin

--P0: process(MR,TRC,i,TBR)		-- generate 16* clock
--begin
--	if MR='1' then
--		i<="00000";
--	elsif TRC='1' and TRC'event then
--		i<=i+C0;
--		if i=CI then
--			clk<='1';
--		elsif i=CM then
--			i<="00000";
--			clk<='0';
--		end if;
--	end if;
--end process;

P1: process(CRL,CTRLWORD)		-- load control word here
    begin
	if CRL='1' then
	    ctrl_word<=CTRLWORD;
	end if;
    end process;
	
-- this process make out the transmit register according to control word.
P2: process(clk,ctrl_word,MR,TBR,TBRL,TBR_sig,t_pari)
    begin
	if (MR='1') then
	    TBR_sig<="11111111"; 
	    t_pari <= '0';
	    trans_reg_temp <= "1111" & TBR_sig;
	else
	    if TBRL='0' then	
		TBR_sig <= TBR;
		t_pari <= parity(TBR);	-- call function and compute the parity
	    end if;
			
	case ctrl_word is
	    when "00000"|"00001" =>		
		if t_pari='0' then				-- odd parity
		    trans_reg_temp <= "111" & "11" & '1' & TBR_sig(4 downto 0) & '0';	 	  
		elsif t_pari='1' then				-- even parity
		    trans_reg_temp <= "111" & "11" & '0' & TBR_sig(4 downto 0) & '0';
		end if;		
	    when "00010"|"00011" =>
		if t_pari='0' then				-- odd parity
		    trans_reg_temp <= "111" & "11" & '0' & TBR_sig(4 downto 0) & '0';	 	  
		elsif t_pari='1' then				-- even parity
		    trans_reg_temp <= "111" & "11" & '1' & TBR_sig(4 downto 0) & '0';
		end if;			
	    when "00100"|"00110"|"00101"|"00111" =>		-- no parity
		trans_reg_temp <= "1111" & "11" & TBR_sig(4 downto 0) & '0';
	    when "01000"|"01001" =>
		if t_pari='0' then				-- odd parity
		    trans_reg_temp <= "11" & "11" & '1' & TBR_sig(5 downto 0) & '0';	 	  
		elsif t_pari='1' then				-- even parity
		    trans_reg_temp <= "11" & "11" & '0' & TBR_sig(5 downto 0) & '0';
		end if;		
	    when "01010"|"01011" =>
		if t_pari='0' then				-- odd parity
		    trans_reg_temp <= "11" & "11" & '0' & TBR_sig(5 downto 0) & '0';	 	  
		elsif t_pari='1' then				-- even parity
		    trans_reg_temp <= "11" & "11" & '1' & TBR_sig(5 downto 0) & '0';
		end if;
	    when "01100"|"01110"|"01101"|"01111" =>		-- no parity
		trans_reg_temp <= "111" & "11" & TBR_sig(5 downto 0) & '0';		
	    when "10000"|"10001" =>
		if t_pari='0' then				-- odd parity
		    trans_reg_temp <= '1' & "11" & '1' & TBR_sig(6 downto 0) & '0';	 	  
		elsif t_pari='1' then				-- even parity
		    trans_reg_temp <= '1' & "11" & '0' & TBR_sig(6 downto 0) & '0';
		end if;						
	    when "10010"|"10011" =>
		if t_pari='0' then				-- odd parity
		    trans_reg_temp <= '1' & "11" & '0' & TBR_sig(6 downto 0) & '0';	 	  
		elsif t_pari='1' then				-- even parity
		    trans_reg_temp <= '1' & "11" & '1' & TBR_sig(6 downto 0) & '0';
		end if;								 
	    when "10100"|"10110"|"10101"|"10111" =>		-- no parity
		trans_reg_temp <= "11" & "11" & TBR_sig(6 downto 0) & '0';		
	    when "11000"|"11001" =>
		if t_pari='0' then				-- odd parity
		    trans_reg_temp <= "11" & '1' & TBR_sig(7 downto 0) & '0';	 	  
		elsif t_pari='1' then				-- even parity
		    trans_reg_temp <= "11" & '0' & TBR_sig(7 downto 0) & '0';
		end if;						
	    when "11010"|"11011" =>	
		if t_pari='0' then				-- odd parity
		    trans_reg_temp <= "11" & '0' & TBR_sig(7 downto 0) & '0';	 	  
		elsif t_pari='1' then				-- even parity
		    trans_reg_temp <= "11" & '1' & TBR_sig(7 downto 0) & '0';
		end if;			
	    when others =>					-- no parity
		trans_reg_temp <= '1' & "11" & TBR_sig(7 downto 0) & '0';	
	end case;				
    end if;	
end process;

-- P3 describes the whole transmission procedure
P3: process
	variable cnt: integer range 0 to 12;    	
	variable cnt_limit: integer range 0 to 12;
    begin
		
	wait until TRC'event and TRC='1'; 

	if MR='1' then
	    old_tbr_sig <= "11111111";
	    delay<="0";
	    go<='0';
	    i <= "0000";
	else
	    if (i=MM) then
		i<="0000";
		if(go='0') then					
		    delay<="0";			
		    cnt := 12;
		    TRE <= '1';
		    if (old_tbr_sig=TBR_sig) then
			go <= '0';	 
		    elsif (old_tbr_sig/=TBR_sig) then
	 		go <='1';
	 	    end if;
		    trans_reg <= "111111111111";		
		elsif (go='1' and delay="0") then		  
		    go<='1';
		    cnt:=0;				
		    delay<=delay+1;					
		    TRE <= '1';
		    trans_reg <= "111111111111";			
		elsif (go='1' and delay="1" and cnt=0) then	 
		    go <= '1';
	 	    cnt:=cnt+1;	
	 	    delay<=delay+0;		
	 	    old_tbr_sig<=TBR_sig;	   
	 	    TRE<='0';		
		    trans_reg <= trans_reg_temp;
		elsif (go='1' and delay="1" and cnt/=0) then  		   
		    trans_reg <= '1' & trans_reg(11 downto 1);
		    case ctrl_word(4 downto 2) is		  
			when "000" => 	if ctrl_word(0)='0' then
					    cnt_limit := 8;
					elsif ctrl_word(0)='1' then
					    cnt_limit :=9;
					end if;
			when "001" => 	if ctrl_word(0)='0' then
					    cnt_limit := 7;
					elsif ctrl_word(0)='1' then
					    cnt_limit :=8;
					end if;
			when "010" => 	if ctrl_word(0)='0' then
					    cnt_limit := 9;
					elsif ctrl_word(0)='1' then
					    cnt_limit :=10;
					end if;
			when "011" => 	if ctrl_word(0)='0' then
					    cnt_limit := 8;
					elsif ctrl_word(0)='1' then
					    cnt_limit :=9;
					end if;
			when "100" => 	if ctrl_word(0)='0' then
					    cnt_limit := 10;
					elsif ctrl_word(0)='1' then
					    cnt_limit :=11;
					end if;
			when "101" => 	if ctrl_word(0)='0' then
					    cnt_limit := 9;
					elsif ctrl_word(0)='1' then
					    cnt_limit :=10;
					end if;
			when "110" => 	if ctrl_word(0)='0' then
					    cnt_limit :=11;
					elsif ctrl_word(0)='1' then
					    cnt_limit :=12;
					end if;
			when "111" => 	if ctrl_word(0)='0' then
					    cnt_limit :=10;
					elsif ctrl_word(0)='1' then
					    cnt_limit :=11;
					end if;				
			when others =>
		    end case;
		
		    if cnt/=cnt_limit then
			go <= '1';
			delay<=delay+0;
			cnt:=cnt+1;			
			TRE<='0';			    
	 	    elsif cnt=cnt_limit then 	 		
			go <= '0';
			delay<="0"; 	
			TRE<='1';	
		    end if;	   				
		end if; 		

		if SFD='1' then					
	 	    TBRE <= 'Z';			
	 	elsif SFD='0' then 
		    if (cnt=0 or cnt=1) then 
			TBRE <= '0';
		    else
			TBRE <= '1';
		    end if;
		end if;
	    else
		i<=i+1;		
	    end if;
	end if;
end process;
	
	-- this cocurrent statement handles the serial output of Transmitter
	tro <= trans_reg(0);
	
end behv;

⌨️ 快捷键说明

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