📄 uart transmitter.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 + -