sensitivity list

V

Volker

Guest
Hello,
I have a question about the sensitivity list.Until now i thought a process
is sleeping as long as a signal changed which is in the sensitivity list.
Please see the code (process OUT_PROC) below. Signal CMI_OUT is changing
also when the sensitivity signals FIRST_BIT and SECOND_BIT not !!
changing.(simulated with QuartusII Simulator and Modelsim)
Can anybody tell me why??
I would realize the function like it act now, but i dont know why. In the
RTL viewer of Quartus i can see the synthesised logic. Its OK for me, but
why the VHDL code is synthesised in that way? Is the clock signal implicit
in a sensitivity list?
Thanks
Volker

SM_CLK: process(CLK, RST)
begin
if (RST ='1')then
PRESENT_STATE <= RESET_STATE;
elsif (CLK'EVENT AND CLK ='1') then
PRESENT_STATE <= NEXT_STATE;

case PRESENT_STATE is
when S00 =>
FIRST_BIT <= '0';
SECOND_BIT <= '0';
when S11 =>
FIRST_BIT <= '1';
SECOND_BIT <= '1';
when S01A =>
FIRST_BIT <= '0';
SECOND_BIT <= '1';
when S01B =>
FIRST_BIT <= '0';
SECOND_BIT <= '1';
when others =>
null;
end case;
end if;
end process SM_CLK;

OUT_PROC: process(FIRST_BIT, SECOND_BIT)
begin
if (CLK ='1') then
CMI_OUT <= FIRST_BIT;
elsif (CLK ='0') then
CMI_OUT <= SECOND_BIT;
end if;
end process OUT_PROC;
 
On Jan 25, 6:44 am, "Volker" <j...@gmx.de> wrote:
Hello,
I have a question about the sensitivity list.Until now i thought a process
is sleeping as long as a signal changed which is in the sensitivity list.
Please see the code (process OUT_PROC) below. Signal CMI_OUT is changing
also when the sensitivity signals FIRST_BIT and SECOND_BIT not !!
changing.(simulated with QuartusII Simulator and Modelsim)
Can anybody tell me why??
I would realize the function like it act now, but i dont know why. In the
RTL viewer of Quartus i can see the synthesised logic. Its OK for me, but
why the VHDL code is synthesised in that way? Is the clock signal implicit
in a sensitivity list?
Thanks
Volker

SM_CLK: process(CLK, RST)
begin
if (RST ='1')then
PRESENT_STATE <= RESET_STATE;
elsif (CLK'EVENT AND CLK ='1') then
PRESENT_STATE <= NEXT_STATE;

case PRESENT_STATE is
when S00 =
FIRST_BIT <= '0';
SECOND_BIT <= '0';
when S11 =
FIRST_BIT <= '1';
SECOND_BIT <= '1';
when S01A =
FIRST_BIT <= '0';
SECOND_BIT <= '1';
when S01B =
FIRST_BIT <= '0';
SECOND_BIT <= '1';
when others =
null;
end case;
end if;
end process SM_CLK;

OUT_PROC: process(FIRST_BIT, SECOND_BIT)
begin
if (CLK ='1') then
CMI_OUT <= FIRST_BIT;
elsif (CLK ='0') then
CMI_OUT <= SECOND_BIT;
end if;
end process OUT_PROC;
Even though the _values_ of FIRST_BIT and SECOND_BIT are not changing,
you're still doing an _assignment_ to them on every clock tick.
OUT_PROC is sensitive to _assignments_ to FIRST_BIT and SECOND_BIT, not
to whether or not the values assigned change.

Other comments:

a) OUT_PROC should be made sensitive to changes in CLK, as it's a
fully-combinatorial process. Simulation might not match the synthesis
results; there may be a combinatorial latch (yuck).

b) I suppose strictly speaking CLK, which is probably declared as
std_logic, can take values others than '1' and '0', so the if/elsif
statement is not complete and you could get a latch. Why not just do
if (CLK = '1') CMI_OUT = FIRSTBIT; else CMI_OUT=SECOND_BIT; ??

-a
 
Andy Peters wrote:


OUT_PROC: process(FIRST_BIT, SECOND_BIT)
begin
if (CLK ='1') then
CMI_OUT <= FIRST_BIT;
elsif (CLK ='0') then
CMI_OUT <= SECOND_BIT;
end if;
end process OUT_PROC;

Even though the _values_ of FIRST_BIT and SECOND_BIT are not
changing, you're still doing an _assignment_ to them on every clock
tick. OUT_PROC is sensitive to _assignments_ to FIRST_BIT and
SECOND_BIT, not to whether or not the values assigned change.
No. The the statements in a process are executed when an *event*
occurs on one of the signals. An event is a transaction with a value
that differs from the current value. If the value is equal, it is
still a transaction but not an event. So the process will not be
triggered in that case.

You're right the sensitivity list is not complete.

--
Paul.
www.aimcom.nl
email address: switch x and s
 
On Jan 27, 7:42 am, Paul Uiterlinden <p...@sx4all.nl> wrote:
Andy Peters wrote:
OUT_PROC: process(FIRST_BIT, SECOND_BIT)
begin
if (CLK ='1') then
CMI_OUT <= FIRST_BIT;
elsif (CLK ='0') then
CMI_OUT <= SECOND_BIT;
end if;
end process OUT_PROC;

Even though the _values_ of FIRST_BIT and SECOND_BIT are not
changing, you're still doing an _assignment_ to them on every clock
tick. OUT_PROC is sensitive to _assignments_ to FIRST_BIT and
SECOND_BIT, not to whether or not the values assigned change.

No. The the statements in a process are executed when an *event*
occurs on one of the signals. An event is a transaction with a value
that differs from the current value. If the value is equal, it is
still a transaction but not an event. So the process will not be
triggered in that case.
Thanks for the correction ... brain fart. I went back and tested this
to prove it to myself. I've been writing "correct" VHDL so long that
I forget what happens when you write bad code.

-a
 
It appears as if you are trying to describe a circuit with double data
rate behavior (outputs changing on both edges of the clock), by
multiplexing two outputs together, depending on the level of the
clock.

I might suggest there are better ways to to do that, such as the
following implementation of a DDR flop using only SDR flops, which can
be implemented in virtually any fpga:

signal qr, qf : std_logic; -- any type that supports XOR
....
re: process (rst, clk) is
begin
if rst = '1' then
qr <= '0';
elsif rising_edge(clk) then
qr <= dr xor qf; -- encode rising_edge value
end if;
end process;

fe: process (rst, clk) is
begin
if rst = '1' then
qf <= '0';
elsif falling_edge(clk) then
qf <= df xor qr; -- encode falling edge value
end if;
end process;

q <= qr xor qf; -- decode output

Or, if your synthesis tool supports it, it can be done in one process:

re: process (rst, clk) is
variable qr, qf : std_logic; -- any type that supports XOR
begin
if rst = '1' then
qr := '0';
qf := '0';
elsif rising_edge(clk) then
qr := dr xor qf;
elsif falling_edge(clk) then
qf := df xor qr;
end if;
q <= qr xor qf; -- combo xor of reg'd qr & qf
end process;

These equivalent examples avoid glitches on the output, avoid any use
of the clock signal except as a clock, and are compatible with
standard static timing analysis. The dr and df inputs can be tied
together to a single "d" input.

Andy
 
Andy Peters wrote:

Thanks for the correction ... brain fart. I went back and tested
this
to prove it to myself. I've been writing "correct" VHDL so long
that I forget what happens when you write bad code.
:)

Sometimes you have to go back to the basics. I have a directory full
of small code samples. Sometimes to show a bug in the simulator,
sometimes to synchronize my mental simulator with reality (whatever
that may be).

--
Paul.
www.aimcom.nl
email address: switch x and s
 

Welcome to EDABoard.com

Sponsor

Back
Top