|
大家好,以下是我down的uart发送器的代码,基本看懂了,但是有几个问题请教一下:
1、if rst = '1' then
clk1x_enable <= '0' ;
tbre <= '0' ;
这里tbre是不是应该为1,表示空的状态啊?
2、elsif std_logic_vector(no_bits_sent) = "1101" then
clk1x_enable <= '0' ;
为什么选择1101这个状态设置enable为0,在1010时就已经发送完数据了啊?
3、if std_logic_vector(no_bits_sent) = "0001" then
tsr <= tbr ;
tsre <= '0' ;
这里tsre设置为0后,应该表示满的状态,那什么时候再设置为'1',代码里好像没有啊?
并请各位看看我的注释有没有问题?谢谢!
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_arith.all ;
entity txmit is
port (rst,clk16x,wrn : in std_logic ;--wrn为CPU发过来的8位数据锁存信号;
din : in std_logic_vector(7 downto 0) ;
tbre : out std_logic ;--发送缓冲区标志位;
tsre : out std_logic ;--发送移位缓冲区标志位;
sdo : out std_logic
) ;
end txmit ;
architecture v1 of txmit is
signal clk1x_enable : std_logic ;--使能内部时钟;
signal tsr : std_logic_vector (7 downto 0) ;
signal tbr : std_logic_vector (7 downto 0) ;
signal parity : std_logic ;
signal clkdiv : unsigned (3 downto 0) ;
signal clk1x : std_logic ;
signal no_bits_sent : unsigned (3 downto 0) ;
signal wrn1 : std_logic ;
signal wrn2 : std_logic ;--wrn2,wrn1用来对cpu发过来的锁存信号延时两个cycle;
begin
process (rst,clk16x)
begin
if rst = '1' then --这里'1'都表示有效,如复位、发送缓冲区为空等;
wrn1 <= '1' ;
wrn2 <= '1' ;
elsif clk16x'event and clk16x = '1' then
wrn2 <= wrn1 ;
wrn1 <= wrn ;
end if ;
end process ;
process (rst,clk16x)
begin
if rst = '1' then
clk1x_enable <= '0' ;
tbre <= '0' ; --这里tbre应该是1,表示为空的状态?
elsif clk16x'event and clk16x = '1' then --在时钟的上升沿,如果wrn1=0,而且wrn2为1,则表示cpu发出的wrn从1
if wrn1 = '0' and wrn2 = '1' then --跳到了0,这里实际上只能采到wrn1,wrn2是读锁存器里的值,表示
tbre <= '0' ; --cpu要发数据了。
clk1x_enable <= '1' ;
elsif std_logic_vector(no_bits_sent) = "0010" then --这里0010表示发送缓冲区为空的一个状态,如这里写tbre='1';
tbre <= '1' ; --因为0001时刻,tbr中的数据已经给tsr了,也表示可以写往里写数据了。
elsif std_logic_vector(no_bits_sent) = "1101" then --这里1101应该表示为发送结束的一个状态。为什么选这个状态?
clk1x_enable <= '0' ;
end if ;
end if ;
end process ;
process (rst,wrn) --wrn=0表示cpu要发数据了的一个标志,由于cpu发出。
begin
if rst = '1' then
tbr <= (others => '0') ;
elsif wrn'event and wrn = '0' then
tbr <= din ;
end if ;
end process ;
process (rst,clk16x,clk1x_enable)
begin
if rst = '1' then
clkdiv <= "0000" ;
elsif clk16x'event and clk16x = '1' then
if clk1x_enable = '1' then
clkdiv <= clkdiv + "0001" ;
end if ;
end if ;
end process ;
clk1x <= clkdiv(3) ;
process (rst,clk1x,no_bits_sent,tbr) --这里clk1x每16个 clk16x就变一次1,因此可以用clk1x来打数据。
begin
if rst = '1' then
sdo <= '1' ;
tsre <= '1' ;
tsr <= "00000000" ;
parity <= '1' ;
elsif clk1x'event and clk1x = '1' then
if std_logic_vector(no_bits_sent) = "0001" then
tsr <= tbr ;
tsre <= '0' ; --表示tsre不为空,里面有数据。这里tsre什么时候置'1'?
elsif std_logic_vector(no_bits_sent) = "0010" then
sdo <= '0' ; --这里0010表示要发送器要发送数据的状态,因为复位时为'1',
--现在tsr中有待发送的数据后,则输出sdo=0,告诉接收的uart设备我要发数据了。
elsif std_logic_vector(no_bits_sent) >= "0011" and std_logic_vector(no_bits_sent) <= "1010" then
tsr <= tsr(6 downto 0) & '0' ; --从0011开始打数据,一直到1010,打完8位数据。
sdo <= tsr(7) ;
parity <= parity xor tsr(7) ;
end if ;
end if ;
end process ;
process (rst,clk1x,clk1x_enable)
begin
if rst = '1' or clk1x_enable = '0' then
no_bits_sent <= "0000" ;
elsif clk1x'event and clk1x = '1' then --no_bits_sent也是每16个clk16x就变一次;
if clk1x_enable = '1' then
no_bits_sent <= no_bits_sent + "0001" ;
end if ;
end if ;
end process ;
end ; |
|