vhdl prescaled counter with pulsed output

Thread Starter

djstar

Joined Jan 26, 2008
39
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 :)


Rich (BB code):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity counter is
port (
    pushbutton: in std_logic;
    SW: in std_logic_vector(7 downto 0); -- user select switches
    RESET: in std_logic;
    OUTPUT: out std_logic;
    LEDS: out std_logic_vector(8 downto 0) -- un used leds

);
end counter;

architecture Behavioral of counter is
signal COUNTER: std_logic;
signal PRESCALER: std_logic_vector(7 downto 0);
signal SWITCH: std_logic_vector(7 downto 0);
begin

CounterProcess: process(RESET, pushbutton)
begin
    if rising_edge(pushbutton) then
        if RESET = '0' then
            PRESCALER <= (others => '0');
            COUNTER <= '0';
        else        
            if PRESCALER < SWITCH - 1 then
            PRESCALER <= PRESCALER + 1;
            else
                PRESCALER <= (others => '0');
                COUNTER <= '1';
                end if;
        end if;
    end if;
end process;

LEDS <= (others => '0'); -- Turn off all unsed LEDs
SWITCH <= SW; -- Asign switch value into a signal 
OUTPUT <= COUNTER; 

end Behavioral;
 

Brownout

Joined Jan 10, 2012
2,390
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.
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.
 

Thread Starter

djstar

Joined Jan 26, 2008
39
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.
 

Brownout

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

process(clk, reset)
signal edge std_logic;
...
edge <= COUNTER;
if(COUNTER=1 and edge=0) //detecting rising edge of "COUNTER"
....
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.
 

Thread Starter

djstar

Joined Jan 26, 2008
39
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?

Rich (BB code):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity mon_prescale is

	port (
		clk: in std_logic;
		monitor: in std_logic;
		mon_prescale: out std_logic
		
		);
		
end mon_prescale;

architecture Behavioral of mon_prescale is
	signal mon_delay: std_logic;
	
begin

	CounterProcess: process(clk)
	begin
		mon_prescale <= monitor and not mon_delay;
	
		if rising_edge(clk) then
			mon_delay <= monitor;
		end if;
							
	end process;
	
	

end Behavioral;
 

Brownout

Joined Jan 10, 2012
2,390
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.
 
Top