Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Implementing User-Defined "Wait For" time

Disclaimer: I'm a noob

I'm trying to implement an entity which takes as an input a 16-bit binary number called bounceWidth( in std_ulogic_vector(15 downto 0)) which will represent the time in which a pulse wave will last. In my behavioral architecture, I have a variable called intWidth ( in std_ulogic_vector(15 downto 0)) and another one called pulseWidth ( time ).

My desire is to convert the input into a valid form of time expressed in ns so as to be used with the "wait for" command.

Below is what I'm doing that Quartus doesn't like:

--- Quote Start ---

library ieee;

use ieee.numeric_std.all;

use ieee.std_logic_1164.all;

entity bounce_processor is

generic (prop_delay: Time:= 10ns);

port (clock: in std_logic;

bouncewidth: in std_ulogic_vector(15 downto 0);

bounceCount: in std_ulogic_vector(7 downto 0);

opcode: in std_ulogic_vector(2 downto 0);

start: in bit;

output: out bit);

end bounce_processor;

architecture behavioral of bounce_processor is

variable intwidth : integer range 0 to 65535;

variable intCount : natural range 0 to 10;

variable starting_output : bit;

variable pulsewidth : time;

begin

process(clock)

begin

if (rising_edge(clock) and start = '1') then

intwidth := to_integer(bouncewidth);

pulsewidth := time(intwidth);

intCount := to_integer(bounceCount);

starting_output := output;

if opcode = "000" then

output <= '0';

elsif opcode = "001" then

for i in 0 to intCount loop

output <= not output;

wait for pulsewidth ns;

end loop;

if starting_output = '1' then

output <= 0;

else

output <= 1;

end if;

elsif opcode = "010" then

output <= '1';

elsif opcode = "011" then

output <= '0';

end if;

end if;

end process;

end behavioral;

--- Quote End ---

Any help would be greatly appreciated.

18 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    That sounds very much correct if you were writing some C. But remember, this is VHDL (VHSIC Hardware Description Language), so you cannot just write a load of programming instructions and expect it to work. VHDL describes a logic circuit, not a load of instructions to execute in order (but it will also do that, but only in a simulation model - but dont think like this). You need to understand what circuit you're trying to create before writing any code. There is a lot of VHDL that is not synthesisable. I suggest you learn about the VHDL templates for synthesisable constructs (I suggest the Quartus manual, that contains all the templates you need). Or even a good textbook.

    I suggest you start on paper, and draw the circuit out. When you know what the circuit should be, then you can write the HDL.

    --- Quote End ---

    That was what I was afraid of. I can draw out a circuit, but then I seem to have problems taking the input and using it for something such as binary math... sounds like I have to implement an ALU. Or partially instead of telling VHDL to do binary math.

    I've been using Ashenden's "The Student's Guide to VHDL". The examples / syntax are sometimes hard to follow. Do you have a cookbook or "learn by example" book you'd recommend?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It is all verilog, but the theory is the same (and reading verilog would be more up your street if you're a programmer)

    Also study the coding guidelines in the quartus manual. Lots of code examples and templates in there.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    It is all verilog, but the theory is the same (and reading verilog would be more up your street if you're a programmer)

    Also study the coding guidelines in the quartus manual. Lots of code examples and templates in there.

    --- Quote End ---

    For what it's worth, this is the behavioral model of what I'm trying to do (I've got a block diagram below if it's easier to follow):

    --- Quote Start ---

    architecture behavioral of bounce_processor is

    signal tempQ: std_logic;signal lastIntervalValue: std_logic_vector(4 downto 0);

    begin

    process(clock, clr)

    begin

    tempQ <= d;

    lastIntervalValue <= interval;

    if(clr = '1') then

    q <= '0';

    elsif (rising_edge(clock) and start = '1') then

    if opcode = "000" then

    q <= '0';

    elsif opcode = "001" then

    --initial bounce pulse when kicked off

    q <= not tempq;

    tempq <= not tempq;

    while (interval > "00000") loop

    -- complement pulse only when interval value changes

    if (interval /= lastintervalvalue) then

    q <= not tempq;

    tempq <= not tempq;

    lastintervalvalue <= interval;

    end if;

    end loop;

    -- ensure final output is a complent of d regardless of pulses

    q <= not d;

    elsif opcode = "010" then

    q <= '1';

    elsif opcode = "011" then

    q <= '0';

    end if;

    end if;

    end process;

    end behavioral;

    --- Quote End ---

    https://www.alteraforum.com/forum/attachment.php?attachmentid=7394
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If its just a behavioural model, then waits and the like are fine and encouraged to improve sim speed. But in you code you have no wait in your while loop, so it will be an infinite loop in 0 time if interval is greater than 0 when it enters the loop. This is because of the mechanics of vhdl. Signals are only updated when a process suspends eg on a wait.

    there are other unusual things in you code, like updating tempq and last interval value outside of the reset or clock branches, so the will be assigned on any change of clock or clear.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    If its just a behavioural model, then waits and the like are fine and encouraged to improve sim speed. But in you code you have no wait in your while loop, so it will be an infinite loop in 0 time if interval is greater than 0 when it enters the loop. This is because of the mechanics of vhdl. Signals are only updated when a process suspends eg on a wait.

    there are other unusual things in you code, like updating tempq and last interval value outside of the reset or clock branches, so the will be assigned on any change of clock or clear.

    --- Quote End ---

    Good points.

    Perhaps I should have done it this way?:

    --- Quote Start ---

    architecture behavioral of bounce_processor is

    signal tempQ: std_logic;

    signal lastIntervalValue: std_logic_vector(4 downto 0);

    begin

    tempq <= d;

    lastintervalvalue <= interval;

    process(clock, clr)

    begin

    if(clr = '1') then

    q <= '0';

    elsif (rising_edge(clock) and start = '1') then

    if opcode = "000" then

    q <= '0';

    elsif opcode = "001" then

    --initial bounce pulse when kicked off

    q <= not tempQ;

    tempQ <= not tempQ;

    if (interval > "00000") then

    -- complement pulse only when interval value changes

    if (interval /= lastIntervalValue) then

    q <= not tempQ;

    tempQ <= not tempQ;

    lastIntervalValue <= interval;

    end if;

    -- ensure final output is a complent of d regardless of pulses

    elsif (interval = "00000") then

    q <= not d;

    end if;

    elsif opcode = "010" then

    q <= '1';

    elsif opcode = "011" then

    q <= '0';

    end if;

    end if;

    end process;

    end behavioral;

    --- Quote End ---

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    possibly - what does your testbench say?

    as a small not, you shouldnt really AND anything with the clock - it might create you some async logic with the clock.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    possibly - what does your testbench say?

    as a small not, you shouldnt really AND anything with the clock - it might create you some async logic with the clock.

    --- Quote End ---

    I'll remember to remove the ANDing.

    I haven't had a chance to do a testbench yet. I've recently discovered the Mega-Wizard plug-in feature and have replaced everything with things generated from that. The only part I've not converted structurally is the actual "bouncing" portion of the circuit.

    My thought is to use a 4-to-2 MUX.... but I'm trying to think about how I can switch my overall output to come from the MUX or from a "bouncer" which takes input from the MUX when the MUX Sel is "01" (Bounce the input).

    For bouning, I guess I'm needing to use an inverter and then a latch.... maybe something SR instead? Either way, there seems to be an abundance of debouncing stuff on VHDL but nothing out there to simulate relay bounces via VHDL.