---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 21:49:24 05/26/2008 -- Design Name: -- Module Name: top - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use usefuls.all; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; entity top is port ( clk : in std_logic; reset : in std_logic; led_1 : out std_logic; led_2 : out std_logic; scl : inout std_logic; sda : inout std_logic; pulse_in : in std_logic_vector(7 downto 0); pulse_out : out std_logic_vector(7 downto 0); ext_reset_n : out std_logic; hd3 : in std_logic; hd4 : in std_logic; hd8 : in std_logic; hd14 : in std_logic); end top; architecture Behavioral of top is constant por_counter_length : positive := 5; signal por_counter : std_logic_vector(por_counter_length-1 downto 0) := (others => '1'); component DividerN is generic ( divide_value : integer); port ( clk_in, ce : in std_logic; clk_out, tc : out std_logic); end component; signal clk_1M, clk_50, clk_1 : std_logic; signal tc_1M, tc_50 : std_logic; component i2c port( scl : inout std_logic; sda : inout std_logic; clk : in std_logic; reset : in std_logic; address : out std_logic_vector(6 downto 0); valid_address : in std_logic; data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); transaction : out std_logic; -- keep '1' in the same transaction dir : out std_logic; -- OUT => '0', IN => '1' request : out std_logic; -- request to client ready : in std_logic); -- client ready end component; signal i2c_address : std_logic_vector(6 downto 0); signal i2c_valid_address : std_logic; signal i2c_data_in : std_logic_vector(7 downto 0); signal i2c_data_out : std_logic_vector(7 downto 0); signal i2c_transaction : std_logic; signal i2c_dir : std_logic; signal i2c_request : std_logic; signal i2c_ready : std_logic; component ServoObserver is generic ( resolution : integer := 8; reset_value : integer := 0); port ( clk : in std_logic; -- original pulse_in : in std_logic; tick : in std_logic; updated : out std_logic; -- data IF pulse_width_in : in std_logic_vector(resolution-1 downto 0); pulse_width_out : out std_logic_vector(resolution-1 downto 0); dir : in std_logic; -- read => '1', write => '0' cs : in std_logic; -- chip select done : out std_logic; -- complete write / valid output reset : in std_logic); end component; component ServoDriver is generic ( resolution : integer := 8; reset_value : integer := 0); port ( clk : in std_logic; -- original pulse_out : out std_logic; tick : in std_logic; drive : in std_logic; -- data IF pulse_width_in : in std_logic_vector(resolution-1 downto 0); pulse_width_out : out std_logic_vector(resolution-1 downto 0); dir : in std_logic; -- read => '1', write => '0' cs : in std_logic; -- chip select done : out std_logic; -- complete write / valid output reset : in std_logic); end component; signal servo_cs : std_logic_vector(num_servo_observer+num_servo_observer-1 downto 0); signal servo_pw_in : std_logic_vector(servo_resolution-1 downto 0); signal servo_pw_out : std_logic_vector(servo_resolution-1 downto 0); signal servo_dir : std_logic; signal servo_done : std_logic; component DEMUX is generic( address_width : integer := 8; num_demux : integer range 0 to (2 ** address_width) := 8; lowest_address : integer range 0 to ((2 ** address_width) - num_demux) := 0); port( address : in std_logic_vector(address_width - 1 downto 0); cs_in : in std_logic; cs_out : out std_logic_vector(num_demux - 1 downto 0)); end component; component Bus2Periph is generic ( bus_width : natural := 8; periph_width : natural range (bus_width + 1) to natural'high := 16); port ( clk : in std_logic; transaction : in std_logic; data_in : in std_logic_vector(bus_width-1 downto 0); data_out : out std_logic_vector(bus_width-1 downto 0); dir : in std_logic; -- write register => '1', read register => '0' cs : in std_logic; -- chip select done : out std_logic; -- complete write / valid output periph_in : in std_logic_vector(periph_width-1 downto 0); periph_out : out std_logic_vector(periph_width-1 downto 0); periph_dir : out std_logic; -- write register => '1', read register => '0' periph_cs : out std_logic; -- chip select periph_done : in std_logic); -- complete write / valid output end component; signal i2c_2_servo_cs : std_logic; component SmallRegister is generic ( bits : integer := 8; reset_value : integer := 0); port ( clk : in std_logic; data_in : in std_logic_vector(bits-1 downto 0); data_out : out std_logic_vector(bits-1 downto 0); dir : in std_logic; -- write register => '1', read register => '0' cs : in std_logic; -- chip select done : out std_logic; -- complete write / valid output reset : in std_logic); end component; signal i2c_request1, i2c_request2 : std_logic; signal servo_done_buf : std_logic; begin Div1 : DividerN generic map(48) -- 48 MHz => 1 MHz port map( clk_in => clk, ce => '1', clk_out => clk_1M, tc => tc_1M); Div2 : DividerN generic map(20000) -- 1 MHz => 50 Hz port map( clk_in => clk, ce => tc_1M, clk_out => clk_50, tc => tc_50); Div3 : DividerN generic map(50) -- 50 Hz => 1 Hz port map( clk_in => clk, ce => tc_50, clk_out => clk_1); led_1 <= clk_1; process (reset, tc_50) begin if reset = '1' then por_counter <= (others => '1'); elsif tc_50'event and tc_50 = '1' and por_counter > conv_std_logic_vector(0, por_counter_length) then por_counter <= por_counter - 1; else por_counter <= por_counter; end if; end process; ext_reset_n <= not reset when por_counter = conv_std_logic_vector(0, por_counter_length) else '0'; process (clk) begin if clk'event and clk = '1' then if i2c_transaction = '1' then if servo_done_buf = '0' and servo_done = '1' then led_2 <= '1'; else null; end if; else led_2 <= '0'; end if; servo_done_buf <= servo_done; end if; end process; I2C_IF : i2c port map( clk => clk, reset => reset, scl => scl, sda => sda, address => i2c_address, valid_address => i2c_valid_address, data_in => i2c_data_in, data_out => i2c_data_out, transaction => i2c_transaction, dir => i2c_dir, request => i2c_request, ready => i2c_ready); i2c_valid_address <= '1' when i2c_address < conv_std_logic_vector(num_servo_observer + num_servo_driver + 1, 7) else '0'; --pd_servo_done : pulldown port map (servo_done); gen_servo_obs : for i in 0 to num_servo_observer-1 generate servo_obs : ServoObserver generic map (servo_resolution, 3000) port map ( clk => clk, pulse_in => pulse_in(i), tick => clk_1M, --updated => 'Z', pulse_width_in => servo_pw_in, pulse_width_out => servo_pw_out, dir => servo_dir, cs => servo_cs(i), done => servo_done, reset => reset); end generate; gen_servo_drv : for i in 0 to num_servo_driver-1 generate servo_drv : ServoDriver generic map (servo_resolution, 3000) port map ( clk => clk, pulse_out => pulse_out(i), tick => clk_1M, drive => clk_50, pulse_width_in => servo_pw_in, pulse_width_out => servo_pw_out, dir => servo_dir, cs => servo_cs(i + num_servo_observer), done => servo_done, reset => reset); end generate; i2c_DEMUX : DEMUX generic map( address_width => 7, num_demux => num_servo_observer + num_servo_driver, lowest_address => 0) port map( address => i2c_address, cs_in => i2c_2_servo_cs, cs_out => servo_cs); i2c_2_servo : Bus2Periph generic map( bus_width => 8, periph_width => servo_resolution) port map ( clk => clk, transaction => i2c_transaction, data_in => i2c_data_out, data_out => i2c_data_in, dir => not i2c_dir, cs => i2c_request1, done => i2c_ready, periph_in => servo_pw_out, periph_out => servo_pw_in, periph_dir => servo_dir, periph_cs => i2c_2_servo_cs, periph_done => servo_done); uut_sr: SmallRegister generic map (8, 16#00#) port map ( clk => clk, data_in => i2c_data_out, data_out => i2c_data_in, dir => not i2c_dir, cs => i2c_request2, done => i2c_ready, reset => reset); process(i2c_request, i2c_address) begin if (i2c_address < conv_std_logic_vector(num_servo_observer + num_servo_driver, 7)) then i2c_request1 <= i2c_request; i2c_request2 <= '0'; else i2c_request1 <= '0'; i2c_request2 <= i2c_request; end if; end process; end Behavioral;