Assistance with INOUT Records

Discussion in 'VHDL' started by Analog_Guy, Oct 18, 2006.

  1. Analog_Guy

    Analog_Guy Guest

    Hi ... I've been a bit stumped with all the issues I am having with
    records, when trying to implement a client/server approach between two
    entities.

    Basically, I keep getting X's in the simulation for cmd_rec.a and
    cmd_rec.b, even though they appear to be properly defined.

    The records are initialized at the ENTITY PORT level of the two
    components (test_ctrl_clv.vhd and cpu_bfm_clv.vhd). They are assigned
    in cpu_bfm_pkg_clv.vhd ... and this is when I get X's.

    I have noted two things:

    1. If I uncomment the assignment to cmd_rec.c in cpu_bfm_clv.vhd
    everything works fine! Why do I have to make a signal assignment to
    cmd_rec.c in order for this to work? The record element cmd_rec.c is
    already initialized to a value at the ENTITY PORT level ... isn't that
    good enough?

    2. If i leave the assignment to cmd_rec.c in cpu_bfm_clv.vhd commented
    out, and instead change CMD_REC_TYPE_INIT to all 'Z' entries everything
    works fine! I really want some of the signals to have initial values,
    so I didn't want to have to do this.

    What are the rules related to RECORDs to ensure I am not running into
    all these conflicts? I have chosen all RECORD elements to be STD_LOGIC
    so that they should all be resolved. I can't seem to find anything
    relevant in the LRM regarding this. What is the standard a




    A very simplified example (which compiles and simulates) is presented
    below:
    ************************************************************************************************
    1. TOP-LEVEL (tb_top_test_clv.vhd)
    --============================================
    -- General Library Declarations
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    USE ieee.numeric_std.ALL;
    --
    -- BFM Package Declarations
    LIBRARY rec_test;
    USE rec_test.cpu_bfm_pkg_clv;
    --
    --===============================================
    ENTITY tb_top_test_clv IS
    --
    END ENTITY tb_top_test_clv;
    --
    --================================================
    ARCHITECTURE tb OF tb_top_test_clv IS
    --
    -- DUT Interface Signals
    SIGNAL M_CTRL_CLK : STD_LOGIC; -- Main PLD clock.
    SIGNAL RESETn : STD_LOGIC; -- Main PLD reset.
    --
    -- Transaction Based Signals
    SIGNAL ctrl_rec : cpu_bfm_pkg_clv.CTRL_REC_TYPE;
    SIGNAL cmd_rec : cpu_bfm_pkg_clv.CMD_REC_TYPE;
    --
    --------------------------------------------------------------------------------
    -- COMPONENT DECLARATIONS
    -- ----------------------
    --
    COMPONENT test_ctrl_clv IS
    PORT (
    CLOCK : IN STD_LOGIC; -- Main PLD clock.
    RESETn : IN STD_LOGIC; -- Main PLD reset.
    ctrl_rec : INOUT cpu_bfm_pkg_clv.CTRL_REC_TYPE;
    cmd_rec : INOUT cpu_bfm_pkg_clv.CMD_REC_TYPE
    );
    END COMPONENT test_ctrl_clv;
    --
    --+++++++++++++++++++++++++++++++++++++++++++++++++
    COMPONENT cpu_bfm_clv IS
    PORT (
    CLOCK : IN STD_LOGIC; -- Main PLD clock.
    RESETn : IN STD_LOGIC; -- Main PLD reset.
    ctrl_rec : INOUT cpu_bfm_pkg_clv.CTRL_REC_TYPE;
    cmd_rec : INOUT cpu_bfm_pkg_clv.CMD_REC_TYPE
    );
    END COMPONENT cpu_bfm_clv;
    --
    --------------------------------------------------------------------------------
    BEGIN
    --
    -- COMPONENT INSTANTIATIONS
    -- ------------------------
    test_ctrl_u1 : test_ctrl_clv
    PORT MAP (
    CLOCK => M_CTRL_CLK,
    RESETn => RESETn,
    ctrl_rec => ctrl_rec,
    cmd_rec => cmd_rec
    );
    --
    --+++++++++++++++++++++++++++++++++++++++++++++++++
    cpu_bfm_u1 : cpu_bfm_clv
    PORT MAP (
    CLOCK => M_CTRL_CLK,
    RESETn => RESETn,
    ctrl_rec => ctrl_rec,
    cmd_rec => cmd_rec
    );
    --
    END ARCHITECTURE tb;
    --
    --=========================================




    **************************************************************************************************
    2. TEST CONTROL (test_ctrl_clv.vhd)
    --=====================================================
    -- General Library Declarations
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    --
    -- BFM Package Declarations
    LIBRARY rec_test;
    USE rec_test.cpu_bfm_pkg_clv;
    --
    --===================================================
    ENTITY test_ctrl_clv IS
    PORT (
    CLOCK : IN STD_LOGIC;
    RESETn : IN STD_LOGIC;
    ctrl_rec : INOUT cpu_bfm_pkg_clv.CTRL_REC_TYPE :=
    cpu_bfm_pkg_clv.CTRL_REC_TYPE_INIT;
    cmd_rec : INOUT cpu_bfm_pkg_clv.CMD_REC_TYPE :=
    cpu_bfm_pkg_clv.CMD_REC_TYPE_INIT
    );
    END ENTITY test_ctrl_clv;
    --
    --================================================
    ARCHITECTURE behav OF test_ctrl_clv IS
    BEGIN
    --
    main_testcase : PROCESS
    BEGIN
    WAIT UNTIL RISING_EDGE(RESETn);
    -- Exercise CPU READs
    cpu_bfm_pkg_clv.cpu_read(X"0000_0000", X"A5A5_A5A5_A5A5_A5A5",
    ctrl_rec, cmd_rec);
    cpu_bfm_pkg_clv.cpu_read(X"0000_0001", X"5A5A_5A5A_5A5A_5A5A",
    ctrl_rec, cmd_rec);
    -- Extend Simulation Time
    WAIT FOR 1000 ns;
    -- Terminate Simulation (Current settings in ModelSim break simulation
    on severity
    -- level of FAILURE)
    ASSERT (FALSE)
    REPORT "*** Ignore Failure *** : Simulator Terminated Normally!"
    SEVERITY FAILURE;
    -- Suspend Process
    WAIT;
    END PROCESS main_testcase;
    END ARCHITECTURE behav;
    --
    --=========================================




    *********************************************************************************
    3. BFM PACKAGE (cpu_bfm_pkg_clv.vhd)
    --============================================
    -- General Library Declarations
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    --
    --=============================================
    PACKAGE cpu_bfm_pkg_clv IS
    -- Transaction Record Declarations
    TYPE CTRL_REC_TYPE IS RECORD
    req : STD_LOGIC;
    ack : STD_LOGIC;
    END RECORD CTRL_REC_TYPE;

    TYPE CMD_REC_TYPE IS RECORD
    a : STD_LOGIC;
    b : STD_LOGIC;
    c : STD_LOGIC;
    END RECORD CMD_REC_TYPE;
    --
    --++++++++++++++++++++++++++++++++++++++++++
    -- Transaction Record Initializations
    CONSTANT CTRL_REC_TYPE_INIT : CTRL_REC_TYPE :=
    ( req => '0',
    ack => 'Z');

    CONSTANT CMD_REC_TYPE_INIT : CMD_REC_TYPE :=
    ( a => 'Z',
    b => 'Z',
    c => 'Z'
    );
    --
    --------------------------------------------------------------------------------
    -- CPU BFM PROCEDURE DECLARATIONS
    -- ------------------------------
    --
    -- Transaction Level Read
    -- ----------------------
    PROCEDURE cpu_read ( CONSTANT addr : IN STD_LOGIC_VECTOR;
    CONSTANT data : IN STD_LOGIC_VECTOR;
    SIGNAL ctrl_rec : INOUT CTRL_REC_TYPE;
    SIGNAL cmd_rec : INOUT CMD_REC_TYPE
    );
    --
    END PACKAGE cpu_bfm_pkg_clv;
    --
    --===================================================
    PACKAGE BODY cpu_bfm_pkg_clv IS
    --
    -- CPU BFM PROCEDURE DEFINITIONS
    -- -----------------------------
    --
    -- Transaction Level Read
    -- ----------------------
    PROCEDURE cpu_read ( CONSTANT addr : IN STD_LOGIC_VECTOR;
    CONSTANT data : IN STD_LOGIC_VECTOR;
    SIGNAL ctrl_rec : INOUT CTRL_REC_TYPE;
    SIGNAL cmd_rec : INOUT CMD_REC_TYPE) IS
    BEGIN
    -- Put Transaction into Record
    cmd_rec.a <= '0';
    cmd_rec.b <= '1';
    -- Handshake with BFM
    ctrl_rec.req <= NOT(ctrl_rec.req);
    WAIT UNTIL ctrl_rec.ack'ACTIVE;
    END PROCEDURE cpu_read;
    --
    END PACKAGE BODY cpu_bfm_pkg_clv;
    --
    --============================================




    ****************************************************************************************
    4. BFM (cpu_bfm_clv.vhd)
    --================================================
    -- General Library Declarations
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    --
    -- BFM Package Declarations
    LIBRARY rec_test;
    USE rec_test.cpu_bfm_pkg_clv;
    --
    ================================================
    ENTITY cpu_bfm_clv IS
    PORT (
    CLOCK : IN STD_LOGIC;
    RESETn : IN STD_LOGIC;
    ctrl_rec : INOUT cpu_bfm_pkg_clv.CTRL_REC_TYPE :=
    cpu_bfm_pkg_clv.CTRL_REC_TYPE_INIT;
    cmd_rec : INOUT cpu_bfm_pkg_clv.CMD_REC_TYPE :=
    cpu_bfm_pkg_clv.CMD_REC_TYPE_INIT
    );
    END ENTITY cpu_bfm_clv;
    --
    --================================================
    ARCHITECTURE behav OF cpu_bfm_clv IS
    --
    BEGIN
    --
    -- INTERFACE SPECIFICATION
    -- -----------------------
    --
    -- CPU READ Control
    -- ----------------
    bfm_ctrl_1 : PROCESS
    BEGIN
    IF (RESETn = '0') THEN
    ctrl_rec.ack <= '0';
    ELSIF (ctrl_rec.req'ACTIVE) THEN
    -- Execute Functionality.
    WAIT UNTIL CLOCK = '1' and CLOCK'EVENT;
    -- cmd_rec.c <= '1' AFTER 5 ns;
    WAIT FOR 100 ns;
    WAIT UNTIL CLOCK = '1' and CLOCK'EVENT;
    ctrl_rec.ack <= NOT(ctrl_rec.ack); -- Toggle acknowledge to
    Client, indicating end of access.
    END IF;
    WAIT ON RESETn, ctrl_rec;
    END PROCESS bfm_ctrl_1;
    --
    END ARCHITECTURE behav;
    --
    --=========================================



    Sorry for the length of the post, I am not sure how to attach files
    instead of just copying the text.

    Your comments would be appreciated.
     
    Analog_Guy, Oct 18, 2006
    #1
    1. Advertising

  2. Analog_Guy

    Analog_Guy Guest

    Analog_Guy wrote:

    > I have noted two things:
    >
    > 1. If I uncomment the assignment to cmd_rec.c in cpu_bfm_clv.vhd
    > everything works fine! Why do I have to make a signal assignment to
    > cmd_rec.c in order for this to work? The record element cmd_rec.c is
    > already initialized to a value at the ENTITY PORT level ... isn't that
    > good enough?
    >
    > 2. If i leave the assignment to cmd_rec.c in cpu_bfm_clv.vhd commented
    > out, and instead change CMD_REC_TYPE_INIT to all 'Z' entries everything
    > works fine! I really want some of the signals to have initial values,
    > so I didn't want to have to do this.
    >


    OOPS ... the code presented actually contains the RECORD
    initializations mentioned in point #2 above.

    The actual RECORD assignment that produces the X's is as follows
    (cpu_bfm_pkg_clv.vhd):

    CONSTANT CMD_REC_TYPE_INIT : CMD_REC_TYPE :=
    ( a => '1',
    b => '0',
    c => 'Z'
    );


    Thanks.
     
    Analog_Guy, Oct 18, 2006
    #2
    1. Advertising

  3. Analog_Guy

    Jim Lewis Guest

    Analog_Guy,
    To communicate through the record, one side has to
    drive an inactive value ('Z') while the other side
    drives an active value ('0' or '1').

    There are numerous ways to accomplish this. For example:
    1)
    Initialize ports to all 'Z' with a constant.
    Driving side can drive when appropriate.
    Complication:
    Does starting at 'Z' break anything in your model?
    It does make doing an initial not on a signal difficult.
    For one model I create a constant to toggle values - see below.

    type stdulogic_indexby_stdulogic is array (std_ulogic) of std_ulogic;
    constant toggle_sl_table : stdulogic_indexby_stdulogic := (
    '0' => '1',
    'L' => '1',
    others => '0'
    );

    Are your storing any long term values in the record?
    In the _past_, I would store error counts in the record -
    somewhere these would need to get initialized so I used method 2.
    Now I store error counts in the model and have written a
    transaction that has it display a summary and return an error count.

    2)
    Initialize each side ports to specific values.
    An element must be initialized to 'Z' if the model does
    not drive it.
    Initialize important signals the model drives to a valid value.
    This is where I formerly initialized error counts.

    CONSTANT TEST_CTRL_CMD_REC_INIT : CMD_REC_TYPE :=
    ( a => '1',
    b => '0',
    c => 'Z'
    );

    CONSTANT CPU_BFM_CMD_REC_INIT : CMD_REC_TYPE :=
    ( a => 'Z',
    b => 'Z',
    c => '1'
    );

    3)
    Don't initialize ports.
    In the process that drives the record, assign elements
    the model does not drive to 'Z' (early) and assign elements
    the model does drive to an appropriate starting value.


    I used to think the records worked only with std_logic
    family and 'Z', however, recently I realized that this
    can be done for any resolved type with the right resolution
    functions. I have some proof of concept stuff working with
    integer and time, but based on this, it can work for anything.
    My big hang up was that std_logic lulled me into thinking
    I needed a type to have a non-driving value. Instead think
    of a wired or with an identity value (such as 0) as the
    non-driving value. I will be writing a paper on this soon.

    Cheers,
    Jim

    P.S. (and now the short advertisement)
    SynthWorks teaches these techniques in our
    VHDL Testbenches and Verification classes.
    --
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Jim Lewis
    Director of Training mailto:
    SynthWorks Design Inc. http://www.SynthWorks.com
    1-503-590-4787

    Expert VHDL Training for Hardware Design and Verification
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~





    > Hi ... I've been a bit stumped with all the issues I am having with
    > records, when trying to implement a client/server approach between two
    > entities.
    >
    > Basically, I keep getting X's in the simulation for cmd_rec.a and
    > cmd_rec.b, even though they appear to be properly defined.
    >
    > The records are initialized at the ENTITY PORT level of the two
    > components (test_ctrl_clv.vhd and cpu_bfm_clv.vhd). They are assigned
    > in cpu_bfm_pkg_clv.vhd ... and this is when I get X's.
    >
    > I have noted two things:
    >
    > 1. If I uncomment the assignment to cmd_rec.c in cpu_bfm_clv.vhd
    > everything works fine! Why do I have to make a signal assignment to
    > cmd_rec.c in order for this to work? The record element cmd_rec.c is
    > already initialized to a value at the ENTITY PORT level ... isn't that
    > good enough?
    >
    > 2. If i leave the assignment to cmd_rec.c in cpu_bfm_clv.vhd commented
    > out, and instead change CMD_REC_TYPE_INIT to all 'Z' entries everything
    > works fine! I really want some of the signals to have initial values,
    > so I didn't want to have to do this.
    >
    > What are the rules related to RECORDs to ensure I am not running into
    > all these conflicts? I have chosen all RECORD elements to be STD_LOGIC
    > so that they should all be resolved. I can't seem to find anything
    > relevant in the LRM regarding this. What is the standard a
    >
    >
    >
    >
    > A very simplified example (which compiles and simulates) is presented
    > below:
    > ************************************************************************************************
    > 1. TOP-LEVEL (tb_top_test_clv.vhd)
    > --============================================
    > -- General Library Declarations
    > LIBRARY ieee;
    > USE ieee.std_logic_1164.ALL;
    > USE ieee.numeric_std.ALL;
    > --
    > -- BFM Package Declarations
    > LIBRARY rec_test;
    > USE rec_test.cpu_bfm_pkg_clv;
    > --
    > --===============================================
    > ENTITY tb_top_test_clv IS
    > --
    > END ENTITY tb_top_test_clv;
    > --
    > --================================================
    > ARCHITECTURE tb OF tb_top_test_clv IS
    > --
    > -- DUT Interface Signals
    > SIGNAL M_CTRL_CLK : STD_LOGIC; -- Main PLD clock.
    > SIGNAL RESETn : STD_LOGIC; -- Main PLD reset.
    > --
    > -- Transaction Based Signals
    > SIGNAL ctrl_rec : cpu_bfm_pkg_clv.CTRL_REC_TYPE;
    > SIGNAL cmd_rec : cpu_bfm_pkg_clv.CMD_REC_TYPE;
    > --
    > --------------------------------------------------------------------------------
    > -- COMPONENT DECLARATIONS
    > -- ----------------------
    > --
    > COMPONENT test_ctrl_clv IS
    > PORT (
    > CLOCK : IN STD_LOGIC; -- Main PLD clock.
    > RESETn : IN STD_LOGIC; -- Main PLD reset.
    > ctrl_rec : INOUT cpu_bfm_pkg_clv.CTRL_REC_TYPE;
    > cmd_rec : INOUT cpu_bfm_pkg_clv.CMD_REC_TYPE
    > );
    > END COMPONENT test_ctrl_clv;
    > --
    > --+++++++++++++++++++++++++++++++++++++++++++++++++
    > COMPONENT cpu_bfm_clv IS
    > PORT (
    > CLOCK : IN STD_LOGIC; -- Main PLD clock.
    > RESETn : IN STD_LOGIC; -- Main PLD reset.
    > ctrl_rec : INOUT cpu_bfm_pkg_clv.CTRL_REC_TYPE;
    > cmd_rec : INOUT cpu_bfm_pkg_clv.CMD_REC_TYPE
    > );
    > END COMPONENT cpu_bfm_clv;
    > --
    > --------------------------------------------------------------------------------
    > BEGIN
    > --
    > -- COMPONENT INSTANTIATIONS
    > -- ------------------------
    > test_ctrl_u1 : test_ctrl_clv
    > PORT MAP (
    > CLOCK => M_CTRL_CLK,
    > RESETn => RESETn,
    > ctrl_rec => ctrl_rec,
    > cmd_rec => cmd_rec
    > );
    > --
    > --+++++++++++++++++++++++++++++++++++++++++++++++++
    > cpu_bfm_u1 : cpu_bfm_clv
    > PORT MAP (
    > CLOCK => M_CTRL_CLK,
    > RESETn => RESETn,
    > ctrl_rec => ctrl_rec,
    > cmd_rec => cmd_rec
    > );
    > --
    > END ARCHITECTURE tb;
    > --
    > --=========================================
    >
    >
    >
    >
    > **************************************************************************************************
    > 2. TEST CONTROL (test_ctrl_clv.vhd)
    > --=====================================================
    > -- General Library Declarations
    > LIBRARY ieee;
    > USE ieee.std_logic_1164.ALL;
    > --
    > -- BFM Package Declarations
    > LIBRARY rec_test;
    > USE rec_test.cpu_bfm_pkg_clv;
    > --
    > --===================================================
    > ENTITY test_ctrl_clv IS
    > PORT (
    > CLOCK : IN STD_LOGIC;
    > RESETn : IN STD_LOGIC;
    > ctrl_rec : INOUT cpu_bfm_pkg_clv.CTRL_REC_TYPE :=
    > cpu_bfm_pkg_clv.CTRL_REC_TYPE_INIT;
    > cmd_rec : INOUT cpu_bfm_pkg_clv.CMD_REC_TYPE :=
    > cpu_bfm_pkg_clv.CMD_REC_TYPE_INIT
    > );
    > END ENTITY test_ctrl_clv;
    > --
    > --================================================
    > ARCHITECTURE behav OF test_ctrl_clv IS
    > BEGIN
    > --
    > main_testcase : PROCESS
    > BEGIN
    > WAIT UNTIL RISING_EDGE(RESETn);
    > -- Exercise CPU READs
    > cpu_bfm_pkg_clv.cpu_read(X"0000_0000", X"A5A5_A5A5_A5A5_A5A5",
    > ctrl_rec, cmd_rec);
    > cpu_bfm_pkg_clv.cpu_read(X"0000_0001", X"5A5A_5A5A_5A5A_5A5A",
    > ctrl_rec, cmd_rec);
    > -- Extend Simulation Time
    > WAIT FOR 1000 ns;
    > -- Terminate Simulation (Current settings in ModelSim break simulation
    > on severity
    > -- level of FAILURE)
    > ASSERT (FALSE)
    > REPORT "*** Ignore Failure *** : Simulator Terminated Normally!"
    > SEVERITY FAILURE;
    > -- Suspend Process
    > WAIT;
    > END PROCESS main_testcase;
    > END ARCHITECTURE behav;
    > --
    > --=========================================
    >
    >
    >
    >
    > *********************************************************************************
    > 3. BFM PACKAGE (cpu_bfm_pkg_clv.vhd)
    > --============================================
    > -- General Library Declarations
    > LIBRARY ieee;
    > USE ieee.std_logic_1164.ALL;
    > --
    > --=============================================
    > PACKAGE cpu_bfm_pkg_clv IS
    > -- Transaction Record Declarations
    > TYPE CTRL_REC_TYPE IS RECORD
    > req : STD_LOGIC;
    > ack : STD_LOGIC;
    > END RECORD CTRL_REC_TYPE;
    >
    > TYPE CMD_REC_TYPE IS RECORD
    > a : STD_LOGIC;
    > b : STD_LOGIC;
    > c : STD_LOGIC;
    > END RECORD CMD_REC_TYPE;
    > --
    > --++++++++++++++++++++++++++++++++++++++++++
    > -- Transaction Record Initializations
    > CONSTANT CTRL_REC_TYPE_INIT : CTRL_REC_TYPE :=
    > ( req => '0',
    > ack => 'Z');
    >
    > CONSTANT CMD_REC_TYPE_INIT : CMD_REC_TYPE :=
    > ( a => 'Z',
    > b => 'Z',
    > c => 'Z'
    > );
    > --
    > --------------------------------------------------------------------------------
    > -- CPU BFM PROCEDURE DECLARATIONS
    > -- ------------------------------
    > --
    > -- Transaction Level Read
    > -- ----------------------
    > PROCEDURE cpu_read ( CONSTANT addr : IN STD_LOGIC_VECTOR;
    > CONSTANT data : IN STD_LOGIC_VECTOR;
    > SIGNAL ctrl_rec : INOUT CTRL_REC_TYPE;
    > SIGNAL cmd_rec : INOUT CMD_REC_TYPE
    > );
    > --
    > END PACKAGE cpu_bfm_pkg_clv;
    > --
    > --===================================================
    > PACKAGE BODY cpu_bfm_pkg_clv IS
    > --
    > -- CPU BFM PROCEDURE DEFINITIONS
    > -- -----------------------------
    > --
    > -- Transaction Level Read
    > -- ----------------------
    > PROCEDURE cpu_read ( CONSTANT addr : IN STD_LOGIC_VECTOR;
    > CONSTANT data : IN STD_LOGIC_VECTOR;
    > SIGNAL ctrl_rec : INOUT CTRL_REC_TYPE;
    > SIGNAL cmd_rec : INOUT CMD_REC_TYPE) IS
    > BEGIN
    > -- Put Transaction into Record
    > cmd_rec.a <= '0';
    > cmd_rec.b <= '1';
    > -- Handshake with BFM
    > ctrl_rec.req <= NOT(ctrl_rec.req);
    > WAIT UNTIL ctrl_rec.ack'ACTIVE;
    > END PROCEDURE cpu_read;
    > --
    > END PACKAGE BODY cpu_bfm_pkg_clv;
    > --
    > --============================================
    >
    >
    >
    >
    > ****************************************************************************************
    > 4. BFM (cpu_bfm_clv.vhd)
    > --================================================
    > -- General Library Declarations
    > LIBRARY ieee;
    > USE ieee.std_logic_1164.ALL;
    > --
    > -- BFM Package Declarations
    > LIBRARY rec_test;
    > USE rec_test.cpu_bfm_pkg_clv;
    > --
    > ================================================
    > ENTITY cpu_bfm_clv IS
    > PORT (
    > CLOCK : IN STD_LOGIC;
    > RESETn : IN STD_LOGIC;
    > ctrl_rec : INOUT cpu_bfm_pkg_clv.CTRL_REC_TYPE :=
    > cpu_bfm_pkg_clv.CTRL_REC_TYPE_INIT;
    > cmd_rec : INOUT cpu_bfm_pkg_clv.CMD_REC_TYPE :=
    > cpu_bfm_pkg_clv.CMD_REC_TYPE_INIT
    > );
    > END ENTITY cpu_bfm_clv;
    > --
    > --================================================
    > ARCHITECTURE behav OF cpu_bfm_clv IS
    > --
    > BEGIN
    > --
    > -- INTERFACE SPECIFICATION
    > -- -----------------------
    > --
    > -- CPU READ Control
    > -- ----------------
    > bfm_ctrl_1 : PROCESS
    > BEGIN
    > IF (RESETn = '0') THEN
    > ctrl_rec.ack <= '0';
    > ELSIF (ctrl_rec.req'ACTIVE) THEN
    > -- Execute Functionality.
    > WAIT UNTIL CLOCK = '1' and CLOCK'EVENT;
    > -- cmd_rec.c <= '1' AFTER 5 ns;
    > WAIT FOR 100 ns;
    > WAIT UNTIL CLOCK = '1' and CLOCK'EVENT;
    > ctrl_rec.ack <= NOT(ctrl_rec.ack); -- Toggle acknowledge to
    > Client, indicating end of access.
    > END IF;
    > WAIT ON RESETn, ctrl_rec;
    > END PROCESS bfm_ctrl_1;
    > --
    > END ARCHITECTURE behav;
    > --
    > --=========================================
    >
    >
    >
    > Sorry for the length of the post, I am not sure how to attach files
    > instead of just copying the text.
    >
    > Your comments would be appreciated.
    >
     
    Jim Lewis, Oct 18, 2006
    #3
  4. Analog_Guy

    Analog_Guy Guest

    Jim Lewis wrote:
    > Analog_Guy,
    > To communicate through the record, one side has to
    > drive an inactive value ('Z') while the other side
    > drives an active value ('0' or '1').
    >
    > There are numerous ways to accomplish this. For example:
    > 1)
    > Initialize ports to all 'Z' with a constant.
    > Driving side can drive when appropriate.
    > Complication:
    > Does starting at 'Z' break anything in your model?
    > It does make doing an initial not on a signal difficult.
    > For one model I create a constant to toggle values - see below.
    >
    > type stdulogic_indexby_stdulogic is array (std_ulogic) of std_ulogic;
    > constant toggle_sl_table : stdulogic_indexby_stdulogic := (
    > '0' => '1',
    > 'L' => '1',
    > others => '0'
    > );
    >
    > Are your storing any long term values in the record?
    > In the _past_, I would store error counts in the record -
    > somewhere these would need to get initialized so I used method 2.
    > Now I store error counts in the model and have written a
    > transaction that has it display a summary and return an error count.
    >
    > 2)
    > Initialize each side ports to specific values.
    > An element must be initialized to 'Z' if the model does
    > not drive it.
    > Initialize important signals the model drives to a valid value.
    > This is where I formerly initialized error counts.
    >
    > CONSTANT TEST_CTRL_CMD_REC_INIT : CMD_REC_TYPE :=
    > ( a => '1',
    > b => '0',
    > c => 'Z'
    > );
    >
    > CONSTANT CPU_BFM_CMD_REC_INIT : CMD_REC_TYPE :=
    > ( a => 'Z',
    > b => 'Z',
    > c => '1'
    > );
    >
    > 3)
    > Don't initialize ports.
    > In the process that drives the record, assign elements
    > the model does not drive to 'Z' (early) and assign elements
    > the model does drive to an appropriate starting value.
    >
    >
    > I used to think the records worked only with std_logic
    > family and 'Z', however, recently I realized that this
    > can be done for any resolved type with the right resolution
    > functions. I have some proof of concept stuff working with
    > integer and time, but based on this, it can work for anything.
    > My big hang up was that std_logic lulled me into thinking
    > I needed a type to have a non-driving value. Instead think
    > of a wired or with an identity value (such as 0) as the
    > non-driving value. I will be writing a paper on this soon.
    >
    > Cheers,
    > Jim
    >
    > P.S. (and now the short advertisement)
    > SynthWorks teaches these techniques in our
    > VHDL Testbenches and Verification classes.
    > --
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > Jim Lewis
    > Director of Training mailto:
    > SynthWorks Design Inc. http://www.SynthWorks.com
    > 1-503-590-4787
    >
    > Expert VHDL Training for Hardware Design and Verification
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    >
    >
    >

    Jim,

    Thank you very much for the response ... it is greatly appreciated.
    All three approaches you suggest make sense ... I think I am leaning
    towards Option #2 (because signals are all assigned at time 0, and I
    don't have to make initializations within the processes).

    Do you know why the simulation "broke" in my example? The one record
    subelement I didn't create a signal assignment for, caused the other
    two to be invalid. It was initialized to Z at the ports of both
    components it is connected between. Does failing to create a signal
    assignment for one subelement of the record cause problems with the
    whole record?

    I have not convinced myself that it is related, but LRM 2000
    (1.1.1.2-105) states "It is an error if some of the subelements of a
    composite formal port are connected and others are either unconnected
    or unassociated." Doesn't assigning Z to a subelement that has no
    other signal assignments count as creating a driver for that
    subelement?


    Thanks.
     
    Analog_Guy, Oct 19, 2006
    #4
  5. Jim Lewis wrote:

    > I used to think the records worked only with std_logic
    > family and 'Z', however, recently I realized that this
    > can be done for any resolved type with the right resolution
    > functions.


    Would that be by any chance after reading a post in comp.lang.vhdl on
    September 16, 2006? ;-)

    --
    Paul.
    www.aimcom.nl
     
    Paul Uiterlinden, Oct 19, 2006
    #5
  6. Analog_Guy

    Jim Lewis Guest

    Paul,
    >> I used to think the records worked only with std_logic
    >> family and 'Z', however, recently I realized that this
    >> can be done for any resolved type with the right resolution
    >> functions.

    >
    > Would that be by any chance after reading a post in comp.lang.vhdl on
    > September 16, 2006? ;-)


    Actually no, as I would have attributed it to you then.
    I do like your approach though. If I do adopt and/or modify
    your approach do you mind if I cite your name? I don't read
    all of the posts here - I wish I had seen yours sooner.
    Did you know you did more than one post on the 16th :).

    BTW with ideas like yours should be participating in the
    Accellera VHDL technical subcommittee and its subgroups.


    Currently I do all of the handshaking in std_logic so it
    is already resolved. It was dealing with the other
    items that are more naturally represented as integer, time,
    real that I was have trouble with. For these, I am switching
    to a resolution function that revolves around having identity
    values (such as 0) in the type and "wire-or"ing them
    together (something I would have thought of much sooner if
    only I was 5 years older. For this to work of course, the
    models have to cooperate by driving the identity value
    on the net when they are not driving (0, 0 ns, 0.0) respectively.

    The resolution function I use by the way is based on one
    Ofer Hofman of Sital showed me shortly after your post
    (however he was using it for something entirely different).
    I posted one for real in my post on 9/30/2006 with the title
    "Re: VHDL switch in real numbers."

    Cheers,
    Jim
    --
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Jim Lewis
    Director of Training mailto:
    SynthWorks Design Inc. http://www.SynthWorks.com
    1-503-590-4787

    Expert VHDL Training for Hardware Design and Verification
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     
    Jim Lewis, Oct 19, 2006
    #6
  7. Jim Lewis wrote:

    > Paul,
    > >> I used to think the records worked only with std_logic
    > >> family and 'Z', however, recently I realized that this
    > >> can be done for any resolved type with the right resolution
    > >> functions.

    > >
    > > Would that be by any chance after reading a post in
    > > comp.lang.vhdl on
    > > September 16, 2006? ;-)

    >
    > Actually no, as I would have attributed it to you then.


    Ah, ok. I was just curious.

    > I do like your approach though. If I do adopt and/or modify
    > your approach do you mind if I cite your name?


    Be my guest, I would be honored. Just make sure you spell my name
    right. ;-)

    And if possible, I would like to know of any adoptations/modifications
    you have in mind. Sometimes nice things are created if ideas are
    bounced back and forth a few times.

    > I don't read
    > all of the posts here - I wish I had seen yours sooner.
    > Did you know you did more than one post on the 16th :).


    Oops, I missed that. Sorry for the confusion it may have caused.

    > BTW with ideas like yours should be participating in the
    > Accellera VHDL technical subcommittee and its subgroups.


    Actually, this idea has been dormant in my mind for some time now.
    Perhaps it's time to actually do that. How is this organized? Is it
    via mailing lists?

    > Currently I do all of the handshaking in std_logic so it
    > is already resolved. It was dealing with the other
    > items that are more naturally represented as integer, time,
    > real that I was have trouble with. For these, I am switching
    > to a resolution function that revolves around having identity
    > values (such as 0) in the type and "wire-or"ing them
    > together (something I would have thought of much sooner if
    > only I was 5 years older. For this to work of course, the
    > models have to cooperate by driving the identity value
    > on the net when they are not driving (0, 0 ns, 0.0) respectively.


    Yep, you're right about the cooperativeness. I dealt with the same
    problem. I use the req and ack record members. Only one model may
    send an ack. This however is not a real problem, because I only use
    one model per cmd signal. If a model is instantiated multiple times,
    there also are multiple cmd signals. If you don't do that, you cannot
    have real concurrency between these models.

    Because the signal is resolved anyway, sending request (commands) from
    different processes is allowed. One limitation though: they may not
    occur at exact the same time. This is guarded in the resolution
    function by an assert statement.

    To make it just a bit more versatile, I added another record memmer to
    the cmd type. This member is called prio (not shown in my post to
    keep it simple). As you may have guessed, clients may put a priority
    on their request. The cooperativeness with regard of the priority
    part is included in my do_req procedure. The resolution function
    returns the highest priority and the do_req function checks if the
    returned priority is its own. If not, it backs off and waits for the
    other command the finish and then tries again.

    The only limitation now is that no two requests may occur at the same
    time with the same priority.

    With this, you can do neat things, such as creating a low priority
    background process, while your actual testcase does its stuff using a
    higher priority.

    --
    Paul.
    www.aimcom.nl
    email address: switch x and s.
     
    Paul Uiterlinden, Oct 22, 2006
    #7
    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. Luke Airig
    Replies:
    0
    Views:
    823
    Luke Airig
    Dec 31, 2003
  2. =?ISO-8859-15?Q?Fr=E9d=E9ric_Lochon?=

    connecting std_logic inout ports and std_logic_vector inout port

    =?ISO-8859-15?Q?Fr=E9d=E9ric_Lochon?=, Nov 6, 2007, in forum: VHDL
    Replies:
    3
    Views:
    902
  3. Ken

    inout to inout

    Ken, May 9, 2008, in forum: VHDL
    Replies:
    2
    Views:
    663
    Aiken
    May 9, 2008
  4. THurkmans
    Replies:
    14
    Views:
    1,962
    Mike Treseler
    Aug 11, 2009
  5. Dan

    Delete records or update records

    Dan, May 10, 2004, in forum: ASP General
    Replies:
    1
    Views:
    490
    Ray at
    May 10, 2004
Loading...

Share This Page