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

📄 mc8051_siu.vhd

📁 8051VHDL原代码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
-------------------------------------------------------------------------------
library IEEE; 
use IEEE.std_logic_1164.all; 
use IEEE.std_logic_arith.all; 
  
-----------------------------ENTITY DECLARATION--------------------------------

entity mc8051_siu is

  port (clk     : in std_logic;  		    --< system clock
        reset   : in std_logic;  		    --< system reset
        tf_i    : in std_logic;  		    --< timer1 overflow flag
        trans_i : in std_logic;  		    --< 1 activates transm.
        rxd_i   : in std_logic;  		    --< serial data input
        scon_i  : in std_logic_vector(5 downto 0);  --< from SFR register
  						    --< bits 7 to 3
        sbuf_i  : in std_logic_vector(7 downto 0);  --< data for transm.
        smod_i  : in std_logic;  		    --< low(0)/high baudrate

        sbuf_o  : out std_logic_vector(7 downto 0);  --< received data 
        scon_o  : out std_logic_vector(2 downto 0);  --< to SFR register 
  						     --< bits 0 to 2
        rxdwr_o : out std_logic;  	             --< rxd direction signal
        rxd_o   : out std_logic;  		     --< mode0 data output
        txd_o   : out std_logic);  		     --< serial data output
  
end mc8051_siu;
-------------------------------------------------------------------------------
architecture rtl of mc8051_siu is

  signal s_rxpre_count  : unsigned(5 downto 0);  -- Receive prescaler
  signal s_txpre_count  : unsigned(5 downto 0);  -- Transmit prescaler
  signal s_m0_shift_en  : std_logic;             -- masks out every sixteenth
                                                 -- rising edge of clk
  signal s_m2_rxshift_en  : std_logic;           -- mode 2 shift enable
  signal s_m13_rxshift_en : std_logic;           -- mode 1 and 3 shift enable
  signal s_m2_txshift_en  : std_logic;           -- mode 2 shift enable
  signal s_m13_txshift_en : std_logic;           -- mode 1 and 3 shift enable
  signal s_ff0          : std_logic;             -- flipflop for edge dedection
  signal s_ff1          : std_logic;             -- flipflop for edge dedection
  signal s_tf           : std_logic;             -- synchronised timer flag
  signal s_mode         : unsigned(1 downto 0);  -- mode
  signal s_sm2          : std_logic;             -- multi processor comm. bit
  signal s_detect       : std_logic;             -- indicates start of recept. 
  signal s_ren          : std_logic;             -- receive enable
  signal s_rxd_val      : std_logic;             -- received data bit
  signal s_txdm0        : std_logic;             -- shift clock for m0
  signal s_ri           : std_logic;             -- external receive interrupt 
  signal s_trans        : std_logic;             -- enable transmission 
  signal s_recv_done    : std_logic;             -- receive interrupt
  signal s_tran_done    : std_logic;             -- transmit interrupt
  signal s_rb8          : std_logic;             -- 8th data bit
  signal s_tb8          : std_logic;             -- 8th data bit
  signal s_recv_state   : unsigned(3 downto 0);  -- state reg. of receive unit
  signal s_tran_state   : unsigned(3 downto 0);  -- state reg. of transmit unit
  signal s_rxd_ff0      : std_logic;             -- sample flip-flop
  signal s_rxd_ff1      : std_logic;             -- sample flip-flop
  signal s_rxd_ff2      : std_logic;             -- sample flip-flop
  signal s_det_ff0      : std_logic;             -- rec. detect flip-flop
  signal s_det_ff1      : std_logic;             -- rec. detect flip-flop
  signal s_tran_sh      : unsigned(10 downto 0); -- transmission shift register
  signal s_recv_sh      : unsigned(7 downto 0);  -- reception shift register
  signal s_recv_buf     : unsigned(7 downto 0);  -- reception buffer register
  signal s_rxm13_ff0    : std_logic;             -- generates an enable singal
  signal s_rxm13_ff1    : std_logic;             -- generates an enable singal
  signal s_txm13_ff0    : std_logic;             -- generates an enable singal
  signal s_txm13_ff1    : std_logic;             -- generates an enable singal
  
begin                 -- architecture rtl
    
  s_mode(1) <= scon_i(4);               -- defines the 4 operating modes
  s_mode(0) <= scon_i(3); 
  s_ren  <= scon_i(1);                  -- receive enable
  s_sm2  <= scon_i(2);                  -- 1 time or half time baud rate
  s_tb8  <= scon_i(0);                  -- 9th data bit for transmission
  s_ri   <= scon_i(5);                  -- the receive interrupt bit of the
                                        -- control unit
  sbuf_o <= std_logic_vector(s_recv_buf);  -- the receive buffer output
  scon_o(0) <= s_recv_done;             -- set when reception is completed
  scon_o(1) <= s_tran_done;             -- set when transmission is completed
  scon_o(2) <= s_rb8;                   -- 9th data bit of reception  

-------------------------------------------------------------------------------
  -- The two flip flops are updated every rising clock edge of clk.
  -- If a rising edge
  -- on the port tf_i is dedected the signal s_tf is set to 1 for one period.
  --
  -- The transmission start signal s_trans is generated and held high till
  -- the statemachine has been launched with its first shift.
  --
  -- The shift clock for mode0 is generated. It toggles with the half
  -- s_m0_shift_en rate.
  
  s_tf <= '1' when (s_ff0 = '1' and s_ff1 = '0') else '0';      

  p_sample_tf: process (clk,
                        reset)
      
    begin

      if reset = '1' then
        s_ff0 <= '0';
        s_ff1 <= '0';
        s_trans <= '0';
      else
        if clk'event and clk = '1' then
          s_ff0 <= tf_i;
          s_ff1 <= s_ff0;
          
          if trans_i = '1' then
            s_trans <= '1';
          else
            case s_mode is
              when ("00") =>
                if s_m0_shift_en = '1' then
                  s_trans <= '0';
                end if;
              when ("01") => 
                if s_m13_txshift_en = '1' then
                  s_trans <= '0';
                end if;
              when ("10") => 
                if s_m2_txshift_en = '1' then
                  s_trans <= '0';
                end if;
              when others => 
                if s_m13_txshift_en = '1' then
                  s_trans <= '0';
                end if;
            end case;
          end if;
        end if;    
      end if;    

  end process p_sample_tf;
      

-------------------------------------------------------------------------------
  -- The register s_rxpre_count is driven with the system clock clk. So a
  -- good enable signal (which is stable when clk has its rising edge) can be
  -- derived to mask out every pulse of clk needed.
  -- s_m0_shift_en activates every sixteenth clock cycle
  -- s_m2_shift_en activates baud rates of 1/32 or 1/64 the clock frequenzy
  -- depending on signal smod_i
  -- s_m13_shift_en activates baud rates depending on timer/counter1 flag
      
  s_m0_shift_en <= '1' when s_txpre_count(3 downto 0) = conv_unsigned(15,5)
                   else '0';
      
  s_m2_rxshift_en <= '1' when (s_rxpre_count(4 downto 0) = conv_unsigned(31,5)
                               and smod_i = '1') or
                              (s_rxpre_count = conv_unsigned(63,6)
                               and smod_i = '0')
                   else '0';
  s_m13_rxshift_en <= '1' when s_rxm13_ff0 = '1' and s_rxm13_ff1 = '0'
                      else '0';

  s_m2_txshift_en <= '1' when (s_txpre_count(4 downto 0) = conv_unsigned(31,5)
                               and smod_i = '1') or
                              (s_txpre_count = conv_unsigned(63,6)
                               and smod_i = '0')
                   else '0';
  s_m13_txshift_en <= '1' when s_txm13_ff0 = '1' and s_txm13_ff1 = '0'
                      else '0';
      
  p_divide_clk: process (clk, reset)
    
    begin

      if reset = '1' then
        s_rxpre_count <= conv_unsigned(0,6);
        s_txpre_count <= conv_unsigned(0,6);
        s_rxm13_ff0 <= '0';
        s_rxm13_ff1 <= '0';
        s_txm13_ff0 <= '0';
        s_txm13_ff1 <= '0';
      else
        if clk'event and clk='1' then
            
          s_rxm13_ff1 <= s_rxm13_ff0;
          s_txm13_ff1 <= s_txm13_ff0;
          
          if smod_i = '1' then
            if s_rxpre_count(3 downto 0) = conv_unsigned(15,4) then
              s_rxm13_ff0 <= '1';
            else
              s_rxm13_ff0 <= '0';
            end if;
          else
            if s_rxpre_count(4 downto 0) = conv_unsigned(31,5) then
              s_rxm13_ff0 <= '1';
            else
              s_rxm13_ff0 <= '0';
            end if;              
          end if;
             
          if smod_i = '1' then
            if s_txpre_count(3 downto 0) = conv_unsigned(15,4) then
              s_txm13_ff0 <= '1';
            else
              s_txm13_ff0 <= '0';
            end if;
          else
            if s_txpre_count(4 downto 0) = conv_unsigned(31,5) then
              s_txm13_ff0 <= '1';
            else
              s_txm13_ff0 <= '0';
            end if;              
          end if;
            
          if trans_i = '1' then
            s_txpre_count <= conv_unsigned(0,6);
          else
            if s_mode=conv_unsigned(0,2) or s_mode=conv_unsigned(2,2) then 
              s_txpre_count <= s_txpre_count + conv_unsigned(1,1);
            else
              if s_tf = '1' then
                s_txpre_count <= s_txpre_count + conv_unsigned(1,1);  
              end if;
            end if;              
          end if;

          if s_detect = '1' then
            s_rxpre_count <= conv_unsigned(0,6);
          else
            if s_mode=conv_unsigned(0,2) or s_mode=conv_unsigned(2,2) then 
              s_rxpre_count <= s_rxpre_count + conv_unsigned(1,1);
            else
              if s_tf = '1' then
                s_rxpre_count <= s_rxpre_count + conv_unsigned(1,1);  
              end if;
            end if;              
          end if;
        end if;
      end if;    

  end process p_divide_clk;

-------------------------------------------------------------------------------
  -- This section samples the serial input for data detection, that is a
  -- 1-to-0 transition at rxd in state "0000".
  -- In all other states this unit reads the data bits depending on the baud
  -- rate. In mode0 this section is not active.

  s_detect <= '1' when s_det_ff0 = '0' and s_det_ff1 = '1' else '0'; 
  s_rxd_val <= '1' when (s_rxd_ff0 = '1' and s_rxd_ff1 = '1') or
                        (s_rxd_ff0 = '1' and s_rxd_ff2 = '1') or
                        (s_rxd_ff1 = '1' and s_rxd_ff2 = '1') else '0';
               
  p_sample_rx: process (clk,
                        reset)
    
  begin
    if reset = '1' then
      s_rxd_ff0 <= '0';
      s_rxd_ff1 <= '0';
      s_rxd_ff2 <= '0';
      s_det_ff0 <= '0';
      s_det_ff1 <= '0';
    else
      if clk'event and clk='1' then          
        if s_recv_state = conv_unsigned(0,4) then   -- state "0000" means
          if s_ren = '1' then                       -- to listen for a 1 to 0
            case s_mode is                          -- transition
              when ("01") | ("11") => 
                if smod_i = '1' then
                  if s_tf = '1' then
                    s_det_ff0 <= rxd_i;  
                    s_det_ff1 <= s_det_ff0;
                  end if;
                else
                  if s_rxpre_count(0) = '1' then
                    s_det_ff0 <= rxd_i;  
                    s_det_ff1 <= s_det_ff0;                    
                  end if;
                end if;
              when ("10") =>
                if smod_i = '1' then
                  if s_rxpre_count(0) = '1' then
                    s_det_ff0 <= rxd_i;  
                    s_det_ff1 <= s_det_ff0;
                  end if;
                else
                  if s_rxpre_count(1) = '1' then
                    s_det_ff0 <= rxd_i;  
                    s_det_ff1 <= s_det_ff0;                    
                  end if;
                end if;
              when others =>
                null;
            end case;

⌨️ 快捷键说明

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