LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; -- $Id$: -- read a DS18B20 1-wire temperature sensor -- tres bits conv. time [ms] -- "11" 12 750 -- "10" 11 375 -- "01" 10 187.5 -- "00" 9 93.75 -- tL and tH are threshold for alarm, we do not use it, but -- they will be read back and so the interface can be tested! library work; use work.ds_pack.all; entity ds_top is generic ( Nrst0 : Integer range 0 to 1023 := 512; -- us, pull down time Nrsts : Integer range 0 to 255 := 100; -- us, sample time Nrst1 : Integer range 0 to 1023 := 512; -- us, high Z time Nwr0 : Integer range 0 to 127 := 80; -- us, pull down time Nwr1 : Integer range 0 to 15 := 8; -- us, pull down time Nrd : Integer range 0 to 3 := 2; -- us, pull down time Ntts : Integer range 0 to 127 := 90; -- us, total time for a time slot read/write Nrds : Integer range 0 to 15 := 8); -- us, sample time for read port ( clk : in std_logic; -- 1MHz rst_n : in std_logic; -- to the I/O cell oe : out std_logic; dout : out std_logic; din : in std_logic; -- from the configuration or just constants tres : in std_logic_vector(1 downto 0); -- resolution tL : in std_logic_vector(7 downto 0); -- T low tH : in std_logic_vector(7 downto 0); -- T high -- read port for the read bytes, 0..8 presence: out std_logic; rTsensL : out std_logic_vector(7 downto 0); -- read Tsensor rTsensH : out std_logic_vector(7 downto 0); --/ rtL : out std_logic_vector(7 downto 0); -- read thresholds rtH : out std_logic_vector(7 downto 0) --/ ); end ds_top; architecture a of ds_top is component byteslots is generic ( Nrst0 : Integer range 0 to 1023 := 512; -- us, pull down time Nrsts : Integer range 0 to 255 := 180; -- us, sample time Nrst1 : Integer range 0 to 1023 := 512; -- us, high Z time Nwr0 : Integer range 0 to 127 := 80; -- us, pull down time Nwr1 : Integer range 0 to 15 := 8; -- us, pull down time Nrd : Integer range 0 to 3 := 2; -- us, pull down time Ntts : Integer range 0 to 127 := 90; -- us, total time for a time slot read/write Nrds : Integer range 0 to 15 := 8); -- us, sample time for read port( clk : in std_logic; rst_n : in std_logic; -- from the master state machine cmd : in std_logic_vector(1 downto 0); start : in std_logic; -- to the I/O cell oe : out std_logic; dout : out std_logic; din : in std_logic; -- to the master state machine wrbyte : in std_logic_vector(7 downto 0); retbyte : out std_logic_vector(7 downto 0); valid : out std_logic); end component; component program is port( raddr : in std_logic_vector( 4 downto 0); tres : in std_logic_vector( 1 downto 0); tL : in std_logic_vector( 7 downto 0); -- T low tH : in std_logic_vector( 7 downto 0); -- T high rdata : out std_logic_vector(11 downto 0)); end component; -- For Precision! -- The FSM_STATE attribute has 6 possible values: -- auto, binary, onehot, twohot, random, and gray type sm_type is (idle, resets, writeb, readb, waitp, pullH, finish); attribute FSM_STATE : string; attribute FSM_STATE of sm_type : type is "gray"; attribute SAFE_FSM : boolean; attribute SAFE_FSM of sm_type : type is true; signal sm : sm_type; type reg_arr is array(0 to 8) of std_logic_vector(7 downto 0); signal read_reg : reg_arr; signal pdata : std_logic_vector(11 downto 0); signal paddr : std_logic_vector( 4 downto 0); signal retbyte : std_logic_vector( 7 downto 0); signal start_byte : std_logic; signal valid_byte : std_logic; signal pcmd : std_logic_vector(3 downto 0); signal counter : std_logic_vector(19 downto 0); signal valid, start : std_logic; begin process(clk, rst_n) begin if rst_n = '0' then valid <= '0'; start_byte <= '0'; sm <= idle; paddr <= (others => '0'); counter <= (others => '0'); elsif rising_edge(clk) then valid <= '0'; start_byte <= '0'; case sm is when idle => case pcmd is when reset => start_byte <= '1'; if valid_byte='0' then sm <= resets; end if; when rd_cmd => start_byte <= '1'; if valid_byte='0' then sm <= readb; end if; when wr_cmd => start_byte <= '1'; if valid_byte='0' then sm <= writeb; end if; when h_high => start_byte <= '1'; if valid_byte='0' then sm <= pullH; end if; when stop => sm <= finish; when others => sm <= finish; end case; when resets | readb | writeb => if valid_byte = '1' then paddr <= paddr + 1; sm <= idle; end if; when pullH => if valid_byte = '1' then counter <= pdata(7 downto 0) & X"000"; -- counter <= X"000" & pdata(7 downto 0); -- for simulation sm <= waitp; end if; when waitp => if counter = 0 then paddr <= paddr + 1; sm <= idle; else counter <= counter - 1; end if; when finish => valid <= '1'; if start = '1' then paddr <= (others => '0'); sm <= idle; end if; when others => sm <= finish; end case; end if; end process; wrg:process(clk) begin if rising_edge(clk) then if sm = resets and valid_byte='1' then presence <= retbyte(0); end if; start <= valid; if sm = readb and valid_byte='1' then case pdata(3 downto 0) is when "0000" => read_reg(0) <= retbyte; when "0001" => read_reg(1) <= retbyte; when "0010" => read_reg(2) <= retbyte; when "0011" => read_reg(3) <= retbyte; when "0100" => read_reg(4) <= retbyte; when "0101" => read_reg(5) <= retbyte; when "0110" => read_reg(6) <= retbyte; when "0111" => read_reg(7) <= retbyte; when "1000" => read_reg(8) <= retbyte; when others => NULL; end case; end if; end if; end process; --rrg:process(read_reg, raddr) -- begin -- case raddr is -- when "0000" => rbytes <= read_reg(0); -- when "0001" => rbytes <= read_reg(1); -- when "0010" => rbytes <= read_reg(2); -- when "0011" => rbytes <= read_reg(3); -- when "0100" => rbytes <= read_reg(4); -- when "0101" => rbytes <= read_reg(5); -- when "0110" => rbytes <= read_reg(6); -- when "0111" => rbytes <= read_reg(7); -- when "1000" => rbytes <= read_reg(8); -- when others => rbytes <= (others => '-'); -- end case; -- end process; rTsensL <= read_reg(0); rTsensH <= read_reg(1); rtH <= read_reg(2); rtL <= read_reg(3); -- Note: Byte 5 is reserved and should be 0xFF -- Byte 6 is reserved -- Byte 7 is reserved and should be 0x10 -- Byte 8 is CRC prg: program port map( raddr => paddr, tres => tres, tL => tL, tH => tH, rdata => pdata); pcmd <= pdata(11 downto 8); bsl: byteslots generic map( Nrst0 => Nrst0, Nrsts => Nrsts, Nrst1 => Nrst1, Nwr0 => Nwr0, Nwr1 => Nwr1, Nrd => Nrd, Ntts => Ntts, Nrds => Nrds) port map( clk => clk, rst_n => rst_n, -- from the master state machine cmd => pdata(9 downto 8), start => start_byte, -- to the I/O cell oe => oe, dout => dout, din => din, -- to the master state machine wrbyte => pdata(7 downto 0), retbyte => retbyte, valid => valid_byte); end;