testbench procedure trouble

Discussion in 'VHDL' started by Toby, Feb 11, 2005.

  1. Toby

    Toby Guest

    Hi, I'm kinda new to this whole testbench thing. I have a procedure in
    my testbench that looks something like this:

    procedure SMP_READ
    (
    signal A_P_SMP_DATA_READ: out std_logic_vector(7 downto 0);
    ) is
    begin

    A_P_SMP_DATA_READ(7) <= A_SMP_DATA7;
    A_P_SMP_DATA_READ(6) <= A_SMP_DATA6;
    A_P_SMP_DATA_READ(5) <= A_SMP_DATA5;
    A_P_SMP_DATA_READ(4) <= A_SMP_DATA4;
    A_P_SMP_DATA_READ(3) <= A_SMP_DATA3;
    A_P_SMP_DATA_READ(2) <= A_SMP_DATA2;
    A_P_SMP_DATA_READ(1) <= A_SMP_DATA1;
    A_P_SMP_DATA_READ(0) <= A_SMP_DATA0;

    end SMP_READ;

    Where A_SMP_DATA7, A_SMP_DATA6......A_SMP_DATA0 are signals assigned
    for the entire testbench (between the component declarations and the
    procedure declarations) as follows:

    signal A_SMP_DATA0 : STD_LOGIC := 'L';
    signal A_SMP_DATA1 : STD_LOGIC := 'L';
    signal A_SMP_DATA2 : STD_LOGIC := 'L';
    signal A_SMP_DATA3 : STD_LOGIC := 'L';
    signal A_SMP_DATA4 : STD_LOGIC := 'L';
    signal A_SMP_DATA5 : STD_LOGIC := 'L';
    signal A_SMP_DATA6 : STD_LOGIC := 'L';
    signal A_SMP_DATA7 : STD_LOGIC := 'L';

    The problem is, A_P_SMP_DATA_READ(7..0) is not getting the values
    assigned to it in the procedure. I can set a breakpoint (Aldec
    Active-HDL) near the end of the procedure, and I run the cursor over
    the A_P_SMP_DATA_READ(#) and the A_SMP_DATA#, and they just arent
    equal. How can that even be? If I say A_P_SMP_DATA_READ(7) <=
    A_SMP_DATA7; then shouldn't those two things be equal? Any ideas
    would be greatly appreciated.
     
    Toby, Feb 11, 2005
    #1
    1. Advertising

  2. Toby wrote:
    > Hi, I'm kinda new to this whole testbench thing. I have a procedure in

    .. . .
    > The problem is, A_P_SMP_DATA_READ(7..0) is not getting the values
    > assigned to it in the procedure.


    consider adding a synchronous wait to your procedure:

    procedure tic is
    begin
    wait until rising_edge(tb_clk_s);
    end procedure tic;

    procedure SMP_READ is
    begin
    A_P_SMP_DATA_READ(7) <= A_SMP_DATA7;
    A_P_SMP_DATA_READ(6) <= A_SMP_DATA6;
    A_P_SMP_DATA_READ(5) <= A_SMP_DATA5;
    A_P_SMP_DATA_READ(4) <= A_SMP_DATA4;
    A_P_SMP_DATA_READ(3) <= A_SMP_DATA3;
    A_P_SMP_DATA_READ(2) <= A_SMP_DATA2;
    A_P_SMP_DATA_READ(1) <= A_SMP_DATA1;
    A_P_SMP_DATA_READ(0) <= A_SMP_DATA0;
    tic; -- wait after assignments to see changes
    end SMP_READ;

    -- Mike Treseler
     
    Mike Treseler, Feb 11, 2005
    #2
    1. Advertising

  3. Toby

    Toby Guest

    I tried to add the tic thing, but it didnt seem to help. The procedure
    posted earlier was simplified a bit. Here is the complete procedure
    (including the tic call):

    procedure SMP_READ
    -- Timing taken from 'C50 datasheet
    (constant A_SPACE: in character;
    constant A_P_SMP_ADDR_TEMP: in std_logic_vector(2 downto 0);
    signal A_TURBO: in std_logic;
    signal A_SMP_RD_L, A_SMP_IS_L, A_SMP_DS_L, A_SMP_PS_L: out std_logic;
    signal A_P_SMP_DATA_READ: out std_logic_vector(15 downto 0);
    signal A_P_SMP_ADDR: out std_logic_vector(2 downto 0);
    signal A_UPCLKOUT: in std_logic
    ) is
    begin
    A_P_SMP_ADDR <= A_P_SMP_ADDR_TEMP;
    if(A_SPACE = 'I') then
    A_SMP_IS_L <= '0';
    elsif(A_SPACE = 'D') then
    A_SMP_DS_L <= '0';
    elsif(A_SPACE = 'P') then
    A_SMP_PS_L <= '0';
    end if;
    -- tsu(AV-RDL)
    if(A_TURBO = '0') then --turbo mode
    wait for 10 ns;
    else --slow mode
    wait for 20 ns;
    end if;
    A_SMP_RD_L <= '0';
    -- tw(RDL)
    if(A_TURBO = '0') then --turbo mode
    wait for 58 ns;
    else --slow mode
    wait for 88 ns;
    end if;
    A_P_SMP_DATA_READ(15) <= A_SMP_DATA15;
    A_P_SMP_DATA_READ(14) <= A_SMP_DATA14;
    A_P_SMP_DATA_READ(13) <= A_SMP_DATA13;
    A_P_SMP_DATA_READ(12) <= A_SMP_DATA12;
    A_P_SMP_DATA_READ(11) <= A_SMP_DATA11;
    A_P_SMP_DATA_READ(10) <= A_SMP_DATA10;
    A_P_SMP_DATA_READ(9) <= A_SMP_DATA9;
    A_P_SMP_DATA_READ(8) <= A_SMP_DATA8;
    A_P_SMP_DATA_READ(7) <= A_SMP_DATA7;
    A_P_SMP_DATA_READ(6) <= A_SMP_DATA6;
    A_P_SMP_DATA_READ(5) <= A_SMP_DATA5;
    A_P_SMP_DATA_READ(4) <= A_SMP_DATA4;
    A_P_SMP_DATA_READ(3) <= A_SMP_DATA3;
    A_P_SMP_DATA_READ(2) <= A_SMP_DATA2;
    A_P_SMP_DATA_READ(1) <= A_SMP_DATA1;
    A_P_SMP_DATA_READ(0) <= A_SMP_DATA0;
    --tw(RDL) continued
    wait for 1 ns;
    A_SMP_RD_L <= 'H';
    if(A_SPACE = 'I') then
    A_SMP_IS_L <= 'H';
    elsif(A_SPACE = 'D') then
    A_SMP_DS_L <= 'H';
    elsif(A_SPACE = 'P') then
    A_SMP_PS_L <= 'H';
    end if;
    A_P_SMP_ADDR <= "LLL";

    tic(A_UPCLKOUT);

    end SMP_READ;


    As you can see, there are lots of IF and WAIT statements in there too.
    I'm wondering if there is some rule or something I have broken about
    using WAIT and IF statements? Is that procedure even normal looking,
    or is there a better way of doing what I am trying to do? (I am trying
    to have a procedure that simulates all the signals and associated
    timing from a microprocessor read cycle). Thank you thank you to
    anyone who has any suggestions!
     
    Toby, Feb 11, 2005
    #3
  4. Toby wrote:
    > I tried to add the tic thing, but it didnt seem to help. The procedure
    > posted earlier was simplified a bit. Here is the complete procedure
    > (including the tic call):


    Yikes. Consider a synchronous testbench
    using tic;tic;tic; instead of wait for 30ns;

    Do you have a clock and reset process working
    out through to the uut in and out signals?
    Get this working first.

    Do you have some base process wrapped around
    the procedure declarations run the show?


    -- Mike Treseler

    ___________________
    main : process is
    <declarations>
    constant reps : natural := 16;
    begin -- process main
    init;
    for i in 1 to reps loop
    timed_cycle;
    end loop;
    for i in 1 to reps loop
    handshake_cycle;
    end loop;
    coda;
    end process main;
    end architecture sim;
     
    Mike Treseler, Feb 11, 2005
    #4
  5. Toby

    Toby Guest

    Hi Mike,

    a synchronous testbench using tic; tic; tic, huh? Holy crap! I never
    thought of that! Thank you. I do quite a bit of VHDL, and I
    definitely understand the importance of synchronizing stuff, I just
    never thought to do it in a testbench. Is there anything wrong with
    doing tic = 1ps, and doing for loops like a thousand times? Because I
    have some stuff that has to be fractions of a nanosecond, and some
    stuff the is tens or hundreds of nanoseconds. And I want everything in
    my testbench to use the same tic process, right? Tic should be a
    process, not a procedure, right?

    I do have a clock and reset working throughout the uut.

    I dont understand your last comment about having a process wrapped
    around the procedure declarations. A procedure can go in a process? I
    didnt know that. You dont mean I need a single process for the whole
    testbench, do you? I've got a lot of stuff going on in this testbench,
    and a lot of it can happen at the same time (i.e. completely seperate
    logic in the uut). So I think I need seperate processes for that.
    Well, as you can see, any general type of advice about testbenches
    would be very helpful.

    Anyway, thank you so much! I will work on using that tic clock.

    -Toby
     
    Toby, Feb 14, 2005
    #5
  6. Toby

    Toby Guest

    Hi Mike,

    a synchronous testbench using tic; tic; tic, huh? Holy crap! I never
    thought of that! Thank you. I do quite a bit of VHDL, and I
    definitely understand the importance of synchronizing stuff, I just
    never thought to do it in a testbench. Is there anything wrong with
    doing tic = 1ps, and doing for loops like a thousand times? Because I
    have some stuff that has to be fractions of a nanosecond, and some
    stuff the is tens or hundreds of nanoseconds. And I want everything in
    my testbench to use the same tic process, right? Tic should be a
    process, not a procedure, right?

    I do have a clock and reset working throughout the uut.

    I dont understand your last comment about having a process wrapped
    around the procedure declarations. A procedure can go in a process? I
    didnt know that. You dont mean I need a single process for the whole
    testbench, do you? I've got a lot of stuff going on in this testbench,
    and a lot of it can happen at the same time (i.e. completely seperate
    logic in the uut). So I think I need seperate processes for that.
    Well, as you can see, any general type of advice about testbenches
    would be very helpful.

    Anyway, thank you so much! I will work on using that tic clock.

    -Toby
     
    Toby, Feb 14, 2005
    #6
  7. Toby wrote:

    > a synchronous testbench using tic; tic; tic, huh? Holy crap! I never
    > thought of that! Thank you. I do quite a bit of VHDL, and I
    > definitely understand the importance of synchronizing stuff, I just
    > never thought to do it in a testbench. Is there anything wrong with
    > doing tic = 1ps, and doing for loops like a thousand times? Because I
    > have some stuff that has to be fractions of a nanosecond, and some
    > stuff the is tens or hundreds of nanoseconds. And I want everything in
    > my testbench to use the same tic process, right? Tic should be a
    > process, not a procedure, right?


    No the other way around.

    I use one clock/reset generator process (see tb_clk below)
    and one main process. The main process is constructed
    out of procedure calls. The lowest level procedure
    (i.e. the top declaration) is tic, which waits for
    one system clock period. The other procedures
    call tic once, at the end, or not at all.
    All of the procedure calls, other than tic;
    execute in zero simulation time, so no, I don't
    need a 1 ps clock period. The clock is strictly
    for synchronization of uut stimulus and verification.

    > I do have a clock and reset working throughout the uut.


    That's a good start.

    > I dont understand your last comment about having a process wrapped
    > around the procedure declarations. A procedure can go in a process?


    The procedure *code* (declaration) for "do_this"
    is placed before the BEGIN of the
    main process *and* before any other.
    procedures that call "do_this"

    The procedure *call* "do_this;"
    must be placed either in a
    process or procedure after the BEGIN.

    > I didnt know that. You dont mean I need a single process for the whole
    > testbench, do you?


    I use at least two, tb_clk and main. In my last posting
    I showed the main process calls of a real testbench.
    All of the details are in the procedures that I cut out
    from the line <declarations>. When I get back from
    Utah, I will clean up a full example for the group.

    > I've got a lot of stuff going on in this testbench,
    > and a lot of it can happen at the same time (i.e. completely seperate
    > logic in the uut). So I think I need seperate processes for that.


    Yes sometimes you do.

    > Anyway, thank you so much! I will work on using that tic clock.


    You are welcome. Good luck

    -- Mike Treseler


    --____________________________________________
    tb_clk : process is
    constant clk_cy : time := 10 ns;
    constant rst_time : time := 100 ns;
    begin
    clk_s <= '0';
    if now < rst_time then
    rst_s <= '1'; -- rst once with clk running

    else
    rst_s <= '0'; -- then low forever
    end if;
    wait for clk_cy/2; -- clk rising
    clk_s <= '1';
    wait for clk_cy/2; -- clk falling
    if done_s then
    wait; -- Stop clock
    end if;
    end process tb_clk;
    -------------------------------------------------------------------------------
     
    Mike Treseler, Feb 14, 2005
    #7
  8. Mike Treseler wrote:
    >
    > --____________________________________________
    > tb_clk : process is
    > constant clk_cy : time := 10 ns;
    > constant rst_time : time := 100 ns;
    > begin
    > clk_s <= '0';
    > if now < rst_time then
    > rst_s <= '1'; -- rst once with clk running
    > else
    > rst_s <= '0'; -- then low forever
    > end if;
    > wait for clk_cy/2; -- clk rising
    > clk_s <= '1';
    > wait for clk_cy/2; -- clk falling
    > if done_s then
    > wait; -- Stop clock
    > end if;
    > end process tb_clk;
    > -------------------------------------------------------------------------------


    I would not combine the generation of the clock and reset:

    CONSTANT clk_cy : delay_length := 10 ns;
    CONSTANT rst_time : rst_time := 10*clk_cy;

    SIGNAL clk_s : std_ulogic := '0';
    SIGNAL rst_s : std_ulogic;
    SIGNAL done_s : boolean;

    clk_gen: clk_s <= '0' WHEN done_s ELSE NOT clk_s AFTER clk_cy/2;
    rst_gen: rst_s <= '1', '0' AFTER rst_time;

    Nice and short, just two lines. No needless evaluation of "now <
    rst_time". Surely it would make not much of a difference in simulation
    time, but I find my version better readable. Of course, this is a
    personal thing.

    The initial value of clk_s really is needed, or otherwise the clock
    always would be 'X'. Also note that by chosing '0' as initial value (in
    contrast to '1'), rst_s changes value at the falling edge of the clock
    (as in your example).

    Paul.
     
    Paul Uiterlinden, Feb 15, 2005
    #8
  9. Toby

    Toby Guest

    Can somebody either post, or tell me EXACTLY where to find a nice, BIG,
    COMPLETE, good, testbench example with all this stuff you guys are
    talking about? Several examples would be even better, but all this
    stuff you guys are showing me is just pieces, and I'm having a little
    trouble seeing the overall picture of a good testbench design. Thanks!

    -Toby
     
    Toby, Feb 15, 2005
    #9
  10. Toby wrote:
    > Can somebody either post, or tell me EXACTLY where to find a nice, BIG,
    > COMPLETE, good, testbench example with all this stuff you guys are
    > talking about? Several examples would be even better, but all this
    > stuff you guys are showing me is just pieces, and I'm having a little
    > trouble seeing the overall picture of a good testbench design. Thanks!


    My comments are incomplete, but here you go:

    http://home.comcast.net/~mike_treseler/

    -- Mike Treseler
     
    Mike Treseler, Feb 15, 2005
    #10
  11. Mike Treseler <> wrote in message news:<>...
    > Toby wrote:
    > > Can somebody either post, or tell me EXACTLY where to find a nice, BIG,
    > > COMPLETE, good, testbench example with all this stuff you guys are
    > > talking about? Several examples would be even better, but all this
    > > stuff you guys are showing me is just pieces, and I'm having a little
    > > trouble seeing the overall picture of a good testbench design. Thanks!

    >
    > My comments are incomplete, but here you go:
    >
    > http://home.comcast.net/~mike_treseler/
    >
    > -- Mike Treseler


    Hi,

    A very interesting example. There are a lot of things that are
    unfamiliar to me even if I have used VHDL for some years. Could you
    please explain the "init_out_variables" procedure that executes on
    every clock edge? Whats its purpose? Would it be possible for you
    (dont want to waste your time...) to explain more from basic, the
    structure of this example?

    Regards, Peter
     
    Peter Hermansson, Feb 17, 2005
    #11
  12. Toby

    Toby Guest

    Yes that is a very interesting example. It has completely changed the
    way I write testbenches, and I suspect it will also change the way I
    write my VHDL design files. Thank you Mike! Does anyone else have any
    COMPLETE testbench examples they can show me? I just love examples!
    Thanks again Mike, your the best!

    -Toby
     
    Toby, Feb 17, 2005
    #12
  13. it prevents double output registers.
    I will fill in the info files next week.

    -- Mike Treseler
     
    Mike Treseler, Feb 19, 2005
    #13
    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.
Similar Threads
  1. Joe Vanderwall
    Replies:
    11
    Views:
    855
    Peter Sommerfeld
    May 9, 2004
  2. Toby
    Replies:
    0
    Views:
    483
  3. Andrew FPGA
    Replies:
    7
    Views:
    1,157
    stephenmm
    Nov 1, 2008
  4. Mike P
    Replies:
    0
    Views:
    3,352
    Mike P
    Jun 19, 2006
  5. AlexWare
    Replies:
    2
    Views:
    780
    Paul Uiterlinden
    Oct 23, 2009
Loading...

Share This Page