OpenCores
URL https://opencores.org/ocsvn/tosnet/tosnet/trunk

Subversion Repositories tosnet

[/] [tosnet/] [trunk/] [gateware/] [TosNet_rev3_2/] [tdl_app_sync.vhd] - Rev 4

Go to most recent revision | Compare with Previous | Blame | View Log

----------------------------------------------------------------------------------
-- Company: 		University of Southern Denmark
-- Engineer: 		Simon Falsig
-- 
-- Create Date:    	7/3/2010 
-- Design Name		TosNet
-- Module Name:    	app_sync - Behavioral 
-- File Name:		app_sync.vhd
-- Project Name:	TosNet
-- Target Devices:	Spartan3/6
-- Tool versions:	Xilinx ISE 12.2
-- Description: 	The synchronization module handles the synchronization strobes
--					that are emitted at the end of each cycle. The strobe is
--					delayed for a fixed interval, depending on the node address
--					(which specifies the position of the node in the network
--					relative to the master), which causes the strobe to be emitted
--					at the same time in all nodes.
--
-- Revision: 
-- Revision 3.2 - 	Initial release
--
-- Copyright 2010
--
-- This module is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This module is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with this module.  If not, see <http://www.gnu.org/licenses/>.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity tdl_app_sync is
	Port (	app_enable				: in	STD_LOGIC;
			app_data_in				: in	STD_LOGIC_VECTOR(7 downto 0);
			app_data_in_strobe		: in	STD_LOGIC;
			app_data_in_enable		: in	STD_LOGIC;
			app_data_out			: out	STD_LOGIC_VECTOR(7 downto 0);
			app_data_out_strobe		: out	STD_LOGIC;
			app_data_out_enable		: out	STD_LOGIC;
			app_buffer_full			: in	STD_LOGIC;
			app_packet_error		: in	STD_LOGIC;
			app_force_packet_error	: out	STD_LOGIC;
			app_cmd_valid			: in	STD_LOGIC;
			app_sync_strobe			: out	STD_LOGIC;
			app_is_master			: in	STD_LOGIC;
			app_dsc_done			: out	STD_LOGIC;
			app_node_id				: in	STD_LOGIC_VECTOR(3 downto 0);
			app_node_count			: in	STD_LOGIC_VECTOR(3 downto 0);
			app_node_address		: in	STD_LOGIC_VECTOR(3 downto 0);
			app_clk					: in	STD_LOGIC;
			app_reset				: in	STD_LOGIC);
end tdl_app_sync;
 
architecture Behavioral of tdl_app_sync is
 
	type STATES is (OFF, CALC_SYNC_DELAY, SYNC_READY, SYNC_ONLINE, SYNC_RUNNING, SYNC_SET);
 
	signal state					: STATES := OFF;
	signal next_state				: STATES := OFF;
 
	signal last_data_in_enable		: STD_LOGIC;
 
	signal counter					: STD_LOGIC_VECTOR(4 downto 0) := "00000";
 
	signal delay_counter			: STD_LOGIC_VECTOR(11 downto 0) := "000000000000";
	signal delay_current_node		: STD_LOGIC_VECTOR(11 downto 0) := "000000000000";
	constant delay_pr_node			: STD_LOGIC_VECTOR(11 downto 0) := "000100101100";
 
begin
 
	process(app_clk)
	begin
		if(app_clk = '1' and app_clk'EVENT) then
			if(app_reset = '1') then
				state <= OFF;
			else
				state <= next_state;
			end if;
 
			if(state = next_state) then
				counter <= counter + 1;
			else
				counter <= "00000";
			end if;
 
			case state is
 
				when OFF =>
					delay_counter <= "000000000000";
					delay_current_node <= "000000000000";
					app_dsc_done <= '0';
					last_data_in_enable <= '0';
					app_sync_strobe <= '0';
 
				when CALC_SYNC_DELAY =>
					if(app_is_master = '1') then
						delay_current_node <= "000000000000";
					elsif(counter = 0) then
						delay_current_node <= delay_pr_node;
					else
						delay_current_node <= delay_current_node + delay_pr_node;
					end if;
 
				when SYNC_READY =>
					if(app_is_master = '1') then
						app_sync_strobe <= '1';			--If this is the master node, send out a single sync pulse to get the application started...
					end if;
 
				when SYNC_ONLINE =>
					app_dsc_done <= '1';
					app_sync_strobe <= '0';
					delay_counter <= "000000000000";
 
				when SYNC_RUNNING =>
					delay_counter <= delay_counter + 1;
 
				when SYNC_SET =>
					app_sync_strobe <= '1';
 
			end case;
 
			last_data_in_enable <= app_data_in_enable;
 
		end if;
	end process;
 
	process(state, app_enable, counter, app_node_count, app_node_address, delay_counter, delay_current_node, app_data_in_enable, last_data_in_enable)
	begin
		case state is
			when OFF =>
				if(app_enable = '1') then
					next_state <= CALC_SYNC_DELAY;
				else
					next_state <= OFF;
				end if;
			when CALC_SYNC_DELAY =>
				if(counter = app_node_count - app_node_address - 1) then
					next_state <= SYNC_READY;
				else
					next_state <= CALC_SYNC_DELAY;
				end if;
			when SYNC_READY =>									--Make sure that the current transmission is done before going online (if not the enable signal from the received sync_set will trigger the sync mechanism... which is kinda not what we want)
				if(app_data_in_enable = '0') then
					next_state <= SYNC_ONLINE;
				else
					next_state <= SYNC_READY;
				end if;
			when SYNC_ONLINE =>
				if(app_data_in_enable = '0' and last_data_in_enable = '1') then
					next_state <= SYNC_RUNNING;
				else
					next_state <= SYNC_ONLINE;
				end if;
			when SYNC_RUNNING =>
				if(app_data_in_enable = '1') then			--If app_data_in_enable goes high before the sync_strobe something bad is happening - but let's just make sure we don't make it worse by sending a sync_strobe in the middle of a (probably erroneous) transmission...
					next_state <= SYNC_ONLINE;
				elsif(delay_counter = delay_current_node) then
					next_state <= SYNC_SET;
				else
					next_state <= SYNC_RUNNING;
				end if;
			when SYNC_SET =>
				next_state <= SYNC_ONLINE;
		end case;
	end process;
 
 
end Behavioral;
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.