【嵌入式开发】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/

posted @ 2012-12-21 17:24  gnuhpc  阅读(1363)  评论(0编辑  收藏  举报