Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16629 Discussions

Implementing User-Defined "Wait For" time

Altera_Forum
Honored Contributor II
2,588 Views

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.
0 Kudos
18 Replies
Altera_Forum
Honored Contributor II
994 Views

Well, for a start, you cannot use wait statements in a process with a sensitivity list. This is a vhdl restriction, not a quartus one. 

 

secondly, wait statements are not synthesisable. What circuit do you expect from a wait statement. You're going to need some form of counter (and as a hint, it will not involve a loop).
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

I was unaware of the restriction. I'm trying to piecemeal things together with what I see on the web and a VHDL book I have written by a Peter Ashenden. It seems Ashenden's book is popular, but I don't always follow his syntatical examples. 

 

I'm trying to develop an VHDL entity to roughly simulate the bounces that a physical relay switch exhibits before it latches onto a changed state. This is something that the powers that be at where I work want, so I was tasked to implement this. 

 

In other words, I want to generate a pulse waveform for a user-specified time for each pulse outputted before the output goes to its final complementary state. If I understand you correctly, you're suggesting that I use a countdown timer. If so, I'm not visualizing how this all works out. 

 

So I'm looking at an example from a website called VHDL Guru and they have an example of a 4-bit Johnson counter, but I'm not sure of is how many bits should be sufficient for a counter to gauge time duration? I was told that the range of time I may want to consider would be 0.1 to 10ms.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

Is this a block to be synthesised, or just a simulation model? It can make a real difference to the code, because waits might be very appropriate for a model.  

 

for the counter size, you know your clock speed, and you know how long you need to wait, so n bits can be easily calculated.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- Quote Start ---  

So I'm looking at an example from a website called VHDL Guru and they have an example of a 4-bit Johnson counter, but I'm not sure of is how many bits should be sufficient for a counter to gauge time duration? I was told that the range of time I may want to consider would be 0.1 to 10ms. 

--- Quote End ---  

 

 

I'd never heard of a Johnston counter but a quick google shows it's just a massive shift register. 

 

If you've a 10MHz clock you'll need ~ 100,000 bits in your counter for 10ms. 

 

Why not just use a 17 bit binary counter to trigger transitions? 

 

 

 

Nial
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- Quote Start ---  

 

I'll look into a standard binary counter. If I may ask, why 17-bits? 

 

--- Quote End ---  

 

 

Because, at 10MHz, 17 bits is all you need to wait for 10ms with a 10MHz clock.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- Quote Start ---  

Is this a block to be synthesised, or just a simulation model? It can make a real difference to the code, because waits might be very appropriate for a model.  

 

for the counter size, you know your clock speed, and you know how long you need to wait, so n bits can be easily calculated. 

--- Quote End ---  

 

 

This is something that is going into an actual test bench and talking to other subsystems via a C# application. 

 

I don't know what my clock speed is nor how long I should wait. I do realize thought that ns is overkill in trying to simulate the bounce / jitter of a relay switch when it flips. I'm thinking ms should be sufficient.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- Quote Start ---  

This is something that is going into an actual test bench and talking to other subsystems via a C# application. 

I don't know what my clock speed is nor how long I should wait. I do realize thought that ns is overkill in trying to simulate the bounce / jitter of a relay switch when it flips. I'm thinking ms should be sufficient. 

--- Quote End ---  

 

 

Can you outline your requirements and we can try to advise on the details. 

 

What clock are you using? 

How many times do you need the input to bounce? 

Is each bounce the same period (or do they vary)? 

How do you define the periods? 

 

 

Nial
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- Quote Start ---  

Can you outline your requirements and we can try to advise on the details. 

 

What clock are you using? 

How many times do you need the input to bounce? 

Is each bounce the same period (or do they vary)? 

How do you define the periods? 

 

 

Nial 

--- Quote End ---  

 

 

I was just told a 10Mhz Clock is what they want to use. 

 

The input bounce will be anywhere from 0 to 10 bounces. Each with the same period. Periods are defined by user input... I'm assuming it will be in time in units of ms.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

Would it be better if I just take whatever the 16-bit input is and store it to a variable?  

 

So, if I got an input of say 250ms (0000 0000 1111 1010), store the binary input into a variable, run a process with an infinite loop and compare the value of a temp variable against the binary value... if it doesn't match, then the temp variable's value is incremented with a 1. Repeat until bit patterns match... once matched, it's assumed 250ms has elapsed.  

 

Is this correct? Or am I seriously overlooking something?
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- 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?
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

Altera provided this for the stratix 2 - it should still be releavent 

http://www.altera.co.uk/literature/manual/stx_cookbook.pdf
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- 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 ---  

0 Kudos
Altera_Forum
Honored Contributor II
994 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
994 Views

 

--- 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.
0 Kudos
Reply