⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chuankou.txt

📁 串口VHDL实现 串口VHDL实现
💻 TXT
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity sci is
  port(clk,reset,rxd,rd,wr,cs:in std_ulogic;
       txd,rdfull,tdemptyut std_ulogic;
       data_in:in std_logic_vector(7 downto 0);
       data_outut std_logic_vector(7 downto 0));
end sci;
architecture rtl of sci is
  signal scir:std_ulogic_vector(5 downto 0);
  signal scit:std_ulogic_vector(5 downto 0);
  signal sh_r:std_ulogic_vector(3 downto 0);
  signal sl_r:std_ulogic_vector(1 downto 0);
  signal sh_t:std_ulogic_vector(3 downto 0);
  signal sl_t:std_ulogic_vector(1 downto 0);
  signal d_fb:std_ulogic_vector(7 downto 0);
  signal din_latch:std_ulogic_vector(7 downto 0);
  signal do_latch:std_ulogic_vector(7 downto 0);
  signal txdf,rxdf:std_ulogic;
  signal tdempty_s:std_ulogic:='1';
  signal rdfull_s:std_ulogic:='0';
begin
sh_r<=scir(5 downto 2);
sl_r<=scir(1 downto 0);
sh_t<=scit(5 downto 2);
sl_t<=scit(1 downto 0);

tdempty<=tdempty_s;
rdfull<=rdfull_s;

process(clk,rd,cs)
  begin
   if(rd='0' and cs='0')then
      rdfull_s<='0';
   elsif(clk'event and clk='1')then
         if((rxdf='1')and (sh_r="1111")and(sl_r="11"))then
            do_latch<=d_fb;
            rdfull_s<='1';
         end if ;
       end if;
  end process;
process(wr,cs)
variable data_v:std_logic_vector(7 downto 0);
begin
  if(wr'event and wr='1')then
   if(cs='0')then
    data_v:=data_in;
    din_latch<=to_stdulogicvector(data_v);
   end if;
  end if;
end process;

process(clk)
begin
  if(clk'event and clk='1')then
    if(rxd='0')then
     rxdf<='1';
  elsif((rxdf='1')and(sh_r="1111")and(sl_r="11"))then
     rxdf<='0';
  end if;
end if;
end process;

process(wr,clk,cs)
  begin
   if(wr='0'and cs='0')then
    txdf<='0';
    tdempty_s<='0';
   elsif(clk'event and clk='1')then
     if(((txdf='0')and(sh_t="1111")and(sl_t="11"))or reset='0')then
     tdempty_s<='1';
     txdf<='1';
     end if;
   end if;
end process;

process(rd,cs,do_latch)
variable do_latch_v:std_ulogic_vector(7 downto 0);
begin
  do_latch_v:=do_latch;
if(rd='0' and cs='0')then
data_out<=to_stdlogicvector(do_latch_v);
else
data_out<="ZZZZZZZZ";
end if;
end process;
process(clk,reset)
variable scir_v:integer range 0 to 63;
variable scir_s:std_logic_vector(5 downto 0);
begin
if(reset='0')then
  scir_v:=0;
elsif(clk'event and clk='1')then
  if((scir_v<=27)and(rxd='0'))then
    scir_v:=28;
  elsif((scir_v<=27)and (rxd='1'))then
   scir_v:=0;
  else
    scir_v:=scir_v+1;
  end if;
end if;
scir_s:=conv_std_logic_vector(scir_v,6);
scir<=to_stdulogicvector(scir_s);
end process;

process(clk,reset)
variable scit_v:integer range 0 to 63;
variable scit_s:std_logic_vector(5 downto 0);
begin
if(reset='0')then
  scit_v:=0;
elsif(clk'event and clk='1')then
  if(scit_v<=27)then
    if(tdempty_s='0' and wr='1')then
    scit_v:=28;
    else
     scit_v:=0;
    end if;
  else
    scit_v:=scit_v+1;
  end if;
end if;
scit_s:=conv_std_logic_vector(scit_v,6);
scit<=to_stdulogicvector(scit_s);
end process;

process(clk,reset)
begin
if(reset='0')then
  d_fb<="00000000";
elsif(clk'event and clk='0')then
  if((sh_r>="1000")and(sh_r<="1111")and(sl_r="01"))then
   d_fb(7)<=rxd;
   for i in 0 to 6 loop
   d_fb(i)<=d_fb(i+1);
   end loop;
end if;
end if;
end process;

process(sh_t,din_latch)
  begin
   case sh_t is
    when"0111"=>txd<='0';
    when"1000"=>txd<=din_latch(0);
    when"1001"=>txd<=din_latch(1);
    when"1010"=>txd<=din_latch(2);
    when"1011"=>txd<=din_latch(3);
    when"1100"=>txd<=din_latch(4);
    when"1101"=>txd<=din_latch(5);
    when"1110"=>txd<=din_latch(6);
    when"1111"=>txd<=din_latch(7);
    when others=>txd<='1';
  end case;
end process;
end rtl; 






%%%%%%%%%%%%%%%%%%%%%%%%%%
首先介绍串行通信发送器的工作原理。6位计数器用于判断发送的数据是否发送完毕及在发送完毕后装入新的数据,其VHDL语言程序如下: 
process(carry) begin if carry''event and carry=''1''then if counter40="100111"then load<=''1''; counter40<="000000"; else counter40<=counter40+1; load<=''0''; end if; end if; end process; 

由于本设计中选取一位数据4个时钟周期,因此当计数到“100111”时,表示10位数据发送完毕;此时将加载信号“load”置1,则向移位寄存器加载10位数据。此计数器的时钟信号由3位计数器的进位信号提供,3位计数器程序为如下: 

process(clk) begin if clk''event and clk=''1''then if counter4="0011"then counter4<="0000"; carry<=''1''; else counter4<=counter4+1; carry<=''0''; end if; end if; end process; 
当计数脉冲为3时,计数器清零并发出进位信号“carry”,“carry”既是6位计数器的时钟信号,又是移位寄存器的移位脉冲,移位寄存器实际上在发送器中是一个并串转换器,其程序为如下: 

process(load,carry) begin if load=''1''then reg10(9 downto 0)<=regin(9 downto 0); else if carry''event and carry=''1'' then din<=reg10(0); reg10(8 downto 0)<=reg10(9 downto 1); end if; end if; end process; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -