tags:

views:

196

answers:

3

Hy,

I expanding an existing specman test where some code like this appears:

struct dataset {
  !register : int (bits:16);
  ... other members
}

...

data : list of dataset;
foo : dataset;
gen foo;

foo.register = 0xfe;
... assign other foo members ...
data.push(foo.copy());

is there a way to assign to the members of the struct in one line? like:

foo = { 0xff, ... };
+2  A: 

Hi Andreas,

I currently can't think of a direct way of setting all members as you want, but there is a way to initialize variables (I'm not sure if it works on struct members as well). Anyway something like the following may fit for you:

myfunc() is {
    var foo : dataset = new dataset with {
        .register = 0xff;
        .bar = 0xfa;
    }
    data.push(foo.copy());
}

You can find more information about new with help new struct from the specman prompt.

Hope it helps!

danielpoe
A: 

You can directly use the pack and unpack facility of Specman with "physical fields" ( those instance members prefixed with the modifier %).

Example:

define FLOODLES_WIDTH 47;
type floodles_t : uint(bits:FLOODLES_WIDTH);

define FLABNICKERS_WIDTH 28;
type flabnickers_t : uint(bits:FLABNICKERS_WIDTH);

struct foo_s {
   %!floodle : floodles_t;
   %!flabnicker : flabnickers_t;
};

extend sys {
   run() is also {
      var f : foo_s = new;
      unpack(packing.low,64'hdeadbeefdeadbeef,f);
      print f;

      unpack(packing.low,64'hacedacedacedaced,f);
      print f;

   };
   setup() is also {
      set_config(print,radix,hex);
   };
};

When this run, it prints:

Loading /nfs/pdx/home/rbroger1/tmp.e ...
read...parse...update...patch...h code...code...clean...
Doing setup ...
Generating the test using seed 1...

Starting the test ...
Running the test ...
  f = foo_s-@0: foo_s   of unit: sys
        ----------------------------------------------  @tmp
0       !%floodle:                      0x3eefdeadbeef
1       !%flabnicker:                   0x001bd5b
  f = foo_s-@0: foo_s   of unit: sys
        ----------------------------------------------  @tmp
0       !%floodle:                      0x2cedacedaced
1       !%flabnicker:                   0x00159db

Look up packing, unpacking, physical fields, packing.low, packing.high in your Specman docs.

You can still use physical fields even if the struct doesn't map to the DUT. If your struct is already using physical fields for some other purpose then you'll need to pursue some sort of set* method for that struct.

Ross Rogers
OMG! unpack! :) always treat unpack() as a non-type-safe constructor or API. it's so easy to forget these assignment, and there's no verifying code to keep you (or client of your code) alert.
Asaf
+1  A: 

the simple beuty of assigning fields by name is one language feature i've always found usefull , safe to code and readable.

this is how i'd go about it:

struct s {
  a : int;
  b : string;
  c : bit;
};

extend sys {
  ex() is {
    var s := new s with {.a = 0x0; .b = "zero"; .c = 0;};
  };
  run() is also {
    var s;
    gen s keeping {.a == 0x0; .b == "zero"; .c == 0;};
  };
};

i even do data.push(new dataset with {.reg = 0xff; bar = 0x0;}); but you may raise the readablity flag if you want.

warning: using unpack() is perfectly correct (see ross's answer), however error prone IMO. i recommend to verify (with code that actually runs) every place you opt to use unpack().

Asaf