📄 u_rec.vhd
字号:
-- SUART Project
--
-- U_REC.vhd
-- 接收模块
--
-- Design By jy2010
-- Update:
-- 19/12/2002 归档
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity u_rec is
generic (FrameLen : integer := 8 );
port(resetL : in std_logic; -- 异步复位,低电平有效
bclk : in std_logic; -- UART Clock,16倍于波特率
-- uart
rxd : in std_logic; -- UART接收端
rbuf : out std_logic_vector(Framelen-1 downto 0); -- 接收缓冲区
rec_ready : out std_logic); -- 接收准备信号,当变高电平时,数据接收完毕
end u_rec;
ARCHITECTURE behv OF u_rec IS
-- 接收状态机状态定义
type r_state_type is (r_start,r_center,r_wait,r_sample,r_stop);
signal next_state,state : r_state_type;
signal rxd_sync : std_logic; -- rxd同步信号
signal rcnt16 : std_logic_vector(3 downto 0); -- 16×计数器
signal rcnt16_clr : std_logic;
signal sertopar : std_logic_vector(FrameLen-1 downto 0); -- 移位寄存器
signal rshift_en : std_logic;
signal rbitcnt : std_logic_vector(3 downto 0); -- 接收位计数器
signal rbitcnt_en : std_logic;
signal rbitcnt_clr : std_logic;
signal rec_done : std_logic; -- 接收完毕信号
BEGIN
-- 同步异步串行输入rxd
process(bclk,resetL)
begin
if(resetL = '0') then
rxd_sync <= '1';
elsif(bclk'event and bclk = '1') then
rxd_sync <= rxd;
end if;
end process;
-- 16×计数器
bcnt_proc:process(bclk,resetL)
begin
if(resetL = '0') then
rcnt16 <= "0000";
elsif(bclk'event and bclk = '1') then
if(rcnt16_clr = '1') then
rcnt16 <= "0000";
else
rcnt16 <= rcnt16 + 1;
end if;
end if;
end process;
-- 串并转换,低位(LSB)先移入
s2p_proc:process(bclk,resetL)
begin
if(resetL = '0') then
sertopar <= (others => '0');
elsif(bclk'event and bclk = '1') then
if(rshift_en = '1') then
sertopar <= rxd_sync & sertopar(7 downto 1);
end if;
end if;
end process;
-- 接收位计数器
bitcnt_proc:process(bclk,resetL)
begin
if(resetL = '0') then
rbitcnt <= "0000";
elsif(bclk'event and bclk = '1') then
if(rbitcnt_en = '1') then
rbitcnt <= rbitcnt + 1;
elsif(rbitcnt_clr = '1') then
rbitcnt <= "0000";
end if;
end if;
end process;
next_proc:process(bclk,resetL)
begin
if(resetL = '0') then
state <= r_start;
elsif(bclk'event and bclk = '1') then
state <= next_state;
end if;
end process;
-- 接收状态机
r_state:process(state,rxd_sync,rcnt16,rbitcnt)
begin
-- default
rcnt16_clr <= '1';
rshift_en <= '0';
rbitcnt_en <= '0';
rbitcnt_clr <= '0';
rec_done <= '0';
case (state) is
-- START State 等待 Start bit
when r_START =>
if (rxd_sync = '0') then
next_state <= r_CENTER; -- 检测到Start bit
else
next_state <= r_START; -- 继续等待
rbitcnt_clr <= '1';
rec_done <= '1';
end if;
-- CENTER State 取采样中点
when r_CENTER =>
if (rcnt16 = "0100") then
if (rxd_sync = '0') then
next_state <= r_WAIT; -- 准备等待中点采样
else -- 不到位中点信号复为零,是干扰
next_state <= r_START;
end if;
else
next_state <= r_CENTER; -- 等待中点到来
rcnt16_clr <= '0'; -- 16×计数器开始计数
end if;
-- WAIT State 等待采样
when r_WAIT =>
if (rcnt16 = "1110") then
if (rbitcnt = FrameLen) then
next_state <= r_STOP; -- 数据位接收完成
else
next_state <= r_SAMPLE;
end if;
else
next_state <= r_WAIT;
rcnt16_clr <= '0';
end if;
-- SAMPLE State 采样
when r_SAMPLE =>
rshift_en <= '1'; -- 串并转换使能
rbitcnt_en <= '1'; -- 位计数器使能
next_state <= r_WAIT;
-- STOP State 接收停止位
when r_STOP=>
next_state <= r_START;
rec_done <= '1';
when others =>
next_state <= r_START;
end case;
end process;
-- 接收准备信号落后接收好一个bclk周期
process(bclk,resetL)
begin
if(resetL = '0') then
rec_ready <= '0';
elsif(bclk'event and bclk = '1') then
rec_ready <= rec_done;
end if;
end process;
-- 在blk的下降沿锁存接收的数据至rbuf
process(bclk)
begin
if(bclk'event and bclk = '0') then
if(rec_done = '1' ) then
rbuf <= sertopar;
end if;
end if;
end process;
end behv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -