title: Encoder Debounce VHDL
body: <p>For practice, I attempted to make a VHDL code to run Rotary encoder hardware. It was full with debounce, quadrature decoder and an up/down counter codes. </p>
  
  <p>Unfortunately, when running simulation with a testbench, my results were disappointing so I decided that each block needs to be analysed separately. For the debounce code, I created a symbol file and produced the circuit below</p>
  
  <p><a href="https://i.stack.imgur.com/2hTSr.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/2hTSr.jpg" alt="schematic setup for simulating the debounce block"></a>
  (clickable)</p>
  
  <p>While attempting to debounce the testbench signal in simulation, I found out that my results were terrible so I believe I am missing something.</p>
  
  <p><a href="https://i.stack.imgur.com/eCmQc.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/eCmQc.jpg" alt="modelsim simulation using debounce testbench values"></a>
  (clickable)</p>
  
  <p>The VHDL code for the encoder block can be found here :</p>
  
  <pre><code>LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  USE ieee.std_logic_unsigned.all;
  
  ENTITY debounce_a IS
  GENERIC( counter_size  :  INTEGER := 8); --counter size (8 bits gives 51.6 us with 5MHz clock)
  PORT(
  clk     : IN  STD_LOGIC;  --input clock
  bounce_a  : IN  STD_LOGIC;  --input signal to be debounced
  result  : OUT STD_LOGIC); --debounced signal
  END debounce_a;
  
  ARCHITECTURE logic OF debounce_a IS
  SIGNAL flipflops   : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops
  SIGNAL counter_set : STD_LOGIC;                    --sync reset to zero
  SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS =&gt; '0'); --counter output
  BEGIN
  
  counter_set &lt;= flipflops(0) xor flipflops(1);   --determine when to start/reset counter
  
  PROCESS(clk) -- occurs within a clock event
  BEGIN
  IF(clk'EVENT and clk = '1') THEN -- can be rising_edge(clk)
  flipflops(0) &lt;= bounce_a;                   -- adresses the signal as a set value
    flipflops(1) &lt;= flipflops(0);
    If(counter_set = '1') THEN                  --reset counter because input is changing
      counter_out &lt;= (OTHERS =&gt; '0');           --set all bits to '0'
    ELSIF(counter_out(counter_size) = '0') THEN --stable input time is not yet met
      counter_out &lt;= counter_out + 1;
    ELSE                                        --stable input time is met
      result &lt;= flipflops(1);
    END IF;    
  END IF;
  END PROCESS;
  END logic;
  </code></pre>
  
  <p>It could be filled to the brim with unwanted logic because I had a limited idea of what I was doing and I took a friends general debounce code and edited it to try and fit my specific needs. </p>
  
  <p>If anything extra is needed I am willing to provide. I feel like it's a pretty basic error but I just need any sort of help.</p>
  
  <p>Here is a look on the testbench code that I used if that helps identify toggling properties : </p>
  
  <pre><code>   LIBRARY ieee;                                               
     USE ieee.std_logic_1164.all;                                
  
     ENTITY decodeblock_vhd_tst IS
     END decodeblock_vhd_tst;
     ARCHITECTURE decodeblock_arch OF decodeblock_vhd_tst IS
     -- constants   
     CONSTANT clk_period : TIME := 20 ns;
     CONSTANT num_clk_cycles : INTEGER := 100;                                              
     -- signals                                                   
       SIGNAL b_Input : STD_LOGIC;
       SIGNAL b_output : STD_LOGIC;
       SIGNAL CLOCK_50 : STD_LOGIC := '0'; 
       COMPONENT decodeblock
   PORT (
   b_Input : IN STD_LOGIC;
   b_output : OUT STD_LOGIC;
   CLOCK_50 : IN STD_LOGIC
   );
       END COMPONENT;
       BEGIN
  i1 : decodeblock
  PORT MAP (
      -- list connections between master ports and signals
  b_Input =&gt; b_Input,
  b_output =&gt; b_output,
  CLOCK_50 =&gt; CLOCK_50
  );
      init : PROCESS                                               
      -- variable declarations                                     
      BEGIN  
      b_input &lt;= '0',
         '1' after 1.1 ns,
         '0' after 2.9 ns,                                                     
         '1' after 5.1 ns,
         '0' after 7.6 ns, 
         '1' after 9.9 ns, 
         '0' after 12.5 ns, 
         '1' after 15.4 ns, 
         '0' after 18.6 ns, 
         '1' after 22.1 ns, 
         '0' after 25.9 ns, 
         '1' after 29.7 ns, 
         '0' after 33.8 ns, 
         '1' after 38.2 ns;
  
          -- variable declarations                                                                                            
          for i in 1 to num_clk_cycles loop
          CLOCK_50 &lt;= not CLOCK_50;          
          wait for clk_period/2; 
          CLOCK_50 &lt;= not CLOCK_50;     
          wait for clk_period/2;      
          end loop;                       
          WAIT;                                                    
          END PROCESS init;                                          
          always : PROCESS                                              
          -- optional sensitivity list                                  
          -- (        )                                                 
          -- variable declarations                                      
          BEGIN                                                         
      -- code executes for every event on sensitivity list  
          WAIT;                                                        
          END PROCESS always;                                          
          END decodeblock_arch;
  </code></pre>