【嵌入式开发】FPGA/CPLD控制串口(VHDL版)

简介:

采用自顶向下设计:

top_rs232_port.vhd

library ieee; 
use ieee.std_logic_1164.all;

entity rs232_port is 
    port (    serialinput   : in  std_logic; 
              clock         : in  std_logic; 
              reset         : in  std_logic; 
              readinput     : in  std_logic; 
              sendoutput          : in  std_logic; 
              serial_in        : in  std_logic_vector(7 downto 0); 
              serialoutput  : out std_logic; 
              getinput            : out std_logic; 
              outputsent          : out std_logic; 
              serial_out    : out std_logic_vector(7 downto 0)); 
     end rs232_port;

architecture behavioral of rs232_port is 
signal fastclk    : std_logic; 
signal slowclk    : std_logic;

component rs232_in 
    port(data_out : out std_logic_vector(7 downto 0); 
           reset    : in std_logic; 
           clock    : in std_logic; 
           getdata  : in std_logic; 
           ready    : out std_logic; 
           serialinput: in std_logic); 
  end component;

component rs232_out 
    port(data_in : in std_logic_vector(7 downto 0); 
           reset   : in std_logic; 
           clock   : in std_logic; 
           load    : in std_logic; 
           ready   : out std_logic; 
           serialoutput : out std_logic); 
  end component;

component clkdiv 
   Generic (Divisor1: positive :=1311; -- clock for sending 
            Divisor2: positive :=82 ); -- clock for receiving 
      PORT(fast_clock : IN STD_LOGIC; 
           reset      : IN STD_LOGIC; 
           slow_clock1: out STD_LOGIC; 
           slow_clock2: out STD_LOGIC); 
END component;

begin 
serin:     rs232_in 
                port map(data_out      => serial_out, 
                            reset         => reset, 
                            clock         => fastclk, 
                            getdata    => readinput, 
                            ready         => getinput, 
                            serialinput=> serialinput);

serout:     rs232_out 
                port map(data_in        => serial_in, 
                            reset          => reset, 
                            clock          => slowclk, 
                            load           => sendoutput, 
                            ready          => outputsent, 
                            serialoutput=> serialoutput); 
clocks:        clkdiv 
                port map(fast_clock     => clock, 
                         reset             => reset, 
                         slow_clock1 => slowclk, 
                         slow_clock2 => fastclk);

end behavioral;

rs232_input.vhd

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 
use ieee.std_logic_unsigned.all;

entity rs232_in is 
    port(data_out: out std_logic_vector(7 downto 0); 
           reset   : in std_logic; 
           clock   : in std_logic; 
           getdata : in std_logic; 
           ready   : out std_logic; 
           serialinput : in std_logic); 
  end rs232_in;

architecture behavioural of rs232_in is 
signal   indata   : std_logic_vector(7 downto 0);    
constant countmax : natural := 153; 
begin

process (clock) 
variable count:natural range 0 to 170; 
variable startbit : integer range 0 to 2 ; 
    begin 
        if (clock'event and clock='1') then 
             if ( reset = '1' or getdata = '1')then 
               indata <= (others => '0'); 
               ready  <= '0'; 
               count  := 0; 
               data_out <= (others => '0'); 
          startbit := 0 ; 
           elsif (serialinput = '0' and startbit = 0) then 
                 startbit := 1;    
        elsif (serialinput = '1' and count  >= countmax) then 
           startbit := 0; 
           data_out <= indata; 
                 count:= 0; 
                 ready <= '1'; 
                 indata <= (others => '0'); 
           end if;      

          if (startbit = 1) then    
             count:= (count +1);    
                        case count is 
                           when 24 => 
                               indata(0) <= serialinput; 
                           when 40 => 
                               indata(1) <= serialinput; 
                           when 56 => 
                               indata(2) <= serialinput; 
                           when 72 => 
                               indata(3) <= serialinput; 
                           when 88 => 
                               indata(4) <= serialinput; 
                           when 104 => 
                               indata(5) <= serialinput; 
                           when 120 => 
                               indata(6) <= serialinput; 
                           when 136 => 
                               indata(7) <= serialinput; 
                           when others => 
                               count:= count; 
                         end case; 
            end if; 
end if; 
end process ; 
end behavioural;

rs232_output.vhd

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 
use ieee.std_logic_unsigned.all;

entity rs232_out is 
    port(data_in : in std_logic_vector(7 downto 0); 
           reset   : in std_logic; 
           clock   : in std_logic; 
           load    : in std_logic; 
           ready   : out std_logic; 
           serialoutput : out std_logic); 
end rs232_out;

architecture behavioural of rs232_out is 
signal frame : std_logic_vector(10 downto 0); 
signal internaldata : std_logic_vector(7 downto 0); 
signal ready_s : std_logic;    
begin 
  frame(0) <= '1'; 
    frame(1) <= '0'; 
    frame(9 downto 2) <= internaldata; 
    frame(10)<= '1'; 
    ready    <= ready_s; 
process (clock) 
variable count:natural range 0 to 10; 
begin 
    if (clock'event and clock ='1') then 
        if (reset = '1') then 
            internaldata <= (others => '0'); 
            ready_s <= '1'; 
            count   := 0; 
            serialoutput <= frame(0); 
        elsif load = '1' then 
            ready_s <= '0'; 
            internaldata <= data_in; 
            serialoutput <= frame(0); 
            count:= 0; 
        elsif ready_s = '1' then 
            serialoutput <= frame(0); 
        elsif count = 10 then 
            ready_s <= '1'; 
            serialoutput <= frame(count); 
            count:= 0; 
        else 
            count:= (count +1); 
            serialoutput <= frame(count); 
        end if;        
    end if; 
end process ; 
end behavioural;

clockkdiv.vhd

LIBRARY ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 
use ieee.std_logic_unsigned.all;

ENTITY clkdiv IS 
   Generic (Divisor1: positive :=1311; -- clock for sending 
            Divisor2: positive :=82 ); -- clock for receiving 
   PORT(fast_clock : IN  STD_LOGIC; 
        reset      : IN  STD_LOGIC; 
        slow_clock1: out STD_LOGIC; 
        slow_clock2: out STD_LOGIC); 
END clkdiv;

ARCHITECTURE behaviour OF clkdiv IS 
signal  slow_clock1_s : std_logic; 
signal  slow_clock2_s : std_logic; 
BEGIN 
slow_clock1 <= slow_clock1_s; 
slow_clock2 <= slow_clock2_s; 
process (fast_clock) 
   variable c1:natural range 0 to Divisor1; 
   variable c2:natural range 0 to Divisor2; 
BEGIN 
if( fast_clock'EVENT and fast_clock = '1') then 
   if (reset = '1') then 
           c1:= 0; 
      c2:= 0; 
      slow_clock1_s <='0' ;  
         slow_clock2_s <= '0';  
    else                                 
         c1 := (c1 + 1); 
      c2 := (c2 + 1); 
         IF (c1=Divisor1) THEN 
            slow_clock1_s <= not slow_clock1_s; 
            c1 := 0; 
         elsif (c2 = Divisor2) then 
            slow_clock2_s <= not slow_clock2_s; 
            c2:= 0; 
         END IF; 
     end if;   
end if; 
END PROCESS ; 
END behaviour;

 




本文转自gnuhpc博客园博客,原文链接:http://www.cnblogs.com/gnuhpc/archive/2012/12/21/2828339.html,如需转载请自行联系原作者

相关文章
|
7月前
|
数据格式 异构计算
|
算法 异构计算
基于FPGA的Lorenz混沌系统verilog开发,含testbench和matlab辅助测试程序
基于FPGA的Lorenz混沌系统verilog开发,含testbench和matlab辅助测试程序
|
算法 芯片 异构计算
通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置
通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置
|
5月前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的MSK调制解调系统verilog开发,包含testbench,同步模块,高斯信道模拟模块,误码率统计模块
升级版FPGA MSK调制解调系统集成AWGN信道模型,支持在Vivado 2019.2中设置不同SNR仿真误码率。示例SNR值从0到15,结果展示解调质量随SNR提升。MATLAB仿真验证了MSK性能,图片显示了仿真结果。 ### 理论概要 研究聚焦于软件无线电中的MSK调制解调,利用Verilog实现。MSK是一种相位连续、恒包络的二进制调制技术,优点包括频谱效率高。系统采用无核设计,关键模块包括调制器、解调器和误码检测。复位、输入数据、中频信号等关键信号通过Verilog描述,并通过Chipscope在线观察。
113 6
基于FPGA的MSK调制解调系统verilog开发,包含testbench,同步模块,高斯信道模拟模块,误码率统计模块
|
5月前
|
存储 算法 数据处理
LabVIEW FPGA开发NI sbRIO-9607高精度数字滤波器
LabVIEW FPGA开发NI sbRIO-9607高精度数字滤波器
55 5
|
7月前
|
前端开发 编译器 测试技术
LabVIEW FPGA利用响应式数字电子板快速开发空间应用程序
LabVIEW FPGA利用响应式数字电子板快速开发空间应用程序
64 1
|
7月前
|
API 异构计算
LabVIEW开发FPGA参考框架
LabVIEW开发FPGA参考框架
53 0
LabVIEW开发FPGA参考框架
|
7月前
|
传感器 数据采集 人工智能
LabVIEW FPGA开发实时滑动摩擦系统
LabVIEW FPGA开发实时滑动摩擦系统
50 0
|
算法 测试技术 计算机视觉
基于FPGA的图像中值滤波开发,包括tb测试文件以及matlab验证代码
基于FPGA的图像中值滤波开发,包括tb测试文件以及matlab验证代码
|
算法 异构计算
基于FPGA的图像sobel边缘提取算法开发,包括tb测试文件以及matlab验证代码
基于FPGA的图像sobel边缘提取算法开发,包括tb测试文件以及matlab验证代码