Čeština / English
Login

SVN Repository / Prohlížení

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

serial_rx.vhd

   1  -- serial_rx.vhd : Receiver
   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_receiver 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        CLK      : in std_logic;
  59        RESET    : in std_logic;
  60  
  61        DATA_OUT : out std_logic_vector(DATAWIDTH-1 downto 0);
  62        DATA_VLD : out std_logic;
  63  
  64        BUSY     : out std_logic;
  65        ERR      : out std_logic;
  66        ERR_RST  : in  std_logic;
  67  
  68        -- Serial interface
  69        RXD      : in  std_logic
  70     );
  71  end serial_receiver;
  72  
  73  
  74  architecture behavioral of serial_receiver is
  75  
  76     type FSMstate is (SIdle, SWaitStartBit, SDataBits, SCheckParity);
  77     signal pstate : FSMstate; -- actual state
  78     signal nstate : FSMstate; -- next state
  79  
  80     signal rx_en      : std_logic;
  81     signal rxd_reg    : std_logic_vector(2 downto 0);
  82     signal startbit   : std_logic;
  83  
  84     signal smplcnt_reg : std_logic_vector(3 downto 0) := (others => '0');
  85     signal smplcnt_en  : std_logic;
  86     signal smplcnt_cmp : std_logic;
  87     signal sample_en   : std_logic;
  88     signal sbit_reg    : std_logic_vector(4 downto 0) := (others => '1');
  89     signal sbit_majority : std_logic;
  90     signal parity_reg  : std_logic;
  91     signal parity_rst  : std_logic;
  92  
  93     signal data_shreg : std_logic_vector(DATAWIDTH downto 0) := (others => '0');
  94     signal bitcnt_reg : std_logic_vector(3 downto 0);
  95     signal bitcnt_rst : std_logic;
  96     signal bitcnt_cmp : std_logic;
  97  
  98     signal err_reg : std_logic;
  99     signal err_en  : std_logic;
 100  
 101     component serial_gen
 102        generic (
 103           SPEED     : serial_speed;
 104           FREQMULT  : positive
 105        );
 106        port(
 107           CLK    : in  std_logic;
 108           RESET  : in  std_logic;
 109           EN     : in  std_logic;
 110  
 111           OUTPUT : out std_logic
 112        );
 113     end component;
 114  
 115     component majority_five
 116        port (
 117           D : in  std_logic_vector(4 downto 0);
 118           Q : out std_logic
 119        );
 120     end component;
 121  
 122  begin
 123     -- ===========================================================================================================
 124     -- Receiver
 125     -- ===========================================================================================================
 126     DATA_OUT <= data_shreg(DATAWIDTH-1 downto 0);
 127  
 128     --Baudrate generator (8x faster than tx)
 129     rxclk_gen: serial_gen
 130        generic map (
 131           SPEED => SPEED,
 132           FREQMULT => 8
 133        )
 134        port map (
 135           CLK     => CLK,
 136           RESET   => RESET,
 137           EN      => '1',
 138           OUTPUT  => rx_en
 139        );
 140  
 141     -- rxd sample register
 142     process (RESET, CLK)
 143     begin
 144        if (RESET = '1') then
 145           rxd_reg <= (others => '1');
 146        elsif (CLK'event) and (CLK = '1') then
 147           rxd_reg <= rxd_reg(1 downto 0) & RXD;
 148        end if;
 149     end process;
 150  
 151     -- start bit detector
 152     startbit <= rxd_reg(2) and (not rxd_reg(1)) and (not rxd_reg(0));
 153  
 154     -- Bit Sample counter
 155     process (RESET, CLK)
 156     begin
 157        if (RESET = '1') then
 158           smplcnt_reg <= (others => '0');
 159        elsif (CLK'event) and (CLK = '1') then
 160           if (smplcnt_en='1') and (rx_en='1') then
 161              if (smplcnt_cmp='1') then
 162                 smplcnt_reg <= (others => '0');
 163              else
 164                 smplcnt_reg <= smplcnt_reg + 1;
 165              end if;
 166           end if;
 167        end if;
 168     end process;
 169     -- last sample
 170     smplcnt_cmp <= '1' when (conv_integer(smplcnt_reg) = 7) else '0';
 171     -- sample enabled
 172     sample_en <= '0' when (conv_integer(smplcnt_reg) = 0) or (conv_integer(smplcnt_reg) = 1) or
 173                           (conv_integer(smplcnt_reg) = 7) else '1';
 174  
 175     -- sample shift register (5 samples)
 176     process (CLK)
 177     begin
 178        if (CLK'event) and (CLK = '1') then
 179           if (sample_en='1') and (rx_en='1') then
 180              sbit_reg <= sbit_reg(3 downto 0) & rxd_reg(2);
 181           end if;
 182        end if;
 183     end process;
 184  
 185     -- majority of five inputs
 186     sbitmajority: majority_five
 187        port map (
 188           D => sbit_reg,
 189           Q => sbit_majority
 190        );
 191  
 192     -- received data shift register
 193     process (CLK)
 194     begin
 195        if (CLK'event) and (CLK = '1') then
 196           if (smplcnt_cmp='1') and (rx_en='1') then
 197              data_shreg <= sbit_majority & data_shreg(DATAWIDTH downto 1);
 198           end if;
 199        end if;
 200     end process;
 201  
 202     -- Parity register
 203     process (CLK)
 204     begin
 205        if (CLK'event) and (CLK = '1') then
 206           if (parity_rst='1') then
 207              parity_reg <= '0';
 208           elsif (smplcnt_cmp='1') and (rx_en='1') then
 209              parity_reg <= parity_reg xor sbit_majority;
 210           end if;
 211        end if;
 212     end process;
 213  
 214     --Bit counter
 215     process (CLK)
 216     begin
 217        if (CLK'event) and (CLK = '1') then
 218           if (bitcnt_rst='1') then
 219              bitcnt_reg <= (others => '0');
 220           elsif (smplcnt_cmp='1') and (rx_en='1') then
 221              bitcnt_reg <= bitcnt_reg + 1;
 222           end if;
 223        end if;
 224     end process;
 225  
 226     --all bits received comparator
 227     bitcnt_cmp <= '1' when ((PARITY = sParityNone) and (conv_integer(bitcnt_reg) = DATAWIDTH-1)) or
 228                   ((PARITY /= sParityNone) and (conv_integer(bitcnt_reg) = DATAWIDTH)) else '0';
 229  
 230     --Error register
 231     error_reg: process (RESET, CLK)
 232     begin
 233        if (RESET = '1') then
 234           err_reg <= '0';
 235        elsif (CLK'event) and (CLK = '1') then
 236           if (err_en='1') then
 237              err_reg <= '1';
 238           elsif (ERR_RST='1') then
 239              err_reg <= '0';
 240           end if;
 241        end if;
 242     end process;
 243  
 244     ERR <= err_reg;
 245  
 246     --Present State registr
 247     pstatereg: process(RESET, CLK)
 248     begin
 249        if (RESET='1') then
 250           pstate <= SIdle;
 251        elsif (CLK'event) and (CLK='1') then
 252           pstate <= nstate;
 253        end if;
 254     end process;
 255  
 256     --Next State logic, Output logic
 257     nstate_logic: process(pstate, startbit, smplcnt_cmp, rx_en, sbit_majority, bitcnt_cmp, parity_reg)
 258     begin
 259        nstate <= SIdle;
 260        smplcnt_en <= '0';
 261        bitcnt_rst <= '0';
 262        DATA_VLD <= '0';
 263        BUSY <= '1';
 264        parity_rst <= '0';
 265        err_en <= '0';
 266  
 267        case pstate is
 268           when SIdle =>
 269              BUSY <= '0';
 270              if (startbit='1') then
 271                 nstate <= SWaitStartBit;
 272              end if;
 273  
 274           -- Sample start bit
 275           when SWaitStartBit =>
 276              nstate <= SWaitStartBit;
 277  
 278              smplcnt_en <= '1';
 279              if (smplcnt_cmp='1') and (rx_en='1') then --first bit sampled
 280                 if (sbit_majority='0') then
 281                    nstate <= SDataBits;
 282                    bitcnt_rst <= '1';
 283                    parity_rst <= '1';
 284                 else
 285                    nstate <= SIdle;
 286                 end if;
 287              end if;
 288  
 289           -- Receive databits
 290           when SDataBits =>
 291              nstate <= SDataBits;
 292              smplcnt_en <= '1';
 293  
 294              if (smplcnt_cmp='1') and (rx_en='1') and (bitcnt_cmp='1') then
 295                 if (PARITY = sParityNone) then
 296                    nstate <= SIdle;
 297                    -- Received valid bits
 298                    DATA_VLD <= '1';
 299                 else
 300                    nstate <= SCheckParity;
 301                 end if;
 302              end if;
 303  
 304           -- Parity check
 305           when SCheckParity =>
 306              nstate <= SCheckParity;
 307  
 308              smplcnt_en <= '1';
 309              if ((PARITY = sParityEven) and (parity_reg='0')) or ((PARITY = sParityOdd) and (parity_reg='1')) then
 310                 nstate <= SIdle;
 311                 -- Received valid bits
 312                 DATA_VLD <= '1';
 313              else
 314                 err_en <= '1';
 315                 nstate <= SIdle;
 316              end if;
 317  
 318           when others => null;
 319        end case;
 320     end process;
 321  
 322  end behavioral;
 323  
 324  
Zobrazeno: 679738x Naposledy: 28.6.2022 19:50:12