vhdl prescaled counter with pulsed output

Discussion in 'Embedded Systems and Microcontrollers' started by djstar, Feb 15, 2014.

  1. djstar

    Thread Starter Active Member

    Jan 26, 2008
    37
    0
    I'm a analogue engineer trying to learn VHDL for a project i have. the project is to count the rising edge of a input signal and prescale the counts to a smaller number. for example if there are 8 counts on the input then 1 count will be outputted. the prescale value can be user changed. i have managed to work the prescale part out but at pressent the output will constantly go high .

    what i am trying to do is once the prescale count is = to the user selected value then a 1us pulse is outputted rather then the constant logic high.

    i have a 50 MHz clk, so the output needs to stay high for 50 clock cycles, however i am unsure how to to do this.

    i am using a DE0 development board that has debounced switches so there is no need for a debounce circuit.

    any help would be great :)


    Code ( (Unknown Language)):
    1. library IEEE;
    2. use IEEE.STD_LOGIC_1164.ALL;
    3. use IEEE.STD_LOGIC_ARITH.ALL;
    4. use IEEE.STD_LOGIC_UNSIGNED.ALL;
    5.  
    6.  
    7. entity counter is
    8. port (
    9.     pushbutton: in std_logic;
    10.     SW: in std_logic_vector(7 downto 0); -- user select switches
    11.     RESET: in std_logic;
    12.     OUTPUT: out std_logic;
    13.     LEDS: out std_logic_vector(8 downto 0) -- un used leds
    14.  
    15. );
    16. end counter;
    17.  
    18. architecture Behavioral of counter is
    19. signal COUNTER: std_logic;
    20. signal PRESCALER: std_logic_vector(7 downto 0);
    21. signal SWITCH: std_logic_vector(7 downto 0);
    22. begin
    23.  
    24. CounterProcess: process(RESET, pushbutton)
    25. begin
    26.     if rising_edge(pushbutton) then
    27.         if RESET = '0' then
    28.             PRESCALER <= (others => '0');
    29.             COUNTER <= '0';
    30.         else        
    31.             if PRESCALER < SWITCH - 1 then
    32.             PRESCALER <= PRESCALER + 1;
    33.             else
    34.                 PRESCALER <= (others => '0');
    35.                 COUNTER <= '1';
    36.                 end if;
    37.         end if;
    38.     end if;
    39. end process;
    40.  
    41. LEDS <= (others => '0'); -- Turn off all unsed LEDs
    42. SWITCH <= SW; -- Asign switch value into a signal
    43. OUTPUT <= COUNTER;
    44.  
    45. end Behavioral;
     
  2. Brownout

    Well-Known Member

    Jan 10, 2012
    2,375
    998
    Just count 50 clocks

    process(clk, reset)
    ...
    if(rising_edge (clk))
    if(COUNTER = 1)
    count <= count + 1;

    You will probably need to make this the same process as the one you already have. It should all be clocked anyway.
    ...

    if(count=50)
    COUNTER <= 0;

    etc.
     
  3. djstar

    Thread Starter Active Member

    Jan 26, 2008
    37
    0
    Thanks for the reply, i'm still a bit confused on how to output the pulse. i can see what is happening with the code you have written but if i add the rising_edge (clk) then i have 2 rising edge statements in one process and i cant compile it.

    im guessing i need two processes but im unsure how to get information from one process into another such as when the output goes high start the next process which will be the 1us pulse.
     
  4. Brownout

    Well-Known Member

    Jan 10, 2012
    2,375
    998
    The correct way to get a rising edge from signals other than clocks is to use a clocked edge detector:

    The signal "edge" will go high one clock period after COUNTER, and so the "if" statement will evaluate to 'true' and fire the conditional code,thus you have created an edge detector.

    Then put all your code into a signle process. Never use rising edge of a non-clock signal in your process. Always, always use a clock. All design is synchronous these days.
     
  5. djstar

    Thread Starter Active Member

    Jan 26, 2008
    37
    0
    I have managed to get the edge detection working as your see from the code below. The output of the detector is "mon_prescale" wich goes high for only one clock pulse.

    im not sure how to add the counter bit into the process. when I add the2 then if.. it throws up an error?

    Code ( (Unknown Language)):
    1.  
    2. library IEEE;
    3. use IEEE.STD_LOGIC_1164.ALL;
    4. use IEEE.STD_LOGIC_ARITH.ALL;
    5. use IEEE.STD_LOGIC_UNSIGNED.ALL;
    6.  
    7.  
    8. entity mon_prescale is
    9.  
    10.     port (
    11.         clk: in std_logic;
    12.         monitor: in std_logic;
    13.         mon_prescale: out std_logic
    14.        
    15.         );
    16.        
    17. end mon_prescale;
    18.  
    19. architecture Behavioral of mon_prescale is
    20.     signal mon_delay: std_logic;
    21.    
    22. begin
    23.  
    24.     CounterProcess: process(clk)
    25.     begin
    26.         mon_prescale <= monitor and not mon_delay;
    27.    
    28.         if rising_edge(clk) then
    29.             mon_delay <= monitor;
    30.         end if;
    31.                            
    32.     end process;
    33.    
    34.    
    35.  
    36. end Behavioral;
    37.  
     
  6. Brownout

    Well-Known Member

    Jan 10, 2012
    2,375
    998
    Post the code and the error. Sorry, I've been travelling last few days and wasn't able to get back to this.

    PS: the signal "mon_prescale" should be assigned within the rising edge(clk) block. Assign all signals thusly in a clocked process.
     
Loading...