if and and vs if and,and

T

titi

Guest
While we can believe that s1, s2, s3, s4, and s5 give the same result,
why does not s1 and s2 give the same result?
----


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity essai is
port (
unused : in std_logic
);
end essai;

architecture behavioral of essai is

signal clock : std_logic;
signal reset : std_logic;
signal count : std_logic_vector(6 downto 0);

signal ce : std_logic;
signal ce2 : std_logic;

signal e2 : std_logic:='0';
signal e4 : std_logic;
signal e5 : std_logic;
signal e6 : std_logic;
signal e8 : std_logic;
signal e9 : std_logic;

signal s1 : std_logic_vector(1 downto 0);
signal s2 : std_logic_vector(1 downto 0);
signal s3 : std_logic_vector(1 downto 0);
signal s4 : std_logic_vector(1 downto 0);
signal s5 : std_logic_vector(1 downto 0);
begin

p_main : process (clock,e8)
begin
if reset = '1' then
e2 <= '1';
e4 <= '1';
e5 <= '0';
e6 <= '1';
e8 <= '0';
e9 <= '0';
count <="0000000" ;
elsif rising_edge (clock) then
e8 <= not e8 ;
e4 <= not e4 ;
count <= count + "1" ;
elsif rising_edge (e8) then
e2 <= not e2 ;
e6 <= not e6 ;

end if;
end process;

p_clock : process
begin
clock <= '0' ;
reset <= '1' ;
wait for 100 ns ;
reset <= '0' ;
while true loop
wait for 100 ns ;
clock <= not clock ;
end loop;
end process;

p_4 : process(reset,e2,clock)
begin
if(reset = '1') then
s4 <= "00" ;
elsif (clock'event) and (clock ='0') then
s4 <= "00";
elsif (e2='1') then
if clock'event and clock ='1' then
s4 <= s4 + "01";
end if;
end if;
end process;

p_s5 : process(reset, clock,count,e2)
begin
if (reset ='1') then
s5 <= "00";
elsif (clock'event) and (clock ='1') then
if (e2 ='1') then
s5 <= s5 + '1';
end if;
elsif (clock'event) and (clock ='0') then
s5 <= "00";
end if;
end process;

p_3 : process(reset, clock,count,e2)
begin
if (reset ='1') then
s3 <= "00";
elsif (clock'event) and ((clock ='1') and (e2 ='1')) then
s3 <= s3 + '1';
elsif (clock'event) and (clock ='0') then
s3 <= "00";
end if;
end process;

ce <= clock and e2 ;
ce2 <= not ce;

process(reset,clock,e2)
begin
if (reset = '1') then
s2 <= "00";
elsif (clock'event) then
if ( '1' = (clock and e2)) then
s2 <= s2 + '1';
elsif (clock ='0') then
s2 <= "00";
end if;
end if;
end process;

p_1:process(reset,clock,e2,ce)
begin
if reset ='1' then
s1 <= "00";
elsif (clock'event) and (ce = '1' ) then
s1 <= s1 + "01";
elsif (clock'event) and (clock ='0') then
s1 <= "00";
end if;
end process;

end behavioral;
 
On Mar 9, 1:52 pm, titi <t...@nospam.fr> wrote:
While we can believe that s1, s2, s3, s4, and s5 give the same result,
why does not s1 and s2 give the same result?
----

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity essai is
port (
unused : in std_logic
);
end essai;

architecture behavioral of essai is

signal clock : std_logic;
signal reset : std_logic;
signal count : std_logic_vector(6 downto 0);

signal ce : std_logic;
signal ce2 : std_logic;

signal e2 : std_logic:='0';
signal e4 : std_logic;
signal e5 : std_logic;
signal e6 : std_logic;
signal e8 : std_logic;
signal e9 : std_logic;

signal s1 : std_logic_vector(1 downto 0);
signal s2 : std_logic_vector(1 downto 0);
signal s3 : std_logic_vector(1 downto 0);
signal s4 : std_logic_vector(1 downto 0);
signal s5 : std_logic_vector(1 downto 0);
begin

p_main : process (clock,e8)
begin
if reset = '1' then
e2 <= '1';
e4 <= '1';
e5 <= '0';
e6 <= '1';
e8 <= '0';
e9 <= '0';
count <="0000000" ;
elsif rising_edge (clock) then
e8 <= not e8 ;
e4 <= not e4 ;
count <= count + "1" ;
elsif rising_edge (e8) then
e2 <= not e2 ;
e6 <= not e6 ;

end if;
end process;

p_clock : process
begin
clock <= '0' ;
reset <= '1' ;
wait for 100 ns ;
reset <= '0' ;
while true loop
wait for 100 ns ;
clock <= not clock ;
end loop;
end process;

p_4 : process(reset,e2,clock)
begin
if(reset = '1') then
s4 <= "00" ;
elsif (clock'event) and (clock ='0') then
s4 <= "00";
elsif (e2='1') then
if clock'event and clock ='1' then
s4 <= s4 + "01";
end if;
end if;
end process;

p_s5 : process(reset, clock,count,e2)
begin
if (reset ='1') then
s5 <= "00";
elsif (clock'event) and (clock ='1') then
if (e2 ='1') then
s5 <= s5 + '1';
end if;
elsif (clock'event) and (clock ='0') then
s5 <= "00";
end if;
end process;

p_3 : process(reset, clock,count,e2)
begin
if (reset ='1') then
s3 <= "00";
elsif (clock'event) and ((clock ='1') and (e2 ='1')) then
s3 <= s3 + '1';
elsif (clock'event) and (clock ='0') then
s3 <= "00";
end if;
end process;

ce <= clock and e2 ;
ce2 <= not ce;

process(reset,clock,e2)
begin
if (reset = '1') then
s2 <= "00";
elsif (clock'event) then
if ( '1' = (clock and e2)) then
s2 <= s2 + '1';
elsif (clock ='0') then
s2 <= "00";
end if;
end if;
end process;

p_1:process(reset,clock,e2,ce)
begin
if reset ='1' then
s1 <= "00";
elsif (clock'event) and (ce = '1' ) then
s1 <= s1 + "01";
elsif (clock'event) and (clock ='0') then
s1 <= "00";
end if;
end process;

end behavioral;
Caveat: I haven't verified this in a simulator, but here's my 2 cents:

If you're talking about the last two processes, the logic is
different. The second last (anonymous) process will let s1 increment
only on a rising edge ('1' = (clock and ...)). It will then reset at
each falling edge. The last process p_1 will allow s1 to increment
freely at each clock edge as long as ce is held high.

There are also some nasty and convoluted timing semantics; your driver
process sets e2 at the delta cycle following e8 which follows the
clock edge. Then you'll see several process runs at the same timestep
at the clock. This will cause p_1 to run more than once at the clock
because e2 is changing off the edge.

While this is good stuff to investigate the hairiness of language
semantics (or simulator behaviour), I hope you're not planning to
synthesize this!

- Kenn
 
kennheinrich@sympatico.ca a écrit :
On Mar 9, 1:52 pm, titi <t...@nospam.fr> wrote:
While we can believe that s1, s2, s3, s4, and s5 give the same result,
why does not s1 and s2 give the same result?
----

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity essai is
port (
unused : in std_logic
);
end essai;

architecture behavioral of essai is

signal clock : std_logic;
signal reset : std_logic;
signal count : std_logic_vector(6 downto 0);

signal ce : std_logic;
signal ce2 : std_logic;

signal e2 : std_logic:='0';
signal e4 : std_logic;
signal e5 : std_logic;
signal e6 : std_logic;
signal e8 : std_logic;
signal e9 : std_logic;

signal s1 : std_logic_vector(1 downto 0);
signal s2 : std_logic_vector(1 downto 0);
signal s3 : std_logic_vector(1 downto 0);
signal s4 : std_logic_vector(1 downto 0);
signal s5 : std_logic_vector(1 downto 0);
begin

p_main : process (clock,e8)
begin
if reset = '1' then
e2 <= '1';
e4 <= '1';
e5 <= '0';
e6 <= '1';
e8 <= '0';
e9 <= '0';
count <="0000000" ;
elsif rising_edge (clock) then
e8 <= not e8 ;
e4 <= not e4 ;
count <= count + "1" ;
elsif rising_edge (e8) then
e2 <= not e2 ;
e6 <= not e6 ;

end if;
end process;

p_clock : process
begin
clock <= '0' ;
reset <= '1' ;
wait for 100 ns ;
reset <= '0' ;
while true loop
wait for 100 ns ;
clock <= not clock ;
end loop;
end process;

p_4 : process(reset,e2,clock)
begin
if(reset = '1') then
s4 <= "00" ;
elsif (clock'event) and (clock ='0') then
s4 <= "00";
elsif (e2='1') then
if clock'event and clock ='1' then
s4 <= s4 + "01";
end if;
end if;
end process;

p_s5 : process(reset, clock,count,e2)
begin
if (reset ='1') then
s5 <= "00";
elsif (clock'event) and (clock ='1') then
if (e2 ='1') then
s5 <= s5 + '1';
end if;
elsif (clock'event) and (clock ='0') then
s5 <= "00";
end if;
end process;

p_3 : process(reset, clock,count,e2)
begin
if (reset ='1') then
s3 <= "00";
elsif (clock'event) and ((clock ='1') and (e2 ='1')) then
s3 <= s3 + '1';
elsif (clock'event) and (clock ='0') then
s3 <= "00";
end if;
end process;

ce <= clock and e2 ;
ce2 <= not ce;

process(reset,clock,e2)
begin
if (reset = '1') then
s2 <= "00";
elsif (clock'event) then
if ( '1' = (clock and e2)) then
s2 <= s2 + '1';
elsif (clock ='0') then
s2 <= "00";
end if;
end if;
end process;

p_1:process(reset,clock,e2,ce)
begin
if reset ='1' then
s1 <= "00";
elsif (clock'event) and (ce = '1' ) then
s1 <= s1 + "01";
elsif (clock'event) and (clock ='0') then
s1 <= "00";
end if;
end process;

end behavioral;

Caveat: I haven't verified this in a simulator, but here's my 2 cents:

If you're talking about the last two processes, the logic is
different. The second last (anonymous) process will let s1 increment
only on a rising edge ('1' = (clock and ...)). It will then reset at
each falling edge. The last process p_1 will allow s1 to increment
freely at each clock edge as long as ce is held high.
this is not very clear, because :
ce <= clock and e2 ;
This makes condition for S1 and s2 should be the same, at least, from a
simulator point of view.


There are also some nasty and convoluted timing semantics; your driver
process sets e2 at the delta cycle following e8 which follows the
clock edge. Then you'll see several process runs at the same timestep
at the clock. This will cause p_1 to run more than once at the clock
because e2 is changing off the edge.
I understand that vhdl is not easy, but I do not understand why the
process should execute several times in the same clock, due to two
signals event, in sensitivity list.

Do you mean it is incorrect to have more than one signal in sensitivity
list?
Or do you mean it is incorrect that an input signal change on a rising adge?


While this is good stuff to investigate the hairiness of language
semantics (or simulator behaviour), I hope you're not planning to
synthesize this!
- Kenn
How can we know if a code is good for being synthesized?
 
terminator wrote:
kennheinrich@sympatico.ca a écrit :
On Mar 9, 1:52 pm, titi <t...@nospam.fr> wrote:
While we can believe that s1, s2, s3, s4, and s5 give the same result,
why does not s1 and s2 give the same result?
----

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity essai is
port (
unused : in std_logic
);
end essai;

architecture behavioral of essai is

signal clock : std_logic;
signal reset : std_logic;
signal count : std_logic_vector(6 downto 0);

signal ce : std_logic;
signal ce2 : std_logic;

signal e2 : std_logic:='0';
signal e4 : std_logic;
signal e5 : std_logic;
signal e6 : std_logic;
signal e8 : std_logic;
signal e9 : std_logic;

signal s1 : std_logic_vector(1 downto 0);
signal s2 : std_logic_vector(1 downto 0);
signal s3 : std_logic_vector(1 downto 0);
signal s4 : std_logic_vector(1 downto 0);
signal s5 : std_logic_vector(1 downto 0);
begin

p_main : process (clock,e8)
begin
if reset = '1' then
e2 <= '1';
e4 <= '1';
e5 <= '0';
e6 <= '1';
e8 <= '0';
e9 <= '0';
count <="0000000" ;
elsif rising_edge (clock) then
e8 <= not e8 ;
e4 <= not e4 ;
count <= count + "1" ;
elsif rising_edge (e8) then
e2 <= not e2 ;
e6 <= not e6 ;

end if;
end process;

p_clock : process
begin
clock <= '0' ;
reset <= '1' ;
wait for 100 ns ;
reset <= '0' ;
while true loop
wait for 100 ns ;
clock <= not clock ;
end loop;
end process;

p_4 : process(reset,e2,clock)
begin
if(reset = '1') then
s4 <= "00" ;
elsif (clock'event) and (clock ='0') then
s4 <= "00";
elsif (e2='1') then
if clock'event and clock ='1' then
s4 <= s4 + "01";
end if;
end if;
end process;

p_s5 : process(reset, clock,count,e2)
begin
if (reset ='1') then
s5 <= "00";
elsif (clock'event) and (clock ='1') then
if (e2 ='1') then
s5 <= s5 + '1';
end if;
elsif (clock'event) and (clock ='0') then
s5 <= "00";
end if;
end process;

p_3 : process(reset, clock,count,e2)
begin
if (reset ='1') then
s3 <= "00";
elsif (clock'event) and ((clock ='1') and (e2 ='1')) then
s3 <= s3 + '1';
elsif (clock'event) and (clock ='0') then
s3 <= "00";
end if;
end process;

ce <= clock and e2 ;
ce2 <= not ce;

process(reset,clock,e2)
begin
if (reset = '1') then
s2 <= "00";
elsif (clock'event) then
if ( '1' = (clock and e2)) then
s2 <= s2 + '1';
elsif (clock ='0') then
s2 <= "00";
end if;
end if;
end process;

p_1:process(reset,clock,e2,ce)
begin
if reset ='1' then
s1 <= "00";
elsif (clock'event) and (ce = '1' ) then
s1 <= s1 + "01";
elsif (clock'event) and (clock ='0') then
s1 <= "00";
end if;
end process;

end behavioral;

Caveat: I haven't verified this in a simulator, but here's my 2 cents:

If you're talking about the last two processes, the logic is
different. The second last (anonymous) process will let s1 increment
only on a rising edge ('1' = (clock and ...)). It will then reset at
each falling edge. The last process p_1 will allow s1 to increment
freely at each clock edge as long as ce is held high.

this is not very clear, because :
ce <= clock and e2 ;
This makes condition for S1 and s2 should be the same, at least, from a
simulator point of view.
Almost, but not quite. The simulation has slightly different rules
that would apply if, say, you built what you think this code is saying
out of 74LS logic.

What's happening is that ce is being assigned a new value when clk
changes, by the process implicit in the "ce <= clock and e2'"
statement. But *before* its new value is propogated to the actual
signal, all other processes sensitive to clk are run first, and they
get to see the old value of ce. So there does exist a point at which
p_1 runs and sees (clock'event and ce='1') on the falling edge of
clock, and hence executes the increment.

There are also some nasty and convoluted timing semantics; your driver
process sets e2 at the delta cycle following e8 which follows the
clock edge. Then you'll see several process runs at the same timestep
at the clock. This will cause p_1 to run more than once at the clock
because e2 is changing off the edge.

I understand that vhdl is not easy, but I do not understand why the
process should execute several times in the same clock, due to two
signals event, in sensitivity list.
This was more an observation that e2 is included in p_1's sensitivity
list (but is not used). Probably a bug, but I was being pedantic. So
any time any value is assigned to e2 (even the same one it had before
the assignment), p_1 will run. So you have to be careful not to let a
process with such a sensivity list have side effects of doing things
unless they're explicitly guarded by an "if rising_edge(clock)" thype
of condition. If, for example, you had a process which assigned a
solid '1' to the clock for 100 ns, but performed the assignment every
1 ns, every process with clock in it's sensitivity list will run.

Similary, if e2 is assigned as a derivative signal (with no time
delay) between clock and e2, the process will run once when clock
changes, then the other process runs to change e2, then the first
process sensitive to e2 runs again. Thus, two executions for one clock
edge. You need to make sure the second has no effect, or better yet,
doesn't run.

In a real hardware design, with a schematic, you can slap down a wire
(no delay) off of a clock, call it a different clock name, and still
be able to pass data synchronously across domains just as you expect
to. But in VHDL, the process ordering makes this potentially unsafe.

Do you mean it is incorrect to have more than one signal in sensitivity
list?
Or do you mean it is incorrect that an input signal change on a rising adge?


While this is good stuff to investigate the hairiness of language
semantics (or simulator behaviour), I hope you're not planning to
synthesize this!
- Kenn

How can we know if a code is good for being synthesized?
When there's none of this stuff in it :) But seriously, that's a
much longer answer...

HTH,

- Kenn
 
terminator wrote:

How can we know if a code is good for being synthesized?
1. Follow a known good synthesis template.
I like the one here: http://home.comcast.net/~mike_treseler/
but there are others.

2. Simulate the code to verify the function.

3. Run synthesis and check the warnings.

-- Mike Treseler
 

Welcome to EDABoard.com

Sponsor

Back
Top