📄 receiver.vhd
字号:
--异步接收电路VHDL程序。library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;entity receiver isport (rst,clk,rxd,ERBF : in std_logic ; dout : out std_logic_vector (7 downto 0) ; data_ready : out std_logic ; overrun_error : out std_logic; framing_error : out std_logic ; parity_error : out std_logic; clk46 : out std_logic; IQR : out std_logic ) ;end receiver; architecture behave of receiver issignal clklx : std_logic :='0';signal RBF,FE,PE,OE,LDSR,LDRB : std_logic;signal clkdiv : unsigned (5 downto 0) ;signal count : unsigned (4 downto 0);signal rsr : std_logic_vector (7 downto 0) ; --移位寄存器signal rbr : std_logic_vector (7 downto 0) ; --接收缓冲器signal shift :std_logic_vector(9 downto 0);signal cnt :integer range 0 to 10;signal IRQr : std_logic ;signal clkcnt :integer range 0 to 22;type state_typ is (s0,s1,s2,s3);signal Rx_State : state_typ;beginprocess(rst,clk)begin if rst='1' then RBF<='0'; --接受缓冲器指示信号,为1表示其内的信号有效。 data_ready<='0'; --接收数据完毕指示信号。 dout<="00000000"; --并行输出信号。 clkdiv<="000000"; --用于控制同步接受串行信号,采样率为时钟信号的1/45. count<="00000"; --用于判断起始信号是否符合要求。 rsr<="00000000"; --接受移位寄存器。 rbr<="00000000"; --接受缓冲寄存器。 FE<='0'; --帧错误指示信号。 PE<='0'; --奇校验错误指示信号。 cnt<=0; --监测接收数据的位数信号。 Rx_State<=s0; --状态信号。 LDRB<='0'; --接收缓存的'装入'命令信号。 LDSR<='0'; --收到'起始位'的指示信号。 IRQr<='0'; --接收中断信号。 elsif rising_edge(clk) then case Rx_State is when s0 => --空闲状态,时刻检测起始位,然后转移到s1状态。 count<="00000"; if rxd='1' then Rx_State<=s0; else Rx_State<=s1; end if; when s1 => --判断收到的起始位是否符合要求,持续时间足够长,而并非干扰信号。 count<=count+"00001";--若为真正的起始信号则转移到s2. if rxd='1' then Rx_State<=s0; elsif std_logic_vector(count)="11000" then Rx_State<=s2; LDSR<='1'; end if; when s2 => --接收状态,通过45进制计数器来同步采样接收信号。 if std_logic_vector(clkdiv) = "101110" then clkdiv<="000000"; else clkdiv<=clkdiv+"000001"; end if; if std_logic_vector(clkdiv) = "101110" then if cnt<10 then shift<=shift(8 downto 0)& rxd; --取出数据位,校验位和停止位 cnt<=cnt+1; else cnt<=0; Rx_State<=s3; end if; end if; when s3 => --监测状态,判断接受的信号是否有FE或PE错误。若都没则置LDRB为1,然后转移到空闲状态。 if shift(0)='0' then FE<='1'; elsif (shift(1)xor shift(2)xor shift(3)xor shift(4)xor shift(5)xor shift(6)xor shift(7)xor shift(8)xor shift(9))='1' then rsr(7)<=shift(2);rsr(6)<=shift(3); rsr(5)<=shift(4);rsr(4)<=shift(5); rsr(3)<=shift(6);rsr(2)<=shift(7); rsr(1)<=shift(8);rsr(0)<=shift(9); LDRB<='1'; else PE<='1'; end if; Rx_State<=s0; when others => Rx_State<=s0; end case; if LDRB='1' then --若LDRB为1,则将接受移位寄存器中的信号传给接收缓冲寄存器。 rbr<=rsr; RBF<='1'; LDRB<='0'; end if; if (ERBF='1' and RBF='1') then --如构有中断信号则停止输出数据,直到中断信号消失。 IRQr<='1'; elsif RBF='1' then --读出接收缓存器数据 dout<=rbr; data_ready<='1'; --接收数据完毕 RBF<='0'; IRQr<='0'; end if; end if;end process;IQR<=IRQr;process(clk) --该进程用于检测数据是否有溢出错误。begin if rst='1' then OE<='0'; elsif rising_edge(clk) then if LDRB='1' and RBF='1' then OE<='1'; end if; if RBF='0' then OE<='0'; end if; end if;end process;process (rst,clk) --46分频的信号,用于对照作用。begin if rising_edge(clk) then if clkcnt=22 then clkcnt<=0; clklx <= not clklx; else clkcnt <= clkcnt + 1; end if; end if ;end process ;clk46<=clklx;overrun_error<=OE;framing_error<=FE;parity_error<=PE;end behave;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -