Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / apps / communication / ds18b20 / fpga /

one_wire.vhd

   1  -- onewire.vhd: 1-wire
   2  -- Copyright (C) 2009 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Zdenek Vasicek <vasicek AT 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 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.math_pack.all;
  49  
  50  entity onewire is
  51     generic (
  52        CLK_DIV : integer := 250 -- 50MHz CLK (5*50), 40MHz CLK (5*40), 20 MHZ CLK (5*20)
  53     );
  54     port (
  55        CLK      : in std_logic;
  56        RESET    : in std_logic;
  57  
  58  
  59        CMD      : in std_logic_vector(1 downto 0);
  60        CMD_WE   : in std_logic;
  61  
  62        DATA_IN  : in std_logic_vector(7 downto 0);
  63        DATA_OUT : out std_logic_vector(7 downto 0);
  64        PRESENCE : out std_logic;
  65  
  66        BUSY     : out std_logic;
  67        DQ       : inout std_logic
  68     );
  69  end onewire;
  70  
  71  
  72  architecture beh of onewire is
  73     signal dqclk : std_logic;
  74     signal clk_cntr : std_logic_vector(log2(CLK_DIV)-1 downto 0);
  75  
  76     signal cmd_reg : std_logic_vector(1 downto 0);
  77     signal din_shreg : std_logic_vector(7 downto 0);
  78     signal din_shen : std_logic;
  79     signal dout_shreg : std_logic_vector(7 downto 0);
  80     signal dout_shen : std_logic;
  81     signal presence_reg : std_logic;
  82     signal presence_we : std_logic;
  83  
  84     signal bit_cntr : std_logic_vector(2 downto 0);
  85     signal bitcntr_cmp : std_logic;
  86     signal bitcntr_zero : std_logic;
  87  
  88     type FSMstate is (SInit, SCLKWait, SReset1, SReset2, SReset3, SWrite1, SWrite2, SWrite3, SRead1, SRead2a,SRead2, SRead3);
  89     signal pstate : FSMstate; -- actual state
  90     signal nstate : FSMstate; -- next state
  91  
  92     signal cntr : std_logic_vector(6 downto 0);
  93     signal cntr_rst : std_logic;
  94     signal cntr_en : std_logic;
  95     signal cmp_100 : std_logic;
  96     signal cmp_14 : std_logic;
  97  
  98     signal dq_reg1 : std_logic;
  99     signal dq_reg2 : std_logic;
 100  begin
 101     -- CLOCK divider (200 kHz signal)
 102     -- ----------------------------------------------------------
 103     dqclk <= '1' when conv_integer(clk_cntr) = CLK_DIV else '0';
 104  
 105     freqdv: process (RESET, CLK)
 106     begin
 107        if (RESET = '1') then
 108           clk_cntr <= (others => '0');
 109        elsif (CLK'event) and (CLK = '1') then
 110           if (dqclk = '1') then
 111              clk_cntr <= (others => '0');
 112           else
 113              clk_cntr <= clk_cntr + 1;
 114           end if;
 115        end if;
 116     end process;
 117  
 118     -- Cycle counter
 119     -- ----------------------------------------------------------
 120     process (RESET, CLK)
 121     begin
 122        if (RESET = '1') then
 123           cntr <= (others => '0');
 124        elsif (CLK'event) and (CLK = '1') then
 125           if (cntr_rst = '1') then
 126              cntr <= (others => '0');
 127           elsif (cntr_en = '1') and (dqclk = '1') then
 128              cntr <= cntr + 1;
 129           end if;
 130        end if;
 131     end process;
 132     cmp_100 <= '1' when conv_integer(cntr) = 100 else '0';
 133     cmp_14  <= '1' when conv_integer(cntr) = 14  else '0';
 134  
 135     -- Data registers
 136     -- ----------------------------------------------------------
 137     process (RESET, CLK)
 138     begin
 139        if (CLK'event) and (CLK = '1') then
 140           if (DQ='0') then
 141              dq_reg1 <= '0';
 142           else
 143              dq_reg1 <= '1';
 144           end if;
 145           dq_reg2 <= dq_reg1;
 146        end if;
 147     end process;
 148  
 149     -- CMD register
 150     process (RESET, CLK)
 151     begin
 152        if (RESET = '1') then
 153           cmd_reg <= (others => '0');
 154        elsif (CLK'event) and (CLK = '1') then
 155           if (CMD_WE='1') then
 156              cmd_reg <= cmd;
 157           end if;
 158        end if;
 159     end process;
 160  
 161     -- DATA (out) shift register
 162     process (RESET, CLK)
 163     begin
 164        if (RESET = '1') then
 165           dout_shreg <= (others => '0');
 166        elsif (CLK'event) and (CLK = '1') then
 167           if (dout_shen = '1') then
 168              dout_shreg <= dq_reg2 & dout_shreg(7 downto 1);
 169           end if;
 170        end if;
 171     end process;
 172  
 173     -- DATA (in) shift register
 174     process (RESET, CLK)
 175     begin
 176        if (RESET = '1') then
 177           din_shreg <= (others => '0');
 178        elsif (CLK'event) and (CLK = '1') then
 179           if (CMD_WE='1') then
 180              din_shreg <= DATA_IN;
 181           elsif (din_shen = '1') then
 182              din_shreg <= '0' & din_shreg(7 downto 1);
 183           end if;
 184        end if;
 185     end process;
 186  
 187     -- bit counter
 188     bitcntr_cmp  <= '1' when conv_integer(bit_cntr) = 7 else '0';
 189     bitcntr_zero <= '1' when conv_integer(bit_cntr) = 0 else '0';
 190  
 191     process (RESET, CLK)
 192     begin
 193        if (RESET = '1') then
 194           bit_cntr <= (others => '0');
 195        elsif (CLK'event) and (CLK = '1') then
 196           if (din_shen = '1') or (dout_shen='1') then
 197              if (bitcntr_cmp = '1') then
 198                 bit_cntr <= (others => '0');
 199              else
 200                 bit_cntr <= bit_cntr + 1;
 201              end if;
 202           end if;
 203        end if;
 204     end process;
 205  
 206     process (RESET, CLK)
 207     begin
 208        if (RESET = '1') then
 209           presence_reg <= '0';
 210        elsif (CLK'event) and (CLK = '1') then
 211           if (presence_we = '1') then
 212              presence_reg <= not dq_reg2;
 213           end if;
 214        end if;
 215     end process;
 216  
 217     PRESENCE <= presence_reg;
 218  
 219     DATA_OUT <= dout_shreg;
 220  
 221     -- FSM
 222     -- ----------------------------------------------------------
 223     --Present State registr
 224     pstatereg: process(RESET, CLK)
 225     begin
 226        if (RESET='1') then
 227           pstate <= SInit;
 228        elsif (CLK'event) and (CLK='1') then
 229           pstate <= nstate;
 230        end if;
 231     end process;
 232  
 233     --Next State logic
 234     nstate_logic: process(pstate, CMD_WE, cmd_reg, dqclk, cmp_100, cmp_14, bitcntr_zero, din_shreg)
 235     begin
 236        cntr_rst <= '0';
 237        cntr_en <= '0';
 238        presence_we <= '0';
 239        din_shen <= '0';
 240        dout_shen <= '0';
 241        BUSY <= '1';
 242        DQ <= 'Z';
 243  
 244        nstate <= SInit;
 245        case pstate is
 246           when SInit =>
 247              BUSY <= '0';
 248  
 249              nstate <= SInit;
 250              if (CMD_WE='1') then
 251                 nstate <= SCLKWait;
 252              end if;
 253  
 254           when SCLKWait =>
 255              cntr_rst <= '1';
 256  
 257              nstate <= SCLKWait;
 258              if (dqclk = '1') then
 259                 if (cmd_reg = "00") then
 260                    nstate <= SReset1;
 261                 elsif (cmd_reg = "01") then
 262                    nstate <= SWrite1;
 263                 elsif (cmd_reg = "10") then
 264                    nstate <= SRead1;
 265                 else
 266                    nstate <= SInit;
 267                 end if;
 268              end if;
 269           ----------------- Reset ------------------
 270           when SReset1 =>
 271              DQ <= '0';
 272              cntr_en <= '1';
 273  
 274              nstate <= SReset1;
 275              if (cmp_100 = '1') then
 276                 cntr_rst <= '1';
 277                 nstate <= SReset2;
 278              end if;
 279  
 280           when SReset2 =>
 281              cntr_en <= '1';
 282  
 283              nstate <= SReset2;
 284              if (cmp_14 = '1') then
 285                 presence_we <= '1';
 286                 nstate <= SReset3;
 287              end if;
 288  
 289           when SReset3 =>
 290              cntr_en <= '1';
 291  
 292              nstate <= SReset3;
 293              if (cmp_100 = '1') then
 294                 nstate <= SInit;
 295              end if;
 296  
 297           ----------------- Write ------------------
 298           when SWrite1 =>
 299              cntr_en <= '1';
 300              DQ <= '0';
 301  
 302              nstate <= SWrite1;
 303              if (dqclk = '1') then
 304                 nstate <= SWrite2;
 305              end if;
 306  
 307           when SWrite2 =>
 308              cntr_en <= '1';
 309              DQ <= din_shreg(0); --Data, ktera se maji zapsat
 310  
 311              nstate <= SWrite2;
 312              if (cmp_14 = '1') then
 313                 nstate <= SWrite3;
 314                 din_shen <= '1';
 315              end if;
 316  
 317           when SWrite3 =>
 318              cntr_rst <= '1';
 319  
 320              nstate <= SWrite3;
 321              if (dqclk = '1') then
 322                 if (bitcntr_zero = '1') then
 323                    nstate <= SInit;
 324                 else
 325                    nstate <= SWrite1;
 326                 end if;
 327              end if;
 328  
 329           ----------------- Read ------------------
 330           when SRead1 =>
 331              cntr_en <= '1';
 332              DQ <= '0';
 333  
 334              nstate <= SRead1;
 335              if (dqclk = '1') then
 336                 nstate <= SRead2;
 337              end if;
 338  
 339           when SRead2 =>
 340              cntr_en <= '1';
 341  
 342              nstate <= SRead2;
 343              if (dqclk = '1') then
 344                 nstate <= SRead2a;
 345              end if;
 346  
 347           when SRead2a =>
 348              --vzorkovani DQ
 349              dout_shen <= '1';
 350              cntr_en <= '1';
 351              nstate <= SRead3;
 352  
 353           when SRead3 =>
 354              cntr_en <= '1';
 355  
 356              nstate <= SRead3;
 357              if (cmp_14 = '1') then
 358                 cntr_rst <= '1';
 359                 if (bitcntr_zero = '1') then
 360                    nstate <= SInit;
 361                 else
 362                    nstate <= SRead1;
 363                 end if;
 364              end if;
 365  
 366           when others => null;
 367        end case;
 368     end process;
 369  
 370  end beh;
 371  
 372  
Zobrazeno: 154127x Naposledy: 18.11.2017 16:39:22