||
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity SERIAL is
Port ( clk,exreset,rx :in STD_LOGIC;
datain:in STD_LOGIC_vector(15 downto 0);
sendfinish,rxtest1 :buffer STD_LOGIC;
rxbuf:buffer std_logic_vector(7 downto 0);
tx,receivesuccess,stopbiterr,clkrxouttest,rxtest: out STD_LOGIC);
end SERIAL;
architecture Behavioral of SERIAL is
TYPE sreg IS (ready,startbitpending,startbitsure,receive);
signal sendprocess,serialtxclk,serialrxclk,success:STD_LOGIC;
signal clktxcount,overcount :integer range 0 to 511;
signal txbitcount,pendingcount:integer range 0 to 31;
signal shiftcount:integer range 0 to 15;
signal txshift:STD_LOGIC_vector(15 downto 0);
signal rxbitcount,clkrxcount,t2,t3,t4,t5:integer range 0 to 127;
signal bittemp:integer range 0 to 3;
signal rxshift:std_logic_vector(7 downto 0);
signal currentstate,nextstate:sreg;
begin
serialtxclkout:process(exreset,clk)
begin
if exreset='0' then
clktxcount<=0;
serialtxclk<='1';
elsif rising_edge(clk) then
if clktxcount=433 then
--if clktxcount=3 then
clktxcount<=0;
serialtxclk<='1';
else
clktxcount<=clktxcount+1;
if clktxcount=216 then
--if clktxcount=1 then
serialtxclk<='0';
end if;
end if;
end if;
end process serialtxclkout;
serialrxclkout:process(exreset,clk)
begin
if exreset='0' then
clkrxcount<=0;
clkrxouttest<='1';
serialrxclk<='1';
elsif rising_edge(clk) then
if clkrxcount=61 then
clkrxcount<=0;
clkrxouttest<='1';
serialrxclk<='1';
else
clkrxcount<=clkrxcount+1;
if clkrxcount=30 then
serialrxclk<='0';
clkrxouttest<='0';
end if;
end if;
end if;
end process serialrxclkout;
rxin:process(exreset,serialrxclk)
begin
if exreset='0' then
overcount<=0;
currentstate<=ready;
nextstate<=ready;
pendingcount<=0;
rxbitcount<=0;
success<='0';
elsif rising_edge(serialrxclk) then
if sendfinish='0' then
success<='0';
end if;
if overcount>70 then
currentstate<=ready;
nextstate<=ready;
pendingcount<=0;
rxbitcount<=0;
nextstate<=ready;
end if;
--rxtest1<=not rxtest1;
overcount<=overcount+1;
rxtest<=rx;
case currentstate is
when ready=>
if rx='0' then
rxbitcount<=0;
nextstate<=startbitpending;
pendingcount<=0;
overcount<=0;
rxtest1<='0';
t2<=8;
t3<=9;
t4<=10;
t5<=11;
end if;
when startbitpending=>
rxbitcount<=rxbitcount+1;
if rx='0' then
pendingcount<=pendingcount+1;
if pendingcount>3 then
nextstate<=startbitsure;
bittemp<=0;
shiftcount<=0;
receivesuccess<='0';
stopbiterr<='0';
else
rxtest1<='1';
end if;
else
pendingcount<=0;
nextstate<=ready;
end if;
when startbitsure=>
rxbitcount<=rxbitcount+1;
nextstate<=receive;
rxtest1<='0';
when receive=>
--rxtest1<=not rxtest1;
rxbitcount<=rxbitcount+1;
if rxbitcount=t2 then
rxtest1<=not rxtest1;
if rx='1' then
bittemp<=bittemp+1;
end if;
t2<=t2+7;
end if;
if rxbitcount=t3 then
rxtest1<=not rxtest1;
if rx='1' then
bittemp<=bittemp+1;
end if;
t3<=t3+7;
end if;
if rxbitcount=t4 then
rxtest1<=not rxtest1;
if rx='1' then
bittemp<=bittemp+1;
end if;
t4<=t4+7;
end if;
if rxbitcount=t5 then
rxtest1<=not rxtest1;
rxshift(6 downto 0)<=rxshift(7 downto 1);
if bittemp>1 then
rxshift(7)<='1';
else
rxshift(7)<='0';
end if;
bittemp<=0;
if shiftcount=8 then --对
if bittemp>1 then
receivesuccess<='1';
success<='1';
rxbuf<=rxshift(7 downto 0);
else
stopbiterr<='1';
end if;
nextstate<=ready;
else
nextstate<=receive;
shiftcount<=shiftcount+1;
t5<=t5+7;
end if;
end if;
when others=>
nextstate<=ready;
end case;
end if;
currentstate<=nextstate;
end process rxin;
txout:process(success,serialtxclk,exreset)
begin
if exreset='0' then
sendfinish<='1';
tx<='1';
txbitcount<=0;
sendprocess<='0';
else
--if (send='0') or (sendprocess='1') then
--if (rx='0') or (sendprocess='1') then
if (success='1') or (sendprocess='1') then
if rising_edge(serialtxclk) then
case txbitcount is
when 0=>
--txshift<=datain;
txshift<=rxbuf & rxbuf;
tx<='0';
sendfinish<='0';
sendprocess<='1';
txbitcount<=txbitcount+1;
when 10=>
tx<='0';
txbitcount<=txbitcount+1;
when 9=>
tx<='1';
txbitcount<=txbitcount+1;
when 19=>
sendfinish<='1';
sendprocess<='0';
txbitcount<=0;
tx<='1';
when others=>
tx<=txshift(0);
txshift(14 downto 0)<=txshift(15 downto 1);
txbitcount<=txbitcount+1;
end case;
end if;
end if;
end if;
end process txout;
end Behavioral;