From: hadeshyp Date: Fri, 20 Feb 2009 18:00:15 +0000 (+0000) Subject: added passive 1wire listener X-Git-Tag: oldGBE~480 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=0c3d5017ac6f2b354f18450aa83851e7a77f869c;p=trbnet.git added passive 1wire listener --- diff --git a/testbenches/testbench_pseudo_random_stream.prj b/testbenches/testbench_pseudo_random_stream.prj new file mode 100644 index 0000000..650f940 --- /dev/null +++ b/testbenches/testbench_pseudo_random_stream.prj @@ -0,0 +1,7 @@ +vhdl work "../trb_net_std.vhd" +vhdl work "../basics/signal_sync.vhd" +vhdl work "../trb_net16_med_16_CC.vhd" +vhdl work "../trb_net_CRC.vhd" +vhdl work "pseudo_random_stream_generator.vhd" +vhdl work "pseudo_random_stream_checker.vhd" +vhdl work "testbench_pseudo_random_stream.vhd" diff --git a/testbenches/testbench_pseudo_random_stream.vhd b/testbenches/testbench_pseudo_random_stream.vhd new file mode 100644 index 0000000..7bb80a9 --- /dev/null +++ b/testbenches/testbench_pseudo_random_stream.vhd @@ -0,0 +1,199 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net16_hub_func.all; + + +entity testbench is +end entity testbench; + +architecture testbench_arch of testbench is + + component pseudo_random_stream_checker is + generic( + WIDTH : integer := 16 + ); + port( + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + D_IN : in std_logic_vector(15 downto 0); + D_EN : in std_logic; + D_RST : in std_logic; + FAIL : out std_logic; + MY_CRC_OUT: out std_logic_vector(15 downto 0) + ); + end component; + + component pseudo_random_stream_generator is + port( + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + D_OUT : out std_logic_vector(15 downto 0); + D_EN : out std_logic; + D_RST : out std_logic + ); + end component; + + component trb_net16_med_16_CC is + port( + CLK : in std_logic; + CLK_EN : in std_logic; + RESET : in std_logic; + + --Internal Connection + MED_DATA_IN : in std_logic_vector(c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_IN : in std_logic_vector(c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_IN : in std_logic; + MED_READ_OUT : out std_logic; + MED_DATA_OUT : out std_logic_vector(c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_OUT : out std_logic; + MED_READ_IN : in std_logic; + + DATA_OUT : out std_logic_vector(15 downto 0); + DATA_VALID_OUT : out std_logic; + DATA_CTRL_OUT : out std_logic; + DATA_IN : in std_logic_vector(15 downto 0); + DATA_VALID_IN : in std_logic; + DATA_CTRL_IN : in std_logic; + + STAT_OP : out std_logic_vector(15 downto 0); + CTRL_OP : in std_logic_vector(15 downto 0); + STAT_DEBUG : out std_logic_vector(63 downto 0) + ); + end component; + + signal CLK : std_logic := '1'; + signal RESET : std_logic := '1'; + signal CLK_EN : std_logic := '1'; + + signal MED_DATAREADY_IN : std_logic; + signal MED_READ_IN : std_logic; + signal MED_DATAREADY_OUT : std_logic; + signal MED_READ_OUT : std_logic; + signal MED_PACKET_NUM_OUT : std_logic_vector(2 downto 0); + signal MED_PACKET_NUM_IN : std_logic_vector(2 downto 0); + signal MED_DATA_IN : std_logic_vector(15 downto 0); + signal MED_DATA_OUT : std_logic_vector(15 downto 0); + signal MED_R_DATAREADY_IN : std_logic; + signal MED_R_READ_IN : std_logic; + signal MED_R_DATAREADY_OUT : std_logic; + signal MED_R_READ_OUT : std_logic; + signal MED_R_PACKET_NUM_OUT : std_logic_vector(2 downto 0); + signal MED_R_PACKET_NUM_IN : std_logic_vector(2 downto 0); + signal MED_R_DATA_IN : std_logic_vector(15 downto 0); + signal MED_R_DATA_OUT : std_logic_vector(15 downto 0); + signal MED_STAT_OP : std_logic_vector(31 downto 0); + signal MED_CTRL_OP : std_logic_vector(31 downto 0); + + + + signal DATA_LINK1 : std_logic_vector(17 downto 0); + signal DATA_LINK2 : std_logic_vector(17 downto 0); + signal gen_RESET : std_logic; + +begin + CLK <= not CLK after 5 ns; + RESET <= '0' after 50 ns; + CLK_EN <= '1'; + + +--Sender +----------------------- + THE_GENERATOR : pseudo_random_stream_generator + port map( + CLK => CLK, + RESET => gen_RESET, + CLK_EN => CLK_EN, + D_OUT => MED_DATA_OUT, + D_EN => MED_DATAREADY_OUT, + D_RST => open + ); + MED_PACKET_NUM_OUT <= "000"; + + gen_RESET <= RESET or (not MED_READ_IN); + +--Connecting both parts +----------------------- + + + THE_SENDER_MED : trb_net16_med_16_CC + port map( + CLK => CLK, + CLK_EN => CLK_EN, + RESET => RESET, + + --Internal Connection + MED_DATA_IN => MED_DATA_OUT, + MED_PACKET_NUM_IN => MED_PACKET_NUM_OUT, + MED_DATAREADY_IN => MED_DATAREADY_OUT, + MED_READ_OUT => MED_READ_IN, + MED_DATA_OUT => MED_DATA_IN, + MED_PACKET_NUM_OUT => MED_PACKET_NUM_IN, + MED_DATAREADY_OUT => MED_DATAREADY_IN, + MED_READ_IN => MED_READ_OUT, + + DATA_OUT => DATA_LINK1(15 downto 0), + DATA_VALID_OUT => DATA_LINK1(16), + DATA_CTRL_OUT => DATA_LINK1(17), + DATA_IN => DATA_LINK2(15 downto 0), + DATA_VALID_IN => DATA_LINK2(16), + DATA_CTRL_IN => DATA_LINK2(17), + + STAT_OP => MED_STAT_OP(15 downto 0), + CTRL_OP => MED_CTRL_OP(15 downto 0), + STAT_DEBUG => open + ); + + THE_RECEIVER_MED : trb_net16_med_16_CC + port map( + CLK => CLK, + CLK_EN => CLK_EN, + RESET => RESET, + + --Internal Connection + MED_DATA_IN => MED_R_DATA_OUT, + MED_PACKET_NUM_IN => MED_R_PACKET_NUM_OUT, + MED_DATAREADY_IN => MED_R_DATAREADY_OUT, + MED_READ_OUT => MED_R_READ_IN, + MED_DATA_OUT => MED_R_DATA_IN, + MED_PACKET_NUM_OUT => MED_R_PACKET_NUM_IN, + MED_DATAREADY_OUT => MED_R_DATAREADY_IN, + MED_READ_IN => MED_R_READ_OUT, + + DATA_OUT => DATA_LINK2(15 downto 0), + DATA_VALID_OUT => DATA_LINK2(16), + DATA_CTRL_OUT => DATA_LINK2(17), + DATA_IN => DATA_LINK1(15 downto 0), + DATA_VALID_IN => DATA_LINK1(16), + DATA_CTRL_IN => DATA_LINK1(17), + + STAT_OP => MED_STAT_OP(31 downto 16), + CTRL_OP => MED_CTRL_OP(31 downto 16), + STAT_DEBUG => open + ); +MED_CTRL_OP <= MED_STAT_OP; + +--Receiver +----------------------- + + THE_CHECKER : pseudo_random_stream_checker + port map( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + D_IN => MED_R_DATA_IN, + D_EN => MED_R_DATAREADY_IN, + D_RST => '0', + FAIL => open, + MY_CRC_OUT => open + ); + + +end architecture; \ No newline at end of file diff --git a/trb_net_onewire.vhd b/trb_net_onewire.vhd index 9ac43f6..a09522f 100644 --- a/trb_net_onewire.vhd +++ b/trb_net_onewire.vhd @@ -18,6 +18,7 @@ entity trb_net_onewire is RESET : in std_logic; --connection to 1-wire interface ONEWIRE : inout std_logic; + MONITOR_OUT : out std_logic; --connection to id ram, according to memory map in TrbNetRegIO DATA_OUT : out std_logic_vector(15 downto 0); ADDR_OUT : out std_logic_vector(2 downto 0); @@ -60,6 +61,15 @@ begin ONEWIRE <= '0' when output = '0' else '1' when strong_pullup = '1' else 'Z'; input <= ONEWIRE; + + + PROC_REG_MONITOR : process(CLK) + begin + if rising_edge(CLK) then + MONITOR_OUT <= ONEWIRE; + end if; + end process; + bitcounter_vector <= conv_std_logic_vector(bitcounter,7); process(state, timecounter, bitcounter_vector, input, diff --git a/trb_net_onewire_listener.vhd b/trb_net_onewire_listener.vhd new file mode 100644 index 0000000..fc0958f --- /dev/null +++ b/trb_net_onewire_listener.vhd @@ -0,0 +1,259 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; + +entity trb_net_onewire_listener is + port( + CLK : in std_logic; + CLK_EN : in std_logic; + RESET : in std_logic; + MONITOR_IN : in std_logic; + DATA_OUT : out std_logic_vector(15 downto 0); + ADDR_OUT : out std_logic_vector(2 downto 0); + WRITE_OUT: out std_logic; + TEMP_OUT : out std_logic_vector(11 downto 0); + STAT : out std_logic_vector(31 downto 0) + ); +end entity; + +architecture arch of trb_net_onewire_listener is + + component signal_sync is + generic( + WIDTH : integer := 1; -- + DEPTH : integer := 3 + ); + port( + RESET : in std_logic; --Reset is neceessary to avoid optimization to shift register + CLK0 : in std_logic; --clock for first FF + CLK1 : in std_logic; --Clock for other FF + D_IN : in std_logic_vector(WIDTH-1 downto 0); --Data input + D_OUT : out std_logic_vector(WIDTH-1 downto 0) --Data output + ); + end component; + + signal buf_ADDR_OUT : std_logic_vector(2 downto 0); + signal buf_DATA_OUT : std_logic_vector(15 downto 0); + signal buf_WRITE_OUT : std_logic; + signal buf_TEMP_OUT : std_logic_vector(11 downto 0); + + signal reg_onewire: std_logic; + signal onewire : std_logic; + signal tcounter : unsigned(15 downto 0); --timing of signals + signal rcounter : unsigned(15 downto 0); --detection of long reset pulse + signal bcounter : unsigned(7 downto 0); --bitcounter + signal saved_onewire : std_logic_vector(7 downto 0); + signal read_bit_enable : std_logic; + signal read_byte : std_logic_vector(15 downto 0); + + type state_t is (RESETTING, WAIT_AFTER_RESET, READ_COMMAND_BIT_1, READ_COMMAND_BIT_2, READ_ID_1, READ_ID_2, + READ_TEMP_1, READ_TEMP_2, EVAL_COMMAND, EVAL_ID, EVAL_TEMP, WAIT_FOR_RESET); + signal state : state_t; + signal state_bits : std_logic_vector(3 downto 0); + +begin + + + THE_INPUT_SYNC : signal_sync + generic map( + DEPTH => 2, + WIDTH => 1 + ) + port map( + RESET => RESET, + D_IN(0) => MONITOR_IN, + CLK0 => CLK, + CLK1 => CLK, + D_OUT(0) => reg_onewire + ); + + + PROC_CLEAN_ONEWIRE : process(CLK) + begin + if rising_edge(CLK) and CLK_EN = '1' then + saved_onewire <= reg_onewire & saved_onewire(7 downto 1); + if or_all(saved_onewire) = '0' then + onewire <= '0'; + elsif and_all(saved_onewire) = '1' then + onewire <= '1'; + end if; + end if; + end process; + + PROC_SHIFT_BYTES : process(CLK) + begin + if rising_edge(CLK) and CLK_EN = '1' then + if read_bit_enable = '1' then + read_byte <= onewire & read_byte(15 downto 1); + end if; + end if; + end process; + + + PROC_FSM : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + state <= RESETTING; + buf_TEMP_OUT <= (others => '0'); + buf_WRITE_OUT <= '0'; + elsif CLK_EN = '1' then + read_bit_enable <= '0'; + buf_WRITE_OUT <= '0'; + + case state is + --detect reset pulse > 320us + when RESETTING => + if onewire = '1' then + state <= WAIT_AFTER_RESET; + tcounter <= (others => '0'); + end if; + + --assume presence pulse is ok + when WAIT_AFTER_RESET => + if tcounter(12) = '0' then + if onewire = '0' then + tcounter <= tcounter + "1"; + else + tcounter <= (others => '0'); + end if; + elsif onewire = '1' then + state <= READ_COMMAND_BIT_1; + tcounter <= (others => '0'); + bcounter <= (others => '0'); + end if; + + --wait for 0.64us 0, then wait for 12.80us + when READ_COMMAND_BIT_1 | READ_ID_1 | READ_TEMP_1 => + tcounter <= tcounter + "1"; + if tcounter < 64 and onewire = '1' then + tcounter <= (others => '0'); + elsif tcounter >= 1280 then + read_bit_enable <= '1'; + case state is + when READ_COMMAND_BIT_1 => state <= READ_COMMAND_BIT_2; + when READ_ID_1 => state <= READ_ID_2; + when READ_TEMP_1 => state <= READ_TEMP_2; + when others => state <= WAIT_FOR_RESET; --haha + end case; + tcounter <= (others => '0'); + end if; + + --wait until onewire is high, then go back or evaluate byte + when READ_COMMAND_BIT_2 | READ_ID_2 | READ_TEMP_2 => + if onewire = '1' then + tcounter <= (others => '0'); + bcounter <= bcounter + "1"; + case state is + when READ_COMMAND_BIT_2 => + if bcounter(2 downto 0) = "111" then + state <= EVAL_COMMAND; + else + state <= READ_COMMAND_BIT_1; + end if; + when READ_ID_2 => + if bcounter(3 downto 0) = x"F" then + state <= EVAL_ID; + else + state <= READ_ID_1; + end if; + when READ_TEMP_2 => + if bcounter = x"0B" then + state <= EVAL_TEMP; + else + state <= READ_TEMP_1; + end if; + when others => + state <= WAIT_FOR_RESET; --haha + end case; + end if; + + --interprete the received command + when EVAL_COMMAND => + bcounter <= (others => '0'); + tcounter <= (others => '0'); + case read_byte(15 downto 8) is + when x"33" => --read rom + state <= READ_ID_1; + when x"CC" => --skip rom + state <= READ_COMMAND_BIT_1; + when x"44" => --conv temp + state <= WAIT_FOR_RESET; + when x"BE" => --read temp + state <= READ_TEMP_1; + when others => --ignore + state <= WAIT_FOR_RESET; + end case; + + --output received temperature + when EVAL_TEMP => + bcounter <= (others => '0'); + tcounter <= (others => '0'); + buf_TEMP_OUT <= read_byte(15 downto 4); + state <= WAIT_FOR_RESET; + + --write ID to RAM + when EVAL_ID => + buf_DATA_OUT <= read_byte; + buf_WRITE_OUT <= '1'; + buf_ADDR_OUT <= '0' & std_logic_vector(bcounter(5 downto 4)-"1"); + if bcounter(5 downto 4) = "00" then + state <= WAIT_FOR_RESET; + else + state <= READ_ID_1; + end if; + + --waiting for reset covered by reset detection below + when WAIT_FOR_RESET => null; + when others => state <= WAIT_FOR_RESET; + + end case; + + --detect reset signal + if onewire = '0' then + rcounter <= rcounter + "1"; + if rcounter(15) = '1' then + state <= RESETTING; + rcounter <= (others => '0'); + end if; + else + rcounter <= (others => '0'); + end if; + + end if; + end if; + end process; + + DATA_OUT <= buf_DATA_OUT; + ADDR_OUT <= buf_ADDR_OUT; + WRITE_OUT <= buf_WRITE_OUT; + TEMP_OUT <= buf_TEMP_OUT; + + + state_bits <= "0000" when state = WAIT_FOR_RESET else + "0001" when state = RESETTING else + "0010" when state = WAIT_AFTER_RESET else + "0011" when state = READ_COMMAND_BIT_1 else + "0100" when state = READ_COMMAND_BIT_2 else + "0101" when state = READ_ID_1 else + "0110" when state = READ_ID_2 else + "0111" when state = READ_TEMP_1 else + "1000" when state = READ_TEMP_2 else + "1001" when state = EVAL_COMMAND else + "1010" when state = EVAL_ID else + "1011" when state = EVAL_TEMP else + "1100" when state = WAIT_FOR_RESET else + "1111"; + + STAT(0) <= onewire; + STAT(4 downto 1) <= state_bits; + STAT(12 downto 5) <= std_logic_vector(bcounter); + STAT(15 downto 13) <= buf_ADDR_OUT; + STAT(31 downto 16) <= std_logic_vector(tcounter); + + +end architecture; \ No newline at end of file