⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 onewire2.vhd

📁 Dallas 1-Wire ip 非常有用,不占用CPU的时间.
💻 VHD
字号:
---------------------------------------------------------------------------
-- Copyright (c) 2001,2002 White Bream
---------------------------------------------------------------------------
-- DO NOT DISCLOSE
---------------------------------------------------------------------------
-- File:				onewire.vhd
--	Language:		VHDL 93
--
-- Creation date:	Jan 15, 2001
-- Version:			0.01
-- Revison date:	Jan 15, 2001
-- Author:			Henk Bliek
---------------------------------------------------------------------------
-- Description:	This core implements an 1-Wire controller
--
-- Revisionlog:
--		0.01			Henk Bliek - Jan 15, 2001
--						* Initial version
--						* Changed project to be a commercial VHDL core
---------------------------------------------------------------------------
-- Practical comment: This file is entered with a tabsize of 3 characters.


---- Component declaration, copy this into the target code and uncomment.
---------------------------------------------------------------------------
--	component onewire is
--		port(	bitclk		:in std_logic;
--				sysclk		:in std_logic;
--				rst			:in std_logic;
--				data_in		:in std_logic_vector(7 downto 0);
--				data_out		:out std_logic_vector(7 downto 0);
--				addr_in		:in std_logic_vector(1 downto 0);
--				cs				:in std_logic;
--				rd				:in std_logic;
--				wr				:in std_logic;
--				int			:out std_logic;
--				inwire		:in std_logic;
--				outwire		:out std_logic);
--	end component;

	
---- Component instantiation, copy and uncomment this into the target
---- code and modify the signalnames to whatever needed.
---------------------------------------------------------------------------
--	IrDecoder: onewire
--	port map(	bitclk		:in std_logic;
--					sysclk		:in std_logic;
--					rst			:in std_logic;
--					data_in		:in std_logic_vector(7 downto 0);
--					data_out		:out std_logic_vector(7 downto 0);
--					addr_in		:in std_logic_vector(1 downto 0);
--					cs				:in std_logic;
--					rd				:in std_logic;
--					wr				:in std_logic;
--					int			:out std_logic;
--					inwire		,
--					outwire		= );

library ieee;
use ieee.std_logic_1164.all;

entity onewire2 is
	port(	-- This clock must have a period of ~2us
			bitclk		:in std_logic;
			sysclk		:in std_logic;
			rst			:in std_logic;
			data_in		:in std_logic_vector(7 downto 0);
			data_out		:out std_logic_vector(7 downto 0);
			addr_in		:in std_logic_vector(1 downto 0);
			cs				:in std_logic;
			rd				:in std_logic;
			wr				:in std_logic;
			int			:out std_logic;
			-- The 1-Wire interface itself
			inwire		:in std_logic;
			outwire		:out std_logic);
end entity;

architecture rtl of onewire2 is
	signal read_reg			:std_logic_vector(7 downto 0);
	signal write_reg			:std_logic_vector(7 downto 0);
	signal status_reg			:std_logic_vector(7 downto 0);
	signal control_reg		:std_logic_vector(7 downto 0);
	
	signal wr_buf_empty		:std_logic;
	signal write_read			:std_logic;
	signal status_read		:std_logic;
	signal new_write			:std_logic;
	signal rst_done			:std_logic;
	signal got_pd				:std_logic;
	signal pd_time				:std_logic;
	signal pd_enable			:std_logic;
	signal pd_over				:std_logic;
	
	constant DATA				:std_logic_vector(1 downto 0) := "00";
	constant STATUS			:std_logic_vector(1 downto 0) := "01";
	constant CONTROL			:std_logic_vector(1 downto 0) := "10";

	signal clk_count			:integer range 0 to 32;
	signal wr_bit_count		:integer range 0 to 7;
	signal bit_count			:integer range 0 to 7;
	signal rst_count			:integer range 0 to 16;

	signal write0				:std_logic;
	signal write1				:std_logic;
	signal read01				:std_logic;
	signal reset				:std_logic;
begin
	IntelRead: process(rst, rd)
	begin
		if(rst = '0') then
			data_out <= (others => '0');
			status_read <= '0';
		elsif(rd'event and rd = '0') then
			if(cs = '0') then
				case addr_in is
					when DATA =>
						data_out <= read_reg;
					when STATUS =>
						data_out <= status_reg;
						status_read <= not status_read;
					when CONTROL =>
						data_out <= control_reg;
					when others =>
						null;
				end case;
			end if;
		end if;
	end process IntelRead;

	IntelWrite: process(rst, wr)
	begin
		if(rst = '0') then
			new_write <= '0';
		elsif(wr'event and wr = '0') then
			if(cs = '0') then
				case addr_in is
					when DATA =>
						write_reg <= data_in;
						new_write <= not new_write;
					when CONTROL =>
						control_reg <= data_in;
					when others =>
						null;
				end case;
			end if;
		end if;
	end process IntelWrite;

	WrBufferFlg: process(rst, sysclk)
	begin
		if(rst = '0') then
			wr_buf_empty <= '1';
		elsif(sysclk'event and sysclk = '1') then
			wr_buf_empty <= not (new_write xor write_read);
		end if;
	end process WrBufferFlg;

	Write: process(rst, bitclk)
	begin
		if(rst = '0') then
			write_read <= '0';
			wr_bit_count <= 0;
			write0 <= '0';
			write1 <= '0';
		elsif(bitclk'event and bitclk = '1') then
			if(wr_buf_empty = '0') then
				-- We step through the bit in multiple clocks (8)
				if(clk_count = 0) then
					write0 <= '0';
					write1 <= '0';
					case wr_bit_count is
						when 0 =>
							if(write_reg(0) = '0') then
								write0 <= '1';
							else
								write1 <= '1';
							end if;
						when 1 =>
							if(write_reg(1) = '0') then
								write0 <= '1';
							else
								write1 <= '1';
							end if;
						when 2 =>
							if(write_reg(2) = '0') then
								write0 <= '1';
							else
								write1 <= '1';
							end if;
						when 3 =>
							if(write_reg(3) = '0') then
								write0 <= '1';
							else
								write1 <= '1';
							end if;
						when 4 =>
							if(write_reg(4) = '0') then
								write0 <= '1';
							else
								write1 <= '1';
							end if;
						when 5 =>
							if(write_reg(5) = '0') then
								write0 <= '1';
							else
								write1 <= '1';
							end if;
						when 6 =>
							if(write_reg(6) = '0') then
								write0 <= '1';
							else
								write1 <= '1';
							end if;
						when 7 =>
							if(write_reg(7) = '0') then
								write0 <= '1';
							else
								write1 <= '1';
							end if;
						when others =>
							-- Register empty; we're done
							write_read <= '1';
					end case;
					wr_bit_count <= wr_bit_count + 1;
				end if;
			else
				wr_bit_count <= 0;
			end if;
		end if;
	end process Write;

	Read: process(rst, bitclk)
	begin
		if(rst = '0') then
			read_reg <= (others => '0');
		elsif(bitclk'event and bitclk = '1') then
			-- We step through the bit in multiple clocks (8)
			read_reg <= read_reg(6 downto 0) & inwire;
		end if;
	end process Read;

	DataOut: process(rst, bitclk)
	begin
		if(rst = '0') then
			outwire <= '1';
			rst_count <= 0;
		elsif(bitclk'event and bitclk = '1') then
			if(write0 = '1') then
				rst_done <= '0';
				case clk_count is
					when 31 | 32 =>
						outwire <= '1';
					when others =>
						outwire <= '0';
				end case;
			elsif(write1 = '1') then
				rst_done <= '0';
				case clk_count is
					when 0 =>
						outwire <= '0';
					when others =>
						outwire <= '1';
				end case;
			elsif(reset = '1') then
				pd_time <= '0';
				rst_done <= '0';
				if(clk_count = 30) then
					if(rst_count < 8) then -- 8 * 32 * 2us ~ 480us
						outwire <= '0';
					elsif(rst_count >= 8) then -- 60us
						outwire <= '1';
						rst_done <= '1';
						pd_enable <= '1';
					elsif(rst_count = 16) then
						pd_time <= '1';
						pd_enable <= '0';
					else
						outwire <= '1';
					end if;
					rst_count <= rst_count + 1;
				end if;
			else
				outwire <= '1';
			end if;
			if(pd_over = '1') then	
				pd_enable <= '0';
			end if;
		end if;
	end process DataOut;

	PresDet: process(reset, rst, inwire)
	begin -- Detect negative edge during PD timeslot
		if(rst = '0' or reset = '1') then
			got_pd <= '0';
		elsif(inwire'event and inwire = '0') then
			if(pd_enable = '1') then
				got_pd <= '1';
			end if;
		end if;
	end process PresDet;
	
	PresDetTime: process(reset, rst, inwire)
	begin
		if(rst = '0' or reset = '1') then
			pd_over <= '0';
		elsif(inwire'event and inwire = '1') then
			if(pd_enable = '1' and got_pd = '1') then
				pd_over <= '1';
			end if;
		end if;
	end process PresDetTime;

	Clock: process(rst, bitclk)
	begin
		if(rst = '0') then
			clk_count <= 0;
		elsif(bitclk'event and bitclk = '1') then
			clk_count <= clk_count + 1;
		end if;
	end process Clock;
	
	Interrupt: process(rst, rd, wr_buf_empty, pd_over, got_pd)
	begin
		if(rst = '0') then
			int <= '1';
		elsif(wr_buf_empty = '1' or pd_over = '1' or got_pd = '1') then
			int <= '0'; -- NOT GOOD YET
		elsif(rd'event and rd = '1') then
			int <= '1';
		end if;
	end process Interrupt;
	
	status_reg <= wr_buf_empty & "000" & '0' & pd_over & got_pd & '0';

	reset <= control_reg(1);
end rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -