📄 onewire2.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 + -