Specman e: Is there a way to extend multiple kinds of a struct? - specman

in my verification environment we work with vr_ad UVM package, where there is a general struct for a register vr_ad_reg which has been extended with different type for every register in the environment, etc:
reg_def TIMER_LOAD_0 TIMER 20'h00010 {
reg_fld timer_load : uint : RW : 0xffff;
}:
The vr_ad_reg has predefined function post_access(), which I would like to extend for every register type that starts with the word 'TIMER'. Is there a way to do it? For example:
extend TIMER_* vr_ad_reg { //The intention here to extend the vr_ad_reg for all types that starts with the word TIMER
post_access() is also {
var some_var : uint;
};
}
Thank you for your help

There's no built in construct to extend multiple sub-types. What you can do however is use a macro based solution. Team Specman had a blog post on this topic: http://www.cadence.com/Community/blogs/fv/archive/2009/10/20/extending-multiple-when-subtypes-simultaneously.aspx
They created a define as computed macro that takes multiple sub-types and extends those:
define <multi_when'statement> "extend \[<detr'name>,...\] <base'type> (<MEMBERS {<struct_member>;...})" as computed {
for each in <detr'names> do {
result = appendf("%s extend %s %s %s;",result,it,<base'type>,<MEMBERS>);
};
};
You can then use like so:
extend [ TIMER_LOAD_0, TIMER_LOAD_1, TIMER_LOAD_2 ] vr_ad_reg {
post_access() is also {
// ...
};
};

If you have a lot of registers that match your expression or you don't know the exact name beforehand, you might want to consider using a run-time solution:
extend vr_reg {
post_access() is also {
var some_var: uint;
if str_match(kind.as_a(string), "/^TIMER_*/") {
... // do stuff for the TIMER_* registers
};
};
};

Related

C++11: How to create an enum class inside an class that behaves like a sub class?

To explain my problem I posted an example below. The code in this form is not tested so there might be some syntax mistake in it. As I have to work with a lot of registers in an integrated circuit with their addresses which can be remapped, it would be very useful to create structures like that below. Is there some trick to create these structures? As this example does not work the way I want it because foo requires a Country object and Country::Europe::Italy is invalid as parameter.
// I want to create a structure like this
class myClass {
public:
class Country {
enum class Europe {
England,
France,
Germany,
Italy
};
enum class Asia {
China,
Japan
};
};
// Here I want to make sure, that the method is only
// called with a Country element and e.g. Italy should
// behave like a Country object. Actually it should behave
// as if it is derived from Country.
int foo(Country c);
};
int main() {
myClass myC();
// Exemplary call of the method foo
myC.foo(myClass::Country::Europe::Italy);
}
You cannot use enum class to achieve your goal. However, you can use a namespace with a set of hardcoded constexpr objects:
struct Country
{
int _id;
};
namespace Countries
{
namespace Europe
{
constexpr Country Italy{0};
constexpr Country France{1};
};
};
Usage:
myC.foo(Countries::Europe::Italy);
A proper example using registers and a better explanation would have been better. I guess you want to remap from one register name to another. A suggestion:
class Register {
public:
enum class UserName {
REG_IO0,
REG_MEM1
};
enum class CPUName {
REG_INT0,
REG_INT1
};
void setMapping(UserName from, CPUName to); // store the mapping
CPUName getMapping(UserName name) const; // retrieve the mapping
private:
std::map<UserName, CPUName> m_registerMap;
};
If you want you could implement get/set methods for the registers in that class if you store the indexes/adresses of the registers. Either use templates or overload them for different data types.
You can explicitly use an enum type as a function or constructor argument, restricting the caller to using that enumeration.
The thing you can't trivially do is combine multiple enum definitions in the way that you have suggested.
You could write several constructors, one for each of the enums Europe, Asia, etc, but that would be work, especially if you have a number of functions that need to take these enums as arguments.
--OR--
You could define one big enum, and define fixed value separators for each subgroup, so you can compare the enum value against these guard values to identify the subgroup. You lose the sub-grouping if you do that. You could use c++11 constant enum initialisers to construct enum value members in subclasses for each continent - but note these are only available for enum class from c++17 (so I am using a nested class trick to provide the member namespace enforcement - in c++17 you could have enum class Location - you can write this in c++11 but you can't then do the const initialisers). The values follow the above rule of separators, but callers have to indirect through the subclasses to get the names.
class Country
{
class Location {
enum Value {
None =0,
Europe = 0x0100,
Asia = 0x0200,
//etc
};
};
struct Asia {
const Location::Value Japan { Location::Asia + 1 };
//etc
};
struct Europe {
const Location::Value UnitedKingdom { Location::Europe + 1 };
//etc
};
// etc
};
Then you could have
class myClass {
public:
myClass(Country::Location::Value v);
};
And call it with
myClass instance(Country::Asia::Japan);
-- OR --
You could define another structure who's only purpose is to take the various enumerations and convert them to a pair of values for the continent and country index. You could then use that structure as your function parameter, and allow auto-conversion from that structure. This means you only do the conversion once, and callers to your code are not impacted. You could use the guard ranges such that you don't need to explicitly store the continent code, just the raw country number would be unique across all your enums.

Preserving struct field visibility with a macro

I'm trying to write a Rust macro that allows me to make use of the field names and types of a struct declaration, but I still need to emit the struct.
I've got it working with optional attributes, visibility of the struct (thanks to The Little Book of Rust Macros), but can't figure out how to deal with the optional presence of pub in the individual fields.
So far I've got:
macro_rules! with_generic {
($(#[$struct_meta:meta])*
pub struct $name:ident { $($fname:ident : $ftype:ty), *}
) => {
with_generic![(pub) $(#[$struct_meta])* struct $name {$($fname: $ftype) ,*}];
};
($(#[$struct_meta:meta])*
struct $name:ident { $($fname:ident : $ftype:ty), *}
) => {
with_generic![() $(#[$struct_meta])* struct $name {$($fname: $ftype), *}];
};
(
($($vis:tt)*)
$(#[$struct_meta:meta])*
struct $name:ident { $($fname:ident : $ftype:ty), *}
) => {
// emit the struct here
$(#[$struct_meta])*
$($vis)* struct $name {
$($fname: $ftype,)*
}
// I work with fname and ftypes here
}
}
And it works with something like
with_generic! {
#[derive(PartialEq, Eq, Debug)]
pub struct Person {
first_name: String,
last_name: String
}
}
or
with_generic! {
#[derive(PartialEq, Eq, Debug)]
struct PrivatePerson {
first_name: String,
last_name: String
}
}
but doesn't work with
with_generic! {
#[derive(PartialEq, Eq, Debug)]
struct MixedPerson {
pub first_name: String,
last_name: String
}
}
I'd like to get some help on how to make the macro work with that last case. I feel like I might be missing something basic here, such as the type used for binding visibility. If there's a way to bind the whole struct tree while getting the field names and types, that would also be fine.
I'd also like to learn how to get it to work with structs that have lifetime parameters, but maybe that should be a separate question.
You can't. At least, not with a single, non-recursive rule. This is because Rust doesn't have a macro matcher for visibility.
The parse-macros crate contains a parse_struct! macro that shows the work necessary to completely parse a struct definition. Short version: you need to parse each field individually, with one rule for each of "has pub" and "doesn't have pub".
I'd also just note that there's another case your macro doesn't yet account for: attributes on the fields, which is needed for doc-comments on them to work.
Quite soon, macros 1.1 should be stabilised, which might provide an easier approach (assuming you can express your macro as a derivation, and don't care about older versions of Rust).
Since Rust 1.30, you can match visibility keywords with the vis specifier. A vis metavariable will match nothing if there is no visibility keyword to match, so you don't even need to use it inside $()*. This change makes with_generic vastly simpler:
macro_rules! with_generic {
($(#[$struct_meta:meta])*
$sv:vis struct $name:ident { $($fv:vis $fname:ident : $ftype:ty), *}
) => {
// emit the struct here
$(#[$struct_meta])*
$sv struct $name {
$($fv $fname: $ftype,)*
}
// do whatever else you need here
}
}
Rust 1.15 was officially released shortly after I asked this question and brings procedural macros (custom derive) support like #DK. has said.
Going forward, I think custom derives w/ syn and quote will be the standard way of doing this kind of thing and side-steps this issue completely since you no longer need to manually re-emit the struct.

How to write a macro to generate list item

I have a list of structs, the struct has a field which defines it's type (assume it's name).
I would to have a macro as follows:
MYKEEP <name>.<field> <ANY KEEP>;
which would be translated to:
keep value(mylist.has(it.name == <name>)) => mylist.first(it.name == <name>).<field> <ANY KEEP>
Is it possible to do it without an "as computed" macro?
it looks like you want to get a list of structs as an input, check the value of some of the
struct's fields, and then assign a constant value to a different struct field
according to that value.
taking performance into account,this kind of 'Injective' relationship between the two fields should
be in proceedural code rather than generative. (most likely in post_generate()).
consider using a define as macro that looks like this:
define <name_induced_field'struct_member> "MYKEEP <name'exp> <field'exp> <ANY_KEEP'exp>" as{
post_generate() is also{
for each in l{
if (it.t==<name'exp>){
it.<field'exp> = <ANY_KEEP'exp>;
};
};
};
};
and then use it in the code like so:
type mytype: [AA,BB];
struct s {
t:mytype;
!i:int;
};
extend sys{
MYKEEP AA i 1;
MYKEEP BB i 2;
l:list of s;
keep l.size()==5;
};
note: if the struct field has the same relationship to it's name in other cases ,consider
maybe constraining the field from within the struct, for example:
define <name_induced_field'struct_member> "MYKEEP <name'exp> <field'exp> <ANY_KEEP'exp>" as{
keep value(t==<name'exp>) => (<field'exp>==<ANY_KEEP'exp>);
};
type mytype: [AA,BB];
struct s {
MYKEEP AA i 1;
MYKEEP BB i 2;
t:mytype;
i:int;
post_generate() is also{
print me;
};
};
proceedural code doesn't help me, because these fields may effect others in generation time.
I manged to find a macro that seems to work:
define <ana_packet_gen_con_keep1'exp> "KEEP_CON [(<WORD>soft) ]<type'exp>\.<field'any> <exp>" as {
keep for each (con) in it.containers {
<WORD> (con.con_type==<type'exp>) => con.as_a(<type'exp>'con_type ana_container).<field'any> <exp>;
};
};
Does having several "keep for each" effect the performance too much?

Extending list pseudo methods in Specman

Is there a way I could extend the given pseudo methods for lists in e, to add some specific implementation?
Thanks
"pseudo method" is not really a method, it just looks as if it was. So it cannot be extended with "is also/only/etc".
but you can define any "pseudo method" of your own, using macro.
for example - pseudo method that adds only even items -
(do note the \ before the () )
define <my_pseudo_method'action> "<input1'exp>.add_if_even\(<input2'num>\)"
as computed {
result = append("if ", <input2'num>, " %2 == 0 then { ", <input1'exp>, ".add(", <input2'num>, ")};");
}
then can be called from another file -
extend sys {
run() is also {
var my_list : list of int;
for i from 0 to 10 {
my_list.add_if_even(i);
};
print my_list;
};
};
Using a macro, you can even "override" an existing pseudo-method. For example, let's say you want to modify add() so that it will add an element to the list only if it is not already in the list. (In other words, you want to keep all elements in the list unique).
You can do something like this:
define <my_add'action> "<list'exp>.add\(<exp>\)" as {
if not <list'exp>.has(it == <exp>) then {
var new_size<?>: int = <list'exp>.size() + 1;
<list'exp>.resize(new_size<?>, TRUE, <exp>, TRUE);
};
};
Note that I use another pseudo-method here - resize() - to implement the actual addition of the new element to the list. If I tried to use the add() pseudo-method itself, it wouldn't work, and would lead to an infinite recursion. This is because add() used inside the macro would again call the macro itself, and not the pre-defined pseudo-method being overridden.
You can also use templates to add/modify list pseudo-methods. e.g.
<'
template struct MyList of (<T1'type>) {
items: list of <T1'type>;
keep soft items.size()==10;
pop_index(i:int):<T1'type> is {
result = items[i];
items.delete(i);
};
};
extend sys {
list1: MyList of (byte);
// somehwere
var foo:= list1.pop_index(3);
};
'>

Implementing TypeScript interface with bare function signature plus other fields

How do I write a class that implements this TypeScript interface (and keeps the TypeScript compiler happy):
interface MyInterface {
(): string;
text2(content: string);
}
I saw this related answer:
How to make a class implement a call signature in Typescript?
But that only works if the interface only has the bare function signature. It doesn't work if you have additional members (such as function text2) to be implemented.
A class cannot implement everything that is available in a typescript interface. Two prime examples are callable signatures and index operations e.g. : Implement an indexible interface
The reason is that an interface is primarily designed to describe anything that JavaScript objects can do. Therefore it needs to be really robust. A TypeScript class however is designed to represent specifically the prototype inheritance in a more OO conventional / easy to understand / easy to type way.
You can still create an object that follows that interface:
interface MyInterface {
(): string;
text2(content: string);
}
var MyType = ((): MyInterface=>{
var x:any = function():string { // Notice the any
return "Some string"; // Dummy implementation
}
x.text2 = function(content:string){
console.log(content); // Dummy implementation
}
return x;
}
);
There's an easy and type-safe way to do this with ES6's Object.assign:
const foo: MyInterface = Object.assign(
// Callable signature implementation
() => 'hi',
{
// Additional properties
text2(content) { /* ... */ }
}
)
Intersection types, which I don't think were available in TypeScript when this question was originally asked and answered, are the secret sauce to getting the typing right.
Here's an elaboration on the accepted answer.
As far as I know, the only way to implement a call-signature is to use a function/method. To implement the remaining members, just define them on this function. This might seem strange to developers coming from C# or Java, but I think it's normal in JavaScript.
In JavaScript, this would be simple because you can just define the function and then add the members. However, TypeScript's type system doesn't allow this because, in this example, Function doesn't define a text2 member.
So to achieve the result you want, you need to bypass the type system while you define the members on the function, and then you can cast the result to the interface type:
//A closure is used here to encapsulate the temporary untyped variable, "result".
var implementation = (() => {
//"any" type specified to bypass type system for next statement.
//Defines the implementation of the call signature.
var result: any = () => "Hello";
//Defines the implementation of the other member.
result.text2 = (content: string) => { };
//Converts the temporary variable to the interface type.
return <MyInterface>result;
})(); //Invokes the closure to produce the implementation
Note that you don't need to use a closure. You could just declare your temporary variable in the same scope as the resulting interface implementation. Another option is to name the closure function to improve readability.
Here's what I think is a more realistic example:
interface TextRetriever {
(): string;
Replace(text: string);
}
function makeInMemoryTextRetriever(initialText: string) {
var currentText = initialText;
var instance: any = () => currentText;
instance.Replace = (newText: string) => currentText = newText;
return <TextRetriever>instance;
}
var inMemoryTextRetriever = makeInMemoryTextRetriever("Hello");