OpenCores
URL https://opencores.org/ocsvn/onewire/onewire/trunk

Subversion Repositories onewire

[/] [onewire/] [trunk/] [HDL/] [ow_bit.vhd] - Rev 2

Compare with Previous | Blame | View Log

----------------------------------------------------------------------------------
--  <c>2018 william b hunter
--    This file is part of ow2rtd.
--
--    ow2rtd is free software: you can redistribute it and/or modify
--    it under the terms of the GNU Lessor General Public License as published by
--    the Free Software Foundation, either version 3 of the License, or
--    (at your option) any later version.
--
--    ow2rtd is distributed in the hope that it will be useful,
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--    GNU General Public License for more details.
--
--    You should have received a copy of the GNU Lessor General Public License
--    along with ow2rtd.  If not, see <https://www.gnu.org/licenses/>.
-----------------------------------------------------------------------------------  
--  Create Date: 5/15/2018
--  file: onewire_bit.vhd
--  description: handles single bit transactions on the one wire bus
--  it is used by higher level entities to initialize, search, read, and write the one
--    wire devices on the one wire bus.
--  Each operation consists of a start, that is always low, middle, which for reads
--    represents the time for the slave to respond, and the end, which allows for
--    the slave to finish its operation and provides spacing between bit patterns.
--  For reads and resets, the data is sampled at the end of the mid time
--
-----------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
library work;
 
-------------------------------------------------------------------------------------
-- Entity declaration
-------------------------------------------------------------------------------------
entity ow_bit is
  port (
    --globals
    clk              : in    std_logic;
    srst             : in    std_logic;
    clken            : in    std_logic;
    --interface to higher level
    rstb             : in    std_logic;
    wstb             : in    std_logic;
    istb             : in    std_logic;
    din              : in    std_logic;
    dout             : out   std_logic;
    busy             : out   std_logic;
	--one wire bus
    owout            : out std_logic;   --one wire input
    owin             : in  std_logic    --one wire output
  );
end ow_bit;
 
-------------------------------------------------------------------------------------
-- Architecture declaration
-------------------------------------------------------------------------------------
architecture rtl of ow_bit is
  type pulse_state_type is (S_IDLE, S_START, S_MID, S_END); --, S_DONE
  signal pulse_state : pulse_state_type := S_IDLE;
 
 
  constant r_start  : unsigned(11 downto 0) := to_unsigned(5,12);    --low time
  constant r_mid    : unsigned(11 downto 0) := to_unsigned(10,12);   --high z until sample time
  constant r_end    : unsigned(11 downto 0) := to_unsigned(65,12);   --recovery time
  constant w_start  : unsigned(11 downto 0) := to_unsigned(5,12);    --low time
  constant w_mid    : unsigned(11 downto 0) := to_unsigned(65,12);   --dout time
  constant w_end    : unsigned(11 downto 0) := to_unsigned(10,12);   --recovery time
  constant rw_cnt   : unsigned(11 downto 0) := to_unsigned(1,12);    --number of samples for read or write
  constant i_start  : unsigned(11 downto 0) := to_unsigned(500,12);  --reset low time
  constant i_mid    : unsigned(11 downto 0) := to_unsigned(100,12);  --high z till sample time
  constant i_end    : unsigned(11 downto 0) := to_unsigned(220,12);  --recovery time till end of rst response
  constant i_cnt   : unsigned(3 downto 0) := to_unsigned(1,4);   --number of samples (i_end each) to wait for init response
 
  signal start_time : unsigned(11 downto 0);   -- low pulse time
  signal mid_time   : unsigned(11 downto 0);   -- high pulse time
  signal end_time   : unsigned(11 downto 0);   -- time between samples, or the last sample and the end
  --signal rd_count   : unsigned(4 downto 0) := to_unsigned(30,5);    -- number of read smaples for this bit 
 
 
  signal owo   : std_logic := '0';  --one wire output bit
  --signal owo2   : std_logic := '0';  --one wire output bit combined with one wire power
  --signal owi   : std_logic := '0';  --one wire input bit
  --signal owt   : std_logic := '0';  --one wire tristate, implements open collector bus
  signal wstb_cap   : std_logic := '0';  --captures and holds write requests
  signal rstb_cap   : std_logic := '0';  --captures and holds read requests
  signal istb_cap   : std_logic := '0';  --captures and holds init requests (reset/presence sequence)
  signal din_cap   : std_logic := '0';  --captures and holds input data
  signal pulse_end  : std_logic;
  signal busy_int   : std_logic;
  signal timer      : unsigned(11 downto 0) := x"000";   --used to time one wire bus transactions
  --signal rdcntr     : unsigned(4 downto 0);    --used to count samples in the read mode
  --signal owopwr     : std_logic;               --internal state of dout combined with power input
  signal samp       : std_logic;               --AND'ed value of owi samples
 
  attribute mark_debug : string;
  attribute mark_debug of pulse_state : signal is "true";
  attribute mark_debug of timer : signal is "true";
  attribute mark_debug of samp : signal is "true";
  attribute mark_debug of din : signal is "true";
  attribute mark_debug of dout : signal is "true";
  attribute mark_debug of rstb_cap: signal is "true";
  attribute mark_debug of wstb_cap : signal is "true";
  attribute mark_debug of istb_cap : signal is "true";  
  attribute mark_debug of busy_int : signal is "true";  
  attribute mark_debug of pulse_end : signal is "true";  
 
 
begin
  -------------------------------------
  --        strobe captures         ---
  -------------------------------------
  -- p_capstb - captures the pulse strobes, and clears then when the pulse is complete
  -- this is necessary if the clken is used because the strobes happen on the system clk and
  -- the pulse is timed by the stb1us. We need to hold the strobes throughout the pulse because the active
  -- strobe is used to zelect the timing for the pulse.
  p_capstb : process (clk)
  begin
    if rising_edge(clk) then
      if srst = '1' then
        rstb_cap <= '0';
        wstb_cap <= '0';
        istb_cap <= '0';
	      din_cap  <= '0';
      elsif busy_int = '0' then
        if rstb = '1' then
          rstb_cap <= '1';
        elsif wstb = '1' then
          wstb_cap <= '1';
	        din_cap  <= din;
        elsif istb = '1' then
          istb_cap <= '1';
        end if;
      elsif pulse_state = S_END then
        rstb_cap <= '0';
        wstb_cap <= '0';
        istb_cap <= '0';
	    din_cap  <= '0';
      end if;
    end if;
  end process p_capstb;
 
  -------------------------------------
  --        control muxing          ---
   -------------------------------------
 --busy_int indicates that a pulse is pending (one of the strobe captures is high) or the pulse is active
  busy_int <= '0' when rstb_cap = '0' and wstb_cap = '0' and istb_cap = '0' 
                   and pulse_state = S_IDLE
                   else '1';
 
  start_time <= w_start when wstb_cap = '1' else i_start when istb_cap = '1' else r_start;
  mid_time <= w_mid when wstb_cap = '1' else i_mid when istb_cap = '1' else r_mid;
  end_time <= w_end when wstb_cap = '1' else i_end when istb_cap = '1' else r_end;
 
 
  -------------------------------------
  --        pulse generator         ---
  -------------------------------------
  --p_pulse - generates the pulse, and if needed captures the read bit or read presence pulse
  -- all pulses consist of a start time, a middle time, and an end time.
  -- for read, write, and init, the start time is always low, and starts the timing for the pulse
  -- for a read or init, the middle time is used for the slave to react. data is sampled at the end of the mid time
  -- for the write, the middle time is where the actual data, zero or one, is output.
  -- the end time is used to space between pulses.
  --                    |start| middle |end|
  --     Write one   ----_____-------------
  --     Write zero  ----______________----
  --     read        ----_____xxxxxxxxx----
  --     init        ----_____---------____
  p_pulse : process (clk)
  begin
    if rising_edge(clk) then
      if srst = '1' then
        pulse_state <= S_IDLE;
        timer <= x"000";
        --rdcntr <= "00000";
        owo <= '1';
        samp <= '1';
      elsif clken = '1' then
        case pulse_state is
        when S_IDLE =>
          samp <= '1';
          if busy_int = '1' then
            pulse_state <= S_START;
            timer <= start_time;
            owo <= '0';
          end if;
        when S_START =>
          if timer > 0 then
            timer <= timer -1;
          else
            if wstb_cap = '1' then
		      	  owo <= din_cap;
		      	else
		      	  owo <= '1';
		      	end if;
            timer <= mid_time;
            pulse_state <= S_MID;
          end if;
        when S_MID =>
          if timer > 0 then
            timer <= timer -1;
          else
            samp <= owin;
            timer <= end_time;
            --rdcntr <= rd_count;
            pulse_state <= S_END;
		        owo <= '1';
          end if;
        when S_END =>
          if timer > 0 then
            timer <= timer -1;
           else
            pulse_state <= S_IDLE;
          end if; 
        --when S_DONE =>
        --  pulse_state <= S_IDLE;
        end case;
      end if;
    end if;
  end process p_pulse;
 
  dout <= samp; --this is the value read back from a read pulse or a reset pulse
  busy <= busy_int or rstb or wstb or istb;
 
  --The output is driven high when pwr = 1, otherwise is only driven low when owo is low
  owout <= owo;
 
end rtl;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.