if and and vs if and,and

Discussion in 'VHDL' started by titi, Mar 9, 2007.

  1. titi

    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;
     
    titi, Mar 9, 2007
    #1
    1. Advertising

  2. titi

    Guest

    Re: if and and vs if and,and

    On Mar 9, 1:52 pm, titi <> 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
     
    , Mar 9, 2007
    #2
    1. Advertising

  3. titi

    terminator Guest

    Re: if and and vs if and,and

    a écrit :
    > On Mar 9, 1:52 pm, titi <> 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, Mar 10, 2007
    #3
  4. titi

    Guest

    Re: if and and vs if and,and

    terminator wrote:
    > a écrit :
    > > On Mar 9, 1:52 pm, titi <> 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
     
    , Mar 10, 2007
    #4
  5. Re: if and and vs if and,and

    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
     
    Mike Treseler, Mar 11, 2007
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page