library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; --use ieee.std_logic_unsigned.all; --USE ieee.std_logic_arith.all; entity clk50MHz is Port (clk,data,A_In,B_In,Reset : in std_logic; CSpin,clk_out : out bit; up_down :buffer std_logic; data_out : out std_logic_vector(11 downto 0); Dir : buffer std_logic); end clk50MHz; architecture Behavioral of clk50MHz is signal spi: std_logic:='1'; signal temporal: bit := '0' ; signal counter : integer range 0 to 170 ; signal Chipselect: bit :='1'; signal spiposition: unsigned(11 downto 0):= (others => '0'); SIGNAL Last_A, Last_B :std_logic; SIGNAL Current_A, Current_B : std_logic; signal quad: std_logic:='0'; signal count: unsigned(11 downto 0) := (others => '0'); begin --creating a counter to which spi events take place with triggers. spi_clock: process (clk) begin if (rising_edge(clk) and clk = '1') then counter <= counter + 1; end if; end process; --my bit banged spi to request a reading from encoder, only storing 12 LMSB's, -- tested and works perfect, 3.7us between CS low and position to pins. time_case: process (counter,spi,count, a_in, b_in,spiposition,clk, data) begin if spi='1' then --only needs to run 1 time, once absolute position is obtained it's --angle needs to be passed down to quadrature code to modify from there. case counter is when 0 => Chipselect<='0'; when 18 => temporal <='1'; when 24 => temporal <='0'; when 28 => temporal <='1'; when 32 => temporal <='0'; when 36 => temporal <='1'; when 40 => temporal <='0'; when 44 => temporal <='1'; when 48 => temporal <='0'; when 52 => temporal <='1'; when 56 => temporal <='0'; spiposition(11)<= data; when 60 => temporal <='1'; when 64 => temporal <='0'; spiposition(10)<= data; when 68 => temporal <='1'; when 72 => temporal <='0'; spiposition(9)<= data; when 76 => temporal <='1'; when 80 => temporal <='0'; spiposition(8)<= data; when 84 => temporal <='1'; when 88 => temporal <='0'; spiposition(7)<= data; when 92 => temporal <='1'; when 96 => temporal <='0'; spiposition(6)<= data; when 100 => temporal <='1'; when 104 => temporal <='0'; spiposition(5)<= data; when 108 => temporal <='1'; when 112 => temporal <='0'; spiposition(4)<= data; when 116 => temporal <='1'; when 120 => temporal <='0'; spiposition(3)<= data; when 124 => temporal <='1'; when 128 => temporal <='0'; spiposition(2)<= data; when 132 => temporal <='1'; when 136 => temporal <='0'; spiposition(1)<= data; when 140 => temporal <='1'; when 144 => temporal <='0'; spiposition(0)<= data; when 152 => Chipselect<='1'; when 156 => spiposition<=spiposition(11 downto 0); when 158 => count<=unsigned(count)+unsigned(spiposition); when 160 => spi <='0'; when others=>null; end case; end if; count<=count; end process; process (clk, Reset) --had this example i found also running very smooth, observed with --logic analyzer, there was also a reset tied to encoder Index pin -- to clear count to zero if it had not already over flowed back to 0. begin if (clk'event and clk = '1') then Last_A <= Current_A; Last_B <= Current_B; Current_A <= A_In; Current_B <= B_In; end if; --ive spent several hours a day here, no luck getting a complete --compile, always "removing unused inputs 'data', or 'unable to synthesize count. end process; quadrature: process(clk,spi,count) begin if spi='0' then IF rising_edge(clk) THEN IF(up_down = '1') THEN IF(Dir='1')THEN count <= count + 1; ELSIF(up_down = '0') THEN IF(Dir='0')THEN count <= count - 1; END IF; END IF; END IF; END IF; end if; data_out <=std_logic_vector (count) ; end process; up_down <= (Current_A xor Last_A) xor (Current_B xor Last_B); Dir <= Current_A xor Last_B; CSpin <= Chipselect; clk_out <= temporal; end Behavioral;