new to VHDL: concurrent execution question

B

bhavanireddy

While I was trying to generate a clock signal in the test bench I
noticed a strange behavior

signal clk : std_logic_vector := '0';
begin
clk <= not clk after 5 ns;

The above code works fine but the below code generates only 'U' in the
wave form.

signal clk : std_logic_vector';
begin
clk <= '0';
clk <= not clk after 5 ns;
I thought changing clk <= '0' to clk <= '0' after 2 ns would work but
it didn't. I am new to VHDL and appreciate if anyone explains this.

I know concurrent statements execute whenever any of the RHS signal or
variable changes value but what will happen if we have concurrent
statement like x <= '0' or x <= '0' after 5 ns; where '0' is a literal
value. When will it execute?

BReddy
 
K

KJ

I know concurrent statements execute whenever any of the RHS signal or
variable changes value but what will happen if we have concurrent
statement like x <= '0' or x <= '0' after 5 ns; where '0' is a literal
value. When will it execute?

At t=0.

KJ
 
D

David R Brooks

KJ said:
Remember, concurrent statements can be thought of as shorthand for
processes (I know purists won't like this :)
When you write a concurrent statement, you are creating a process, with
a sensitivity list including all signals mentioned on the right-hand
side of the assignment.
In your example, there are no such signals, so your "process" executes
once only, at the start, as KJ says.
 
B

Brad Smallridge

signal clk : std_logic_vector';
begin
clk <= '0';
clk <= not clk after 5 ns;

Both of these statement will try to schedule an
event for the clk signal. The first one is clear.
The second one tries to schedule clk as not clk
but clk is not known yet because all the concurrent
statements have to be resolved before the scheduled
events take place, which is where the Undefined
comes from. If you think of VHDL concurrent statements
as being scheduled, then the problem will be clearer.

I would be interested in the time from 0 to 5ns. Is that
'U' or '0'?

Brad Smallridge
Ai Vision
 
D

Duane Clark

The above code works fine but the below code generates only 'U' in the
wave form.

signal clk : std_logic_vector';
begin
clk <= '0';
clk <= not clk after 5 ns;

Do this:
clk <= '0';
wait for 1 ns;
clk <= not clk after 5 ns;

That will do what you are expecting. I'll leave it as an exercise to
figure out why ;)
 
J

Jonathan Bromley

Do this:
clk <= '0';
wait for 1 ns;
clk <= not clk after 5 ns;

That will do what you are expecting.

Won't work, because your three assignments need to be in a process.
See my other response.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
J

Jonathan Bromley

While I was trying to generate a clock signal in the test bench I
noticed a strange behavior

signal clk : std_logic_vector := '0';

oops, I think you mean "std_logic"
begin
clk <= not clk after 5 ns;

The above code works fine but the below code generates only 'U' in the
wave form.

signal clk : std_logic_vector';
begin
clk <= '0';
clk <= not clk after 5 ns;
I thought changing clk <= '0' to clk <= '0' after 2 ns would work but
it didn't. I am new to VHDL and appreciate if anyone explains this.

KJ's response is right, but incomplete.

You have written two statements in your *architecture*,
thereby creating two processes. Both processes are driving
"clk". The first one, clk <= '0', represents a driver that
drives '0' on to clk from time 0 onwards, and never changes.
The second one,
clk <= not clk after 5 ns;
represents a driver too. The two drivers will conflict.

The right way to do it is to write a single process:

process
begin
clk <= '0';
wait for 5 ns;
clk <= '1';
wait for 5 ns;
end process;

Or something similar - there are many ways to do it.
Be aware that this clock generator will never stop, so you
will need to find some other way to stop your simulation
or else it will run forever.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
J

Jonathan Bromley

Remember, concurrent statements can be thought of as shorthand for
processes (I know purists won't like this :)
When you write a concurrent statement, you are creating a process, with
a sensitivity list including all signals mentioned on the right-hand
side of the assignment.

Purists *do* like it, because it's exactly true! Concurrent
assignments are PRECISELY shorthand for a process
containing exactly that assignment statement, with a
complete sensitivity list. Conditional and selected concurrent
assignments are likewise shorthand for processes,
but in this case the process contains an "if" or "case" statement.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
B

bhavanireddy

Thanks for all the responses.

If clk <= 0 at t=0 what's wrong with clk <= not clk after 5 ns?
Shoudn't clk be '1' (not clk) at t=5 because clk was set to '0' at
t=0?

I am sorry if it is a BASIC Q. I am new to vhdl.

Thanks again for all
 
M

Mike Treseler

If clk <= 0 at t=0 what's wrong with clk <= not clk after 5 ns?
Shoudn't clk be '1' (not clk) at t=5 because clk was set to '0' at
t=0?

The value is not the problem.
Each process is like a gate,
and you are shorting the outputs together.
The fewer processes, the better.
Try Jonathan's single process solution.

-- Mike Treseler
 
P

Peter

signal clk : std_logic_vector := '0';
begin
clk <= not clk after 5 ns;

I often use:

clk <= simulation_in_progress xor clk after 50 ns;

clk must be initiated as in your first example. You cant have two
drivers as in the
second example. "simulation_in_progress" may be used to switch the
clock off at the
end of the testbench.

/Peter
 
A

Andy

or just:

signal clk : std_logic := '0'; -- initialized to '0'
...
clk <= not clk after 5 ns; -- concurrent statement
...

That's all!

Andy
 
B

Brad Smallridge

If clk <= 0 at t=0 what's wrong with clk <= not clk after 5 ns?
Shoudn't clk be '1' (not clk) at t=5 because clk was set to '0' at
t=0?

This is how I think the machine "thinks"

read clk<='0'
OK schedule clk for '0' at T=0
read clk<= not clk after 5 ns
OK schedule clk for not clk at 5ns
what's clk?
I don't know, Ok we will schedule a U for 5ns
Are all the processes resolved?
Yes.
What's the first scheduled time?
t=0.
What's scheduled?
clk<='0'
What's the next scheduled time?
t=5ns.
What's scheduled?
clk<='U'

Probably somebody out there will explain better how this
works with better terminology, but this is why your code
will not work.

Brad Smallridge
Ai Vision
 
M

Martin Thompson

Peter said:
I often use:

clk <= simulation_in_progress xor clk after 50 ns;

I do:

clk <= not clk after 5 ns when finished /= '1' else '0';

I can then use a resolved logic type for "finished" and once all the
processes driving it have finished (ie driven it high), the clock will
stop.

Again, you have to initialise the clock. I init it high, so that my
first transition is a falling edge (ie not the active edge for most of
my stuff). I don't think it matters much though!

Another "driving trick" for reset lines that I like is:
reset <= '1', '0' after 500 ns;

Cheers,
Martin
 
S

sathya

While I was trying to generate a clock signal in the test bench I
noticed a strange behavior

signal clk : std_logic_vector := '0';
begin
clk <= not clk after 5 ns;

The above code works fine but the below code generates only 'U' in the
wave form.

signal clk : std_logic_vector';
begin
clk <= '0';
clk <= not clk after 5 ns;
I thought changing clk <= '0' to clk <= '0' after 2 ns would work but
it didn't. I am new to VHDL and appreciate if anyone explains this.

I know concurrent statements execute whenever any of the RHS signal or
variable changes value but what will happen if we have concurrent
statement like x <= '0' or x <= '0' after 5 ns; where '0' is a literal
value. When will it execute?

BReddy

1) why is the clk signal defined as std_logic_vector ?
2) i think u can initialize the clock signal to zero and then use the
other statement.. It worked for me ;)

signal clk : std_logic := '0' ;
begin
clk <= not clk after 20ns ;

The problem with your declaration is that the clock signal will be
assigned to 'U' state and so it will not give u what is recquired..Am
i right guys ?
 
J

Jonathan Bromley

or just:

signal clk : std_logic := '0'; -- initialized to '0'
...
clk <= not clk after 5 ns; -- concurrent statement
...

That's all!

Yes, but in fairness: I did say:

And surely the very explicit process is a little easier to
understand, for a beginner? The operation of
concurrent assignments with feedback like that is
not blindingly obvious... especially when combined
with an initialisation in the signal declaration!

OK, it's Clock Generator Wars. Here's my preferred
version for serious work:

signal clock: std_logic;
signal stop: boolean; --- initially FALSE
signal clock_period: time := 10 ns;
....
clockgen: process begin
while not stop loop
clock <= '0', '1' after clock_period/2;
wait for clock_period; --- immune to /2 rounding errors
end loop;
wait until not stop;
end process;

If I don't want a variable clock period I can easily rewrite
the declaration of clock_period as a constant.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
S

sathya

Yes, but in fairness: I did say:


And surely the very explicit process is a little easier to
understand, for a beginner? The operation of
concurrent assignments with feedback like that is
not blindingly obvious... especially when combined
with an initialisation in the signal declaration!

OK, it's Clock Generator Wars. Here's my preferred
version for serious work:

signal clock: std_logic;
signal stop: boolean; --- initially FALSE
signal clock_period: time := 10 ns;
...
clockgen: process begin
while not stop loop
clock <= '0', '1' after clock_period/2;
wait for clock_period; --- immune to /2 rounding errors
end loop;
wait until not stop;
end process;

If I don't want a variable clock period I can easily rewrite
the declaration of clock_period as a constant.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

oops.. i had not read your post properly.
sorry . full credit to you jonathan .
 
A

Andy

Yes, but in fairness: I did say:


And surely the very explicit process is a little easier to
understand, for a beginner? The operation of
concurrent assignments with feedback like that is
not blindingly obvious... especially when combined
with an initialisation in the signal declaration!

OK, it's Clock Generator Wars. Here's my preferred
version for serious work:

signal clock: std_logic;
signal stop: boolean; --- initially FALSE
signal clock_period: time := 10 ns;
...
clockgen: process begin
while not stop loop
clock <= '0', '1' after clock_period/2;
wait for clock_period; --- immune to /2 rounding errors
end loop;
wait until not stop;
end process;

If I don't want a variable clock period I can easily rewrite
the declaration of clock_period as a constant.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Well, since WAR has been declared! ;^)

signal clock_period : time := 25 ns; -- this is usually a generic for
me
signal stop : boolean := false;
signal clock : std_logic := '0';

clock <= '1' after clk_period/2 when not stop and clk = '0'
else '0' after clk_period/2 + (clk_period mod 2) when not stop and
clk = '1';

Works as long as you don't want to start up again after stopping. You
will get one more edge after stop goes true.

Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top