Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / fpga / ctrls / serial /

serial_tx.vhd

   1  -- serial_tx.vhd : Transmitter
   2  -- Copyright (C) 2007 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Zdenek Vasicek (xvasic11 AT stud.fit.vutbr.cz)
   5  --
   6  -- LICENSE TERMS
   7  --
   8  -- Redistribution and use in source and binary forms, with or without
   9  -- modification, are permitted provided that the following conditions
  10  -- are met:
  11  -- 1. Redistributions of source code must retain the above copyright
  12  --    notice, this list of conditions and the following disclaimer.
  13  -- 2. Redistributions in binary form must reproduce the above copyright
  14  --    notice, this list of conditions and the following disclaimer in
  15  --    the documentation and/or other materials provided with the
  16  --    distribution.
  17  -- 3. All advertising materials mentioning features or use of this software
  18  --    or firmware must display the following acknowledgement:
  19  --
  20  --      This product includes software developed by the University of
  21  --      Technology, Faculty of Information Technology, Brno and its
  22  --      contributors.
  23  --
  24  -- 4. Neither the name of the Company nor the names of its contributors
  25  --    may be used to endorse or promote products derived from this
  26  --    software without specific prior written permission.
  27  --
  28  -- This software or firmware is provided ``as is'', and any express or implied
  29  -- warranties, including, but not limited to, the implied warranties of
  30  -- merchantability and fitness for a particular purpose are disclaimed.
  31  -- In no event shall the company or contributors be liable for any
  32  -- direct, indirect, incidental, special, exemplary, or consequential
  33  -- damages (including, but not limited to, procurement of substitute
  34  -- goods or services; loss of use, data, or profits; or business
  35  -- interruption) however caused and on any theory of liability, whether
  36  -- in contract, strict liability, or tort (including negligence or
  37  -- otherwise) arising in any way out of the use of this software, even
  38  -- if advised of the possibility of such damage.
  39  --
  40  -- $Id$
  41  --
  42  --
  43  
  44  library IEEE;
  45  use IEEE.STD_LOGIC_1164.ALL;
  46  use IEEE.STD_LOGIC_ARITH.ALL;
  47  use IEEE.STD_LOGIC_UNSIGNED.ALL;
  48  use work.serial_cfg.all;
  49  
  50  entity serial_transmitter is
  51     generic (
  52        SPEED     : serial_speed   := s460800Bd;
  53        DATAWIDTH : serial_databit := 8;
  54        STOPBITS  : serial_stopbit := 1;
  55        PARITY    : serial_parity  := sParityEven
  56     );
  57     port (
  58        -- Common interface
  59        CLK      : in std_logic;
  60        RESET    : in std_logic;
  61  
  62        DATA_IN  : in std_logic_vector(DATAWIDTH-1 downto 0);
  63        WRITE_EN : in std_logic;
  64  
  65        BUSY     : out std_logic;
  66  
  67        -- Serial interface
  68        TXD      : out std_logic
  69     );
  70  end serial_transmitter;
  71  
  72  
  73  architecture behavioral of serial_transmitter is
  74  
  75     type FSMstate is (SIdle, SWaitTx, SStartbit, SDataBits, SParityBit, SStopBit1, SStopBit2, SStopBit3);
  76     signal pstate : FSMstate; -- actual state
  77     signal nstate : FSMstate; -- next state
  78  
  79     signal tx_en      : std_logic;
  80     signal data_shreg : std_logic_vector(DATAWIDTH-1 downto 0);
  81     signal data_shen  : std_logic;
  82     signal bitcnt_reg : std_logic_vector(3 downto 0);
  83     signal bitcnt_en  : std_logic;
  84     signal bitcnt_rst : std_logic;
  85     signal bit_cmp    : std_logic;
  86     signal outmx_sel  : std_logic_vector(1 downto 0);
  87     signal parity_reg : std_logic;
  88     signal txbusy_reg : std_logic;
  89     signal txbusy_rst : std_logic;
  90  
  91     component serial_gen
  92        generic (
  93           SPEED     : serial_speed;
  94           FREQMULT  : positive
  95        );
  96        port(
  97           CLK    : in  std_logic;
  98           RESET  : in  std_logic;
  99           EN     : in  std_logic;
 100  
 101           OUTPUT : out std_logic
 102        );
 103     end component;
 104  
 105  begin
 106     -- ===========================================================================================================
 107     -- Transmitter
 108     -- ===========================================================================================================
 109     TXD <= '1' when outmx_sel="00" else --idle, stop bit
 110            '0' when outmx_sel="01" else --start bit
 111            data_shreg(0) when outmx_sel="10" else --data bit
 112            parity_reg; --parity bit
 113  
 114     BUSY <= txbusy_reg;
 115  
 116     --Baudrate generator
 117     txclk_gen: serial_gen
 118        generic map (
 119           SPEED => SPEED,
 120           FREQMULT => 1
 121        )
 122        port map (
 123           CLK     => CLK,
 124           RESET   => RESET,
 125           EN      => '1',
 126           OUTPUT  => tx_en
 127        );
 128  
 129     -- Busy register
 130     process (RESET, CLK)
 131     begin
 132        if (RESET = '1') then
 133           txbusy_reg <= '0';
 134        elsif (CLK'event) and (CLK = '1') then
 135           if (txbusy_rst='1') then
 136              txbusy_reg <= '0';
 137           elsif (WRITE_EN='1') and (txbusy_reg='0') then
 138              txbusy_reg <= '1';
 139           end if;
 140        end if;
 141     end process;
 142  
 143     -- Data shift register
 144     process (RESET, CLK)
 145     begin
 146        if (CLK'event) and (CLK = '1') then
 147           if (WRITE_EN='1') and (txbusy_reg='0') then -- parallel load
 148              data_shreg <= DATA_IN;
 149  
 150              if (PARITY = sParityEven) then
 151                 parity_reg <= '0'; --even parity (suda parita)
 152              else
 153                 parity_reg <= '1'; --odd parity (licha parita)
 154              end if;
 155  
 156           elsif (data_shen='1') and (tx_en='1') then -- shift enable
 157              data_shreg <= '0' & data_shreg(DATAWIDTH-1 downto 1);
 158              parity_reg <= parity_reg xor data_shreg(0);
 159           end if;
 160        end if;
 161     end process;
 162  
 163     --Bit counter
 164     process (RESET, CLK)
 165     begin
 166        if (CLK'event) and (CLK = '1') then
 167           if (bitcnt_rst='1') then
 168              bitcnt_reg <= (others => '0');
 169           elsif (bitcnt_en='1') and (tx_en='1') then
 170              bitcnt_reg <= bitcnt_reg + 1;
 171           end if;
 172        end if;
 173     end process;
 174  
 175     --bit comparator
 176     bit_cmp <= '1' when (conv_integer(bitcnt_reg) = DATAWIDTH-1) else '0';
 177  
 178     --Present State registr
 179     pstatereg: process(RESET, CLK)
 180     begin
 181        if (RESET='1') then
 182           pstate <= SIdle;
 183        elsif (CLK'event) and (CLK='1') then
 184           pstate <= nstate;
 185        end if;
 186     end process;
 187  
 188     --Next State logic, Output logic
 189     nstate_logic: process(pstate, txbusy_reg, tx_en, bit_cmp)
 190     begin
 191        data_shen <= '0';
 192        outmx_sel <= "00";
 193        bitcnt_en <= '0';
 194        bitcnt_rst <= '0';
 195        txbusy_rst <= '0';
 196  
 197        nstate <= SIdle;
 198        case pstate is
 199           when SIdle =>
 200              if (txbusy_reg='1') then
 201                 nstate <= SWaitTx;
 202              end if;
 203  
 204           --Synchronization with baudrate generator
 205           when SWaitTx =>
 206              nstate <= SWaitTx;
 207  
 208              if (tx_en='1') then
 209                 nstate <= SStartBit;
 210  
 211                 bitcnt_rst <= '1';
 212              end if;
 213  
 214           --Start bit
 215           when SStartBit =>
 216              nstate <= SStartbit;
 217  
 218              outmx_sel <= "01";
 219              if (tx_en='1') then
 220                 nstate <= SDataBits;
 221              end if;
 222  
 223           -- Data bits
 224           when SDataBits =>
 225              nstate <= SDataBits;
 226  
 227              data_shen <= '1';
 228              bitcnt_en <= '1';
 229              outmx_sel <= "10";
 230              if (tx_en='1') and (bit_cmp='1') then
 231                 if (PARITY = sParityNone) then
 232                    if (STOPBITS=2) then -- two stop bits
 233                       nstate <= SStopBit1;
 234                    else -- one stop bit
 235                       nstate <= SStopBit2;
 236                    end if;
 237                 else
 238                    nstate <= SParityBit;
 239                 end if;
 240              end if;
 241  
 242           -- Parity bit
 243           when SParityBit =>
 244              nstate <= SParityBit;
 245  
 246              outmx_sel <= "11";
 247              if (tx_en='1') then
 248                 if (STOPBITS=2) then -- two stop bits
 249                    nstate <= SStopBit1;
 250                 else -- one stop bit
 251                    nstate <= SStopBit2;
 252                 end if;
 253              end if;
 254  
 255           -- Stop bit
 256           when SStopBit1 =>
 257              nstate <= SStopBit1;
 258  
 259              outmx_sel <= "00";
 260              if (tx_en='1') then
 261                 nstate <= SStopBit2;
 262              end if;
 263  
 264           -- Stop bit - busy reset
 265           when SStopBit2 =>
 266              nstate <= SStopBit3;
 267  
 268              outmx_sel <= "00";
 269              txbusy_rst <= '1';
 270  
 271           -- Stop bit
 272           when SStopBit3 =>
 273              nstate <= SStopBit3;
 274  
 275              outmx_sel <= "00";
 276              if (tx_en='1') then
 277                 if (txbusy_reg='1') then
 278                    nstate <= SStartBit;
 279  
 280                    bitcnt_rst <= '1';
 281                 else
 282                    nstate <= SIdle;
 283                 end if;
 284              end if;
 285  
 286           when others => null;
 287        end case;
 288     end process;
 289  
 290  end behavioral;
 291  
 292  
Zobrazeno: 679457x Naposledy: 25.6.2022 21:17:49