1

I have a register read sequence that goes something like this:

extend vr_ad_sequence_kind: [READ_REG];
extend READ_REG vr_ad_sequence {
    // register to read
    reg_kind : vr_ad_reg_kind;
    !reg : vr_ad_reg;

    // more fields no longer shown here

    body() @driver.clock is {
        var reg_item : vr_ad_reg; // reg_item gets a value from a
                                  // method that returns the correct
                                  // register instance from the addr_map,
                                  // which I no longer want to show here

        reg = new vr_ad_reg with { .kind = reg_kind; };      
        read_reg { .static_item == reg_item; } reg;  
    };   
};

Now, I have a virtual sequence that does the vr_ad_sequence above:

extend MAIN MAIN_TEST sample_vseq {
    !reg_read   : READ_REG vr_ad_sequence;

    body() @driver.clock is first {
        do reg_read keeping {
            .driver == driver.reg_driver;
            .reg_kind == MY_REGISTER;
        };

        // how to get the value of MY_REGISTER.MY_FIELD from
        // the reg_read sequence above?
    };
};

My main objective is to read the value of a specific register bit field which is MY_FIELD in the above example. Is there a way to do it without modifying anything in the original READ_REG vr_ad_sequence? If it can't be helped, how do I make the READ_REG vr_ad_sequence return the read value to the calling sample_vseq?

Thanks very much in advance.

renvill
  • 143
  • 1
  • 10
  • Are you sure your BFM is updating your bus transactions with the data it reads? You need to have the proper infrastructure set up all along the vr_ad -> sequence_driver -> BFM chain. – Tudor Timi Dec 12 '16 at 08:46
  • @TudorTimi: Yes, actually after 'do'ing the `READ_REG` sequence, the vr_ad does a `compare_and_update_body()` which is getting the correct bus value, as I can see from this message -- please refer to the main question above. – renvill Dec 12 '16 at 09:22
  • hi, The sequence reg field is indeed expected to change by the read_reg action. And the value to be put in the register is the value returned by the vr_ad_execute_op() method (the method of the BFM driver). It can happen that the vr_ad_execute_op returns one value (0x4, in your example) and the monitor, calling compare_and_update - calls with another data (0). I suggest setting a break point at *.vr_ad_execute_op, and see the value it returns. – user3467290 Dec 12 '16 at 11:31
  • @user3467290: I simplified the main question as it seems confusing. My issue is not the different read values being returned by vr_ad_execute_op() and compare_and_update(). I simply wanted to know how to get the value of a specific register bit field if my `READ_REG vr_ad_sequence` is **do**ne from a `sample_vseq` virtual sequence, as shown in the 2 blocks of code above. – renvill Dec 13 '16 at 02:51

1 Answers1

1

To obtain the register value after the read you first must make sure that the read is finished on the bus. So either your BFM is blocking (which often it isn't) or you add a flag to the sequence that tells whether the response has been received (this can be set from the BFM/driver). Next, you can get the value from the vr_ad_map instance. E.g.

body() @driver.clock is first {
    do reg_read keeping {
        .driver == driver.reg_driver;
        .reg_kind == MY_REGISTER;
    };
    // Wait for read response
    sync true(reg_read != NULL and reg_read.done);
    // Access shadow register through pointer to vr_ad_map instance
    print addr_map.get_register_by_kind(MY_REGISTER).as_a(MY_REGISTER vr_ad_reg).MY_FIELD;
};

(I can't check the syntax right now)

Thorsten
  • 710
  • 8
  • 17
  • This solved the issue. The correct syntax would be: `print get_enclosing_unit(my_env_u).addr_map.get_reg_by_kind(MY_REGISTER).as_a(MY_REGISTER vr_ad_reg).MY_FIELD;` since I'm in a virtual sequence. The line is a bit long though, but it serves its purpose. Thanks very much! – renvill Dec 14 '16 at 02:50