The Xilinx XC95108 Micro-step controler



----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:41:03 02/25/2006 
-- Design Name:    Dual axis drive controler
-- Module Name:    controler - Behavioral 
-- Project Name: 
-- Target Devices: XC95108
-- 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;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity controler is
    Port (
           rate_clk     : in  STD_LOGIC;    -- high speed step genarator clock
           reg_cl       : in  STD_LOGIC;    -- data & control register read/write clock
           sel_0        : in  STD_LOGIC;    -- chip selects
           sel_1        : in  STD_LOGIC;    --
           rs_0         : in  STD_LOGIC;    -- register selects
           rs_1         : in  STD_LOGIC;    --
           rd_wrt       : in  STD_LOGIC;    -- data bus direction & tri-state control
           data_bus     : inout  STD_LOGIC_VECTOR (7 downto 0);
           rate_out     : out  STD_LOGIC;   -- for hardware testing
           step         : out  STD_LOGIC;   -- step pulse
           dir          : out  STD_LOGIC);  -- step direction
end controler;

architecture Behavioral of controler is
       constant RUN            : std_logic := '1';
       constant UP             : std_logic := '1';
       constant ZERO           : std_logic := '1';

       signal  rate_cntr       : std_logic_vector(23 downto 0);
       signal  rate_data       : std_logic_vector(23 downto 0);
       signal  rate_hold_0     : std_logic_vector(7 downto 0);
       signal  rate_hold_1     : std_logic_vector(7 downto 0);
       signal  rate_z0         : std_logic;
       signal  rate_z1         : std_logic;
       signal  rate_zero       : std_logic;
       signal  sel             : std_logic;
       signal  step_cnt        : std_logic_vector(15 downto 0);
       signal  cntl_reg        : std_logic_vector(2 downto 0);
--                                      (0) = run / halt
--                                      (1) = zero step_cnt
--                                      (2) = step direction
       signal  bus_in          : std_logic_vector(7 downto 0);
       signal  bus_out         : std_logic_vector(7 downto 0);

begin

       data_bus <= bus_out when (rd_wrt = '0') else (others => 'Z');
       bus_in  <= data_bus when (rd_wrt = '1') else (others => 'X');

       dir <= cntl_reg(2);

       step <= rate_z1;
        
       sel <= sel_0 and not sel_1;
        
       rate_z0 <=
            rate_cntr(0) or rate_cntr(1) or rate_cntr(2) or rate_cntr(3) or
            rate_cntr(4) or rate_cntr(5);
            
       rate_z1 <= rate_cntr(6) or rate_cntr(7) or
            rate_cntr(8)  or rate_cntr(9)  or rate_cntr(10) or rate_cntr(11)or
            rate_cntr(12) or rate_cntr(13) or rate_cntr(14) or rate_cntr(15)or
            rate_cntr(16) or rate_cntr(17) or rate_cntr(18) or rate_cntr(19)or
            rate_cntr(20) or rate_cntr(21) or rate_cntr(22) or rate_cntr(23);
         
        rate_zero <= rate_z0 or rate_z1;

        rate_out <= rate_zero; -- for hardware testing

        process (rate_clk) -- step rate generator
        begin
            if (rate_clk'event and (rate_clk = '1')) then
               if( rate_zero = '0' ) then
                  rate_cntr <= rate_data;
               else
                  rate_cntr <= rate_cntr - 1;
               end if;
            end if;
        end process;

        process (rate_z1, cntl_reg(1)) -- step counter
        begin
            if (cntl_reg(1) = ZERO) then
               step_cnt <= (others => '0');
            else
               if (rate_z1'event and (rate_z1 = '1') and (cntl_reg(0) = RUN)) then
                  if( cntl_reg(2) = UP ) then
                     step_cnt <= step_cnt + 1;
                  else
                     step_cnt <= step_cnt - 1;
                  end if;
               end if;
            end if;
        end process;

        process (reg_clk) -- load data latches via input bus
        begin
           if (reg_clk'event and (reg_clk = '1') and (sel = '1')) then
                if (rs_1 = '0') then
                    if (rs_0 = '0') then
                        rate_hold_0 <= bus_in;
                    else
                        rate_hold_1 <= bus_in;
                    end if;
                else
                    if (rs_0 = '0') then
                        rate_data(23 downto 16) <= rate_hold_0;
                        rate_data(15 downto 8) <= rate_hold_1;
                        rate_data(7 downto 0) <= bus_in;
                    else
                        cntl_reg <= bus_in(2 downto 0);
                    end if;
                end if;
           end if;
        end process;

        process (reg_clk, sel) -- the step count register output logic
        begin
           if (reg_clk'event and (reg_clk = '1') and (sel = '1')) then
              if (rs_1 = '0') then
                 if (rs_0 = '0') then
                    bus_out <= step_cnt(15 downto 8);
                 else
                    bus_out <= step_cnt(7 downto 0);
                 end if;
              end if;
           end if;
        end process;

end Behavioral;