VHDL Behavioral and Structural Mixed Models

Discussion in 'VHDL' started by aris, Jul 14, 2010.

  1. aris

    aris

    Joined:
    Jul 14, 2010
    Messages:
    6
    Hi everyone,

    I have been searching over the net, university library, ebooks, etc. but i cudnt really find any example of mixed VHDL models in which both structural and behavioral models are used together. I have a model, as I show below which is composed of one behavioral part and structural part but, whenever I try test it, I always receive incorrect results. Cud somebody please help me with it? :(

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    use work.Components.all;

    entity Deneme is
    generic ( n: natural := bitSize );
    port ( x, y, m : in std_logic_vector ( n-1 downto 0 );
    clk, rst: in std_logic;
    product1, product2 : out std_logic_vector ( n downto 0 )
    );
    end Deneme;

    architecture Behavioral of Deneme is

    signal s, c, regSum, regCarry : std_logic_vector ( n downto 0 ) :=( others => '0' );
    signal pp, uM : std_logic_vector ( n downto 0 ) :=( others => '0' );
    signal sFa, cFa, u : std_logic;
    signal i: integer range 0 to n-1;


    begin

    process ( clk )
    begin
    if ( clk'event and clk='1' ) then
    if ( rst='0' ) then
    i <= 0 ;
    u <= '0' ;
    pp <= ( others => '0' );
    uM <= ( others => '0' );
    product1 <= ( others => '0' );
    product2 <= ( others => '0' );

    else
    if ( i < n-1 ) then
    pp <= ('0' & andVecIndex( x, i, y ));
    u <= pp(0) xor s(0);
    uM <=('0'& andVecScalar( u, m ));
    i <= i + 1;
    else
    i <= 0;
    end if;
    end if;
    end if;

    end process;



    f1: FA port map( s(0), pp(0), uM(0), sFa, cFa );
    c1: CSA port map ( s( n downto 1), c( n downto 1), pp( n downto 1), uM(n downto 1), cFa, regSum, regCarry );
    R1: Reg port map ( clk, rst, regSum, s);
    R2: Reg port map ( clk, rst, regCarry, c);
    product1 <= s;
    product2 <= c;



    end Behavioral;
     
    aris, Jul 14, 2010
    #1
    1. Advertisements

  2. aris

    joris

    Joined:
    Jan 29, 2009
    Messages:
    152
    There shouldn't be a problem with mixing styles (though it seems cleaner not to mix them, keeping all behavioral / RTL level )

    Note that product1, product2 are updated after the rising_edge (In simulation a "delta time" after the clock going high) - what you are seeing may be a timing behavior problem?


    Also, you are using signals inside of your process (u is reading pp, uM is reading u), this probably does not give the semantics you meant:
    A signal it's value is update at the exit of the process -- another statement reading them gets the old value (this is useful for describing pipelining)
    As far as I can see, you don't want this to happen in your code

    You should instead replace them by variables, and only update the signals to their values in the end (only using signals for outside communication);
    something like:
    Code (Text):

    process ( clk )
    variable  vpp, vuM : std_logic_vector ( n downto 0 ) :=( others => '0' );
    variable u : std_logic;
    variable i: integer range 0 to n-1;
    begin
    if ( clk'event and clk='1' ) then
    if ( rst='0' ) then
    i := 0 ;

    pp <= ( others => '0' );
    uM <= ( others => '0' );

    --I think there is no point in having these here / having these here may cause problems
    --product1 <= ( others => '0' );
    --product2 <= ( others => '0' );

    else
    if ( i < n-1 ) then
    vpp := ('0' & andVecIndex( x, i, y ));
    u := vpp(0) xor s(0);
    vuM <=('0'& andVecScalar( u, m ));
    i := i + 1;

    pp <= vpp;
    uM <= vuM;
    else
    i := 0;
    end if;
    end if;
    end if;

    end process;
     
    Note that this kind of "idiom" should avoid the (unintended) semantic difference between signals and variables (inside a process). It can obviously be relaxed somewhat, if you understand well enough what the differences are.
     
    Last edited: Jul 14, 2010
    joris, Jul 14, 2010
    #2
    1. Advertisements

  3. aris

    aris

    Joined:
    Jul 14, 2010
    Messages:
    6
    Thanks for you reply! After posting this thread, i had changed sths with the code. Now, after reading your comments, I realised I did somethings right. Here is the new form of it.


    --- >= <=
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    use work.Components.all;

    entity Deneme is
    generic ( n: natural := bitSize );
    port ( x, y, m : in std_logic_vector ( n-1 downto 0 );
    clk, rst: in std_logic;
    pp, uM : inout std_logic_vector ( n downto 0 );
    s, c : inout std_logic_vector ( n downto 0 );
    bitti : out std_logic

    );
    end Deneme;

    architecture Behavioral of Deneme is

    signal regSum, regCarry : std_logic_vector ( n downto 0 ) :=( others => '0' );
    signal sFa, cFa, u : std_logic;
    signal i: integer range 0 to n-1;


    begin

    process ( clk )
    begin
    if ( clk'event and clk='1' ) then
    if ( rst='0' ) then
    i <= 0 ;
    u <= '0' ;
    pp <= ( others => '0' );
    uM <= ( others => '0' );
    bitti <= '0';

    else
    if ( i < n-1 ) then
    pp <= ('0' & andVecIndex( x, i, y ));
    for j in 0 to n-1 loop
    uM(i) <= ( pp(0) xor s(0) ) and m(i);
    end loop;
    i <= i + 1;
    else
    i <= 0;
    bitti <= '1';
    end if;
    end if;
    end if;

    end process;



    f1: FA port map( s(0), pp(0), uM(0), sFa, cFa );
    c1: CSA port map ( s( n downto 1), c( n downto 1), pp( n downto 1), uM(n downto 1), cFa, regSum, regCarry );
    R1: Reg port map ( clk, rst, regSum, s);
    R2: Reg port map ( clk, rst, regCarry, c);



    end Behavioral;

    In fact, my problem is, controlling the structural part. In the design I am thinking, structural part must work after the behavioral part in order to get correct partial sum and carry values. Cos structural part is parallel to behavioral part, it is always working and after the first cycle, it starts to give incorrect partial sum and carry values. Do you think is there a way to make my code work like Behavioral-Structural-Behavioral-Structural-Beha... In such a way?
     
    aris, Jul 14, 2010
    #3
  4. aris

    aris

    Joined:
    Jul 14, 2010
    Messages:
    6
    No chance to do that? No chance to control the working of structural part? If guarded blocks were synthesizable, then I wud consider using them, but as far as I know they are not synthesizable. :(
     
    aris, Jul 15, 2010
    #4
  5. aris

    joris

    Joined:
    Jan 29, 2009
    Messages:
    152
    it may be harder to get the timings right (that's probably the main issue?), but it sure should be possible.


    I also noticed you're still using only signals inside the process. Especially this code:

    Code (Text):
    for j in 0 to n-1 loop
    uM(i) <= ( pp(0) xor s(0) ) and m(i);
    end loop;
    This introduces a pipeline stage between pp(0) and uM (each element) - is this what you intended ?
     
    joris, Jul 15, 2010
    #5
  6. aris

    joris

    Joined:
    Jan 29, 2009
    Messages:
    152
    I think this may be what you intended (based on the code you originally posted)
    Code (Text):
    architecture Behavioral of Deneme is

    signal s, c : std_logic_vector ( n downto 0 ) :=( others => '0' );
    signal sig_pp, sig_uM : std_logic_vector ( n downto 0 ) :=( others => '0' );

    signal sFa, cFa : std_logic;
    signal regSum, regCarry : std_logic_vector ( n downto 0 ) :=( others => '0' );
    begin

    process ( clk )
      variable u : std_logic;
      variable pp, uM : std_logic_vector ( n downto 0 ) :=( others => '0' );
      variable i: integer range 0 to n-1;
    begin
        if ( clk'event and clk='1' ) then
            if ( rst='0' ) then
                i := 0 ;
                pp := ( others => '0' );
                uM := ( others => '0' );
            else
                if ( i < n-1 ) then
                    pp := ('0' & andVecIndex( x, i, y ));
                    u := pp(0) xor s(0);
                    uM := ('0'& andVecScalar( u, m ));
                    i := i + 1;
                else
                    i := 0;
                end if;
            end if;
            sig_pp <= pp;
            sig_uM <= uM;
        end if;
    end process;

    f1: FA port map( s(0), sig_pp(0), sig_uM(0), sFa, cFa );
    c1: CSA port map ( s( n downto 1), c( n downto 1), sig_pp( n downto 1), sig_uM(n downto 1), cFa, regSum, regCarry );
    R1: Reg port map ( clk, rst, regSum, s);
    R2: Reg port map ( clk, rst, regCarry, c);
    product1 <= s;
    product2 <= c;

    end Behavioral;
     
    joris, Jul 15, 2010
    #6
  7. aris

    aris

    Joined:
    Jul 14, 2010
    Messages:
    6
    Thanks a lot Joris. As you had indicated such a usage in your previous posts, I tried exactly the same things. When I try to test it, I get incorrect partial products. You may be curious how I test it, it is just as simple as having clock, changing between 0 and 1 till the end of simulation, holding reset 0 first, then assigning values to multiplicand(y), multiplier(x), and modulo value(m), then setting reset to 1, observing partial sum and carry values. When I tried previously the code you wrote above, i was still getting incorrect partial sum and carry values. So I thought of changing sths like this:



    Code (Text):

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    use work.Components.all;

    entity Trial is
      generic ( n: natural := bitSize );
      port ( x, y, m : in std_logic_vector ( n-1 downto 0 );
             clk, rst: in std_logic;
                pp, uM : inout std_logic_vector ( n downto 0 );
                s, c : inout std_logic_vector ( n downto 0 );
                bitti : out std_logic
               
                );
    end Trial;

    architecture Behavioral of Trial is

      signal  regSum, regCarry : std_logic_vector ( n downto 0 ) :=( others => '0' );
      signal  cFa: std_logic;
      signal i: integer range 0 to n-1;
     
     
      begin

        process ( clk )
           begin
              if ( clk'event and clk='1' ) then
               if ( rst='0' ) then
                     i <= 0 ;
                        bitti <= '0';
                   pp <= ( others => '0' );
                   uM <= ( others => '0' );                                    
                 else            
                     if ( i < n-1 ) then
                          i <= i + 1;
                        else
                         i <= 0;
                     bitti <= '1';                   
                       end if;
               end if;
              end if;
        end process;
                       
                       
        g1:for j in 0 to n-1 generate
          pp(j) <= x(i) and y(j);
       end generate;
       g2:for k in 0 to n-1 generate
          uM(k) <= ( ( x(i) and y(0) ) xor s(0) ) and m(k);
       end generate;   
        cFa <= (s(0) and pp(0) ) or (s(0) and uM(0)) or (pp(0) and uM(0));
        c1: CSA port map ( s( n downto 1), c( n downto 1), pp( n downto 1), uM(n downto 1), cFa, regSum, regCarry );  
       R1: Reg port map ( clk, rst, regSum, s);
        R2: Reg port map ( clk, rst, regCarry, c); 
       
    end Behavioral;
     
    I think I still cannot get correct/proper timing for my design. I'm reading, searching, thinking on this, but I cudnt really solve it ya! :D Arrghhh!!!
     
    aris, Jul 15, 2010
    #7
  8. aris

    aris

    Joined:
    Jul 14, 2010
    Messages:
    6
    I solved the problem!!! :) Its working correctly now! :) Just with the code I wrote above, changing one wee part of it solved the problem with the design. Its working correctly now! Thanks for your help Joris! Appreciated!
     
    aris, Jul 16, 2010
    #8
  9. aris

    joris

    Joined:
    Jan 29, 2009
    Messages:
    152
    Uhm that's alright -- though I think in the end my responses didn't do very much except poke like "there something's not going right" at least :)
     
    joris, Jul 16, 2010
    #9
  10. aris

    aris

    Joined:
    Jul 14, 2010
    Messages:
    6
    :) Well, giving responses, paying attention, spending time for it, ... These are as important as solving the problem in my opinion! Thanks a lot! :)
     
    aris, Jul 16, 2010
    #10
    1. Advertisements

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.
Similar Threads
  1. Amontec Team
    Replies:
    0
    Views:
    1,855
    Amontec Team
    Jul 11, 2003
  2. Swaroop Kumar
    Replies:
    0
    Views:
    416
    Swaroop Kumar
    Aug 12, 2003
  3. vinjvinj
    Replies:
    15
    Views:
    661
    Jeremy Sanders
    Nov 10, 2005
  4. Jean-Paul Calderone
    Replies:
    0
    Views:
    497
    Jean-Paul Calderone
    Nov 7, 2005
  5. David Heinemeier Hansson
    Replies:
    0
    Views:
    314
    David Heinemeier Hansson
    Dec 23, 2004
Loading...

Share This Page