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


    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

    采用自顶向下设计:

    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/


                   作者:gnuhpc
                   出处:http://www.cnblogs.com/gnuhpc/
                   除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


    分享到:

  • 相关阅读:
    CDQ
    MySQL中的类Decode用法
    HTMLTestRunner生成空白resault.html
    参数化时按行读取txt文件,如何去掉换行符" "
    打开本地html的一些设置
    python中文乱码例子
    Python异常处理实例
    Python根据上下限生成不重复随机数1
    Linux自定义命令
    Python IDLE 清屏工具
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2828339.html
Copyright © 2020-2023  润新知