URL
https://opencores.org/ocsvn/dallas_one-wire/dallas_one-wire/trunk
Subversion Repositories dallas_one-wire
[/] [dallas_one-wire/] [trunk/] [one_wire.vhd] - Rev 4
Compare with Previous | Blame | View Log
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_unsigned.all; entity one_wire is port ( clk, reset, read, write : IN std_logic; DQ : INOUT std_logic; rddata : OUT std_logic_vector(7 downto 0); wrdata : IN std_logic_vector(7 downto 0); ready : INOUT std_logic ); end entity one_wire; architecture structural of one_wire is signal iCount : integer range 0 to 500; signal iCntRst : bit; signal iD : std_logic; begin --This counter is used in the state machine to count micro seconds --it is assumed that the clock edges are coming in at 1uS intervals counter: process begin wait until (clk'event and clk = '0'); if(iCntRst = '1') then iCount <= 0; else iCount <= iCount + 1; end if; end process counter; init_statemachine : block type states is (init1, init2, init3, rdy, begin_read, begin_write, rd_bit, finish_read, wr_bit); signal state : states; begin nxt_state_decoder: process(state, clk) variable next_state : states; variable iBits : integer range 0 to 8; begin if clk 'event and clk = '1' then case (state) is when INIT1 => iCntRst <= '0'; iD <= '0'; ready <= '0'; if (iCount = 500) then next_state := INIT2; iCntRst <= '1'; --stop the timer else next_state := INIT1; end if; when INIT2 => iCntRst <= '0'; --start the timer iD <= '1'; ready <= '0'; if (iCount = 15) then next_state := INIT3; iCntRst <= '1'; --stop the timer else next_state := INIT2; end if; when INIT3 => iCntRst <= '0'; --start the timer (not needed) ready <= '0'; if (DQ = '0') then next_state := RDY; iCntRst <= '1'; --stop the timer (not needed) else next_state := INIT3; end if; when RDY => iCntRst <= '0'; --start the timer iBits := 0; iD <= '1'; if(iCount >= 240 and ready = '0') then ready <= '1'; end if; if(Read = '1' and iCount >= 240) then ready <= '0'; iCntRst <= '1'; --stop timer next_state := BEGIN_READ; elsif(Write = '1' and iCount >= 240) then ready <= '0'; iCntRst <= '1'; --stop timer next_state := BEGIN_WRITE; else next_state := RDY; end if; when BEGIN_READ => iCntRst <= '0'; --start timer iD <= '0'; if (iCount = 2) then --this number used to be a 5 iCntRst <= '1'; --stop timer next_state := RD_BIT; end if; when RD_BIT => iD <= '1'; iCntRst <= '0'; --start timer case ibits is when 0 => rddata(0) <= DQ; when 1 => rddata(1) <= DQ; when 2 => rddata(2) <= DQ; when 3 => rddata(3) <= DQ; when 4 => rddata(4) <= DQ; when 5 => rddata(5) <= DQ; when 6 => rddata(6) <= DQ; when 7 => rddata(7) <= DQ; when others => end case; if(iCount >= 6) then next_state := FINISH_READ; end if; when FINISH_READ => if(iBits <= 6 and iCount >= 55) then --this second number used to be 55 iD <= '1'; iBits := iBits + 1; iCntRst <= '1'; --stop timer next_state := BEGIN_READ; elsif(iBits = 7) then iCntRst <= '1'; -- stop timer next_state := RDY; end if; when BEGIN_WRITE => iCntRst <= '0'; if(iBits <= 7) then iD <= '0'; --start timer end if; if (iCount = 1) then iCntRst <= '1'; --stop timer next_state := WR_BIT; end if; when WR_BIT => iCntRst <= '0'; --The below code is what is being accomplished by the huge if elseif structure --if(data(iBits) = "001") then -- iD := '1'; --end if; if(iBits = 0 and wrdata(0) = '1') then iD <= '1'; elsif(iBIts = 0 and wrdata(0) = '0') then iD <= '0'; elsif(iBits = 1 and wrdata(1) = '1') then iD <= '1'; elsif(iBIts = 1 and wrdata(1) = '0') then iD <= '0'; elsif(iBits = 2 and wrdata(2) = '1') then iD <= '1'; elsif(iBIts = 2 and wrdata(2) = '0') then iD <= '0'; elsif(iBits = 3 and wrdata(3) = '1') then iD <= '1'; elsif(iBIts = 3 and wrdata(3) = '0') then iD <= '0'; elsif(iBits = 4 and wrdata(4) = '1') then iD <= '1'; elsif(iBIts = 4 and wrdata(4) = '0') then iD <= '0'; elsif(iBits = 5 and wrdata(5) = '1') then iD <= '1'; elsif(iBIts = 5 and wrdata(5) = '0') then iD <= '0'; elsif(iBits = 6 and wrdata(6) = '1') then iD <= '1'; elsif(iBIts = 6 and wrdata(6) = '0') then iD <= '0'; elsif(iBits = 7 and wrdata(7) = '1') then iD <= '1'; elsif(iBIts = 7 and wrdata(7) = '0') then iD <= '0'; end if; if(iCount >= 60 and iBits <= 7) then iBits := iBits + 1; iD <= '1'; iCntRst <= '1'; --stop timer next_state := BEGIN_WRITE; elsif(iBits = 8) then iD <= '1'; iCntRst <= '1'; --stop timer next_state := RDY; end if; end case; state <= next_state; if(reset = '1') then state <= init1; end if; end if; end process nxt_state_decoder; end block init_statemachine; trictrl: process(iD) begin if( iD = '0' ) then DQ <= '0'; else DQ <= 'Z'; end if; end process trictrl; end architecture structural; PACKAGE PROTOCOL_PKG IS COMPONENT one_wire END COMPONENT; END PROTOCOL_PKG;