how does a variable to be decided it's value without it's initialize in systemverilog? - system-verilog

Now I'm trying to digging the systemverilog as the below
denaliCdn_ahbTransaction burst1;
task sendTransfers;
 
burst1= new;       
burst1.Direction = DENALI_CDN_AHB_DIRECTION_WRITE;
burst1.FirstAddress = 32'h4020;//16416 M3 and M0 to S1
burst1.Kind = DENALI_CDN_AHB_BURSTKIND_INCR4;
burst1.Size = DENALI_CDN_AHB_TRANSFERSIZE_HALFWORD;
burst1.Data = new [8];
foreach (burst1.Data[ii])
burst1.Data[ii] = ii;
void'(activeMaster1.transAdd(burst1,0));
....
endtask
Especially, from here , how does ii be decided it's value without initialized ?
foreach (burst1.Data[ii])
burst1.Data[ii] = ii;
how does a variable to be decided it's value without it's initialize in systemverilog?

There is a general answer and a specific answer to your question.
The general answer is that all types in System-Verilog initialise to specific values:
int 0
real 0.0
string ""
logic 1'bx
However, the specific answer to your question is that the code you specifically identify
foreach (burst1.Data[ii])
burst1.Data[ii] = ii;
is actually performing initialisation rather than relying on it. The dynamic array burst1.data is constructed with 8 elements in the line
burst1.Data = new [8];
The line
foreach (burst1.Data[ii])
iterates over that array, looping 8 times, once for each element. The variable ii takes the value of the index of each element in the array, ie 0 to 7. The line
burst1.Data[ii] = ii;
Sets element ii of the array to the value ii and so is initialising the array.

Related

How to use for loop to add the previous values in an array in MATLAB?

I have an array like t. It contains the numbers and I would like to add to each number the previous ones. For example: t=[0,2,3,5] and I would like to get tnew=[0,2,5,10]. I tried out this code but it is wrong for sure. (There are 5292 values)
for i=0:5292
t(i)=t(i)+t(i+1)
end
For some array t = [0,2,3,5];, you can just do tnew = cumsum(t).
If you really want to do this in a loop, you need to start from the 2nd index, and keep adding to the value from the previous index
t = [0,2,3,5];
tnew = t;
for ii = 2:numel(t)
tnew(ii) = t(ii) + tnew(ii-1);
end

MATLAB: Loop through the values of a list from 'who' function

I have a long list of variables in my workspace.
First, I'm finding the potential variables I could be interested in using the who function. Next, I'd like to loop through this list to find the size of each variable, however who outputs only the name of the variables as a string.
How could I use this list to refer to the values of the variables, rather than just the name?
Thank you,
list = who('*time*')
list =
'time'
'time_1'
'time_2'
for i = 1:size(list,1);
len(i,1) = length(list(i))
end
len =
1
1
1
If you want details about the variables, you can use whos instead which will return a struct that contains (among other things) the dimensions (size) and storage size (bytes).
As far as getting the value, you could use eval but this is not recommended and you should instead consider using cell arrays or structs with dynamic field names rather than dynamic variable names.
S = whos('*time*');
for k = 1:numel(S)
disp(S(k).name)
disp(S(k).bytes)
disp(S(k).size)
% The number of elements
len(k) = prod(S(k).size);
% You CAN get the value this way (not recommended)
value = eval(S(k).name);
end
#Suever nicely explained the straightforward way to get this information. As I noted in a comment, I suggest that you take a step back, and don't generate those dynamically named variables to begin with.
You can access structs dynamically, without having to resort to the slow and unsafe eval:
timestruc.field = time;
timestruc.('field1') = time_1;
fname = 'field2';
timestruc.(fname) = time_2;
The above three assignments are all valid for a struct, and so you can address the fields of a single data struct by generating the field strings dynamically. The only constraint is that field names have to be valid variable names, so the first character of the field has to be a letter.
But here's a quick way out of the trap you got yourself into: save your workspace (well, the relevant part) in a .mat file, and read it back in. You can do this in a way that will give you a struct with fields that are exactly your variable names:
time = 1;
time_1 = 2;
time_2 = rand(4);
save('tmp.mat','time*'); % or just save('tmp.mat')
S = load('tmp.mat');
afterwards S will be a struct, each field will correspond to a variable you saved into 'tmp.mat':
>> S
S =
time: 1
time_1: 2
time_2: [4x4 double]
An example writing variables from workspace to csv files:
clear;
% Writing variables of myfile.mat to csv files
load('myfile.mat');
allvars = who;
for i=1:length(allvars)
varname = strjoin(allvars(i));
evalstr = strcat('csvwrite(', char(39), varname, '.csv', char(39), ', ', varname, ')');
eval(evalstr);
end

Matlab: Compare strings in a for loop

I want to compare two strings from two structs. My Code is like below:
%matlab model scan
[variables] = Simulink.findVars('myModell');
variablesNames =[];
%save the names of all the variables in variablesNames
for t= 1:length(variables)
variablesNames(t).Name = variables(t).Name;
end
%scan workspace
for f = fieldnames(my_workspace)
found = false;
for c = 1:length(variablesNames)
if strcmp(f{c}, variablesNames(c))
found = true;
result = 'Found in Workspace: ';
end
if ~found
result = 'Not found inside Workspace';
end
end
disp(['Workspace Variable: ', sprintf('%-*s',40,f{c}), result]);
end
variablesNames is a struct 1x15 with 1 field
my_workspace is 1x1 struct with 20 fields
I got only one variable as return.
What is wrong in this code?
I don't really understand why are you creating a new struct here: variablesNames(t).Name, therefore I just removed that part.
The modified code just iterates through the variables struct-array and checks whether variable my_workspace has a field with the name of the value stored in the Name field of the currently processed element, using isfield.
[variables] = Simulink.findVars('myModell');
for i = 1:length(variables)
if isfield(my_workspace, variables(t).Name)
result = 'Found in Workspace: ';
else
result = 'Not found inside Workspace';
end
disp(['Workspace Variable: ', sprintf('%-*s', 40, variables(t).Name), result]);
end

Matlab coder & dynamic field references

I'm trying to conjure up a little parser that reads a .txt file containing parameters for an algorithm so i don't have to recompile it everytime i change a parameter. The application is C code generated from .m via coder, which unfortunately prohibits me from using a lot of handy matlab gimmicks.
Here's my code so far:
% read textfile
string = readfile(filepath);
% do fancy rearranging
linebreaks = zeros(size(string));
equals = zeros(size(string));
% find delimiters
for n=1:size(string,2)
if strcmp(string(n),char(10))
linebreaks(n) = 1;
elseif strcmp(string(n), '=')
equals(n) = 1;
end
end
% write first key-value pair
idx_s = find(linebreaks);idx_s = [idx_s length(string)];
idx_e = find(equals);
key = string(1:idx_e(1)-1);
value = str2double(string(idx_e(1)+1:idx_s(1)-1));
parameters.(key) = value;
% find number of parameters
count = length(idx_s);
% write remaining key-value pairs
for n=2:count
key = string(idx_s(n-1)+1:idx_e(n)-1);
value = str2double(string(idx_e(n)+1:idx_s(n)-1));
parameters.(key) = value;
end
The problem is that seemingly coder does not support dynamic fieldnames for structures like parameters.(key) = value.
I'm a bit at a loss as to how else i am supposed to come up with a parameter struct that holds all my key-value pairs without hardcoding it. It would somewhat (though not completely) defeat the purpose if the names of keys were not dynamically linked to the parameter file (more manual work if parameters get added/deleted, etc.). If anybody has an idea how to work around this, i'd be very grateful.
As you say, dynamic fieldnames for structures aren't allowed in MATLAB code to be used by Coder. I've faced situations much like yours before, and here's how I handled it.
First, we can list some nice tools that are allowed in Coder. We're allowed to have classes (value or handle), which can be quite handy. Also, we're allowed to have variable sized data if we use coder.varsize to specifically designate it. We also can use string values in switch statements if we like. However, we cannot use coder.varsize for properties in a class, but you can have varsized persistent variables if you like.
What I'd do in your case is create a handle class for storing and retrieving the values. The following example is pretty basic, but will work and could be expanded. If a persistent variable were used in a method, you could even create a varsized allocated storage for the data, but in my example, it's a property and has been limited in the number of values it can store.
classdef keyval < handle %# codegen
%KEYVAL A key and value class designed for Coder
% Stores an arbitrary number of keys and values.
properties (SetAccess = private)
numvals = 0
end
properties (Access = private)
intdata
end
properties (Constant)
maxvals = 100;
maxkeylength = 30;
end
methods
function obj = keyval
%KEYVAL Constructor for keyval class
obj.intdata = repmat(struct('key', char(zeros(1, obj.maxkeylength)), 'val', 0), 1, obj.maxvals);
end
function result = put(obj, key, value)
%PUT Adds a key and value pair into storage
% Result is 0 if successful, 1 on error
result = 0;
if obj.numvals >= obj.maxvals
result = 1;
return;
end
obj.numvals = obj.numvals + 1;
tempstr = char(zeros(1,obj.maxkeylength));
tempstr(1,1:min(end,numel(key))) = key(1:min(end, obj.maxkeylength));
obj.intdata(obj.numvals).key = tempstr;
obj.intdata(obj.numvals).value = value;
end
function keystring = getkeyatindex(obj, index)
%GETKEYATINDEX Get a key name at an index
keystring = deblank(obj.intdata(index).key);
end
function value = getvalueforkey(obj, keyname)
%GETVALUEFORKEY Gets a value associated with a key.
% Returns NaN if not found
value = NaN;
for i=1:obj.numvals
if strcmpi(keyname, deblank(obj.intdata(i).key))
value = obj.intdata(i).value;
end
end
end
end
end
This class implements a simple key/value addition as well as lookup. There are a few things to note about it. First, it's very careful in the assignments to make sure we don't overrun the overall storage. Second, it uses deblank to clear out the trailing zeros that are necessary in the string storage. In this situation, it's not permitted for the strings in the structure to be of different length, so when we put a key string in there, it needs to be exactly the same length with trailing nulls. Deblank cleans this up for the calling function.
The constant properties allocate the total amount of space we're allowed in the storage array. These can be increased, obviously, but not at runtime.
At the MATLAB command prompt, using this class looks like:
>> obj = keyval
obj =
keyval with properties:
numvals: 0
>> obj.put('SomeKeyName', 1.23456)
ans =
0
>> obj
obj =
keyval with properties:
numvals: 1
>> obj.put('AnotherKeyName', 34567)
ans =
0
>> obj
obj =
keyval with properties:
numvals: 2
>> obj.getvalueforkey('SomeKeyName')
ans =
1.2346
>> obj.getkeyatindex(2)
ans =
AnotherKeyName
>> obj.getvalueforkey(obj.getkeyatindex(2))
ans =
34567
If a totally variable storage area is desired, the use of persistent variables with coder.varsize would work, but that will limit the use of this class to a single instance. Persistent variables are nice, but you only get one of them ever. As written, you can use this class in many different places in your program for different storage. If you use a persistent variable, you may only use it once.
If you know some of the key names and are later using them to determine functionality, remember that you can switch on strings in MATLAB, and this works in Coder.

Access data in structures when field names are unknown

I have data as a struct with several layers, for example:
data.A.B
The data I want to access is in layer B. But the problem is that field names in B can be different depending on where the data comes from. Therefore I can't just type:
data.A.B.myData
myData is itself a struct
I can use:
fieldnames(data.A)
to find the names, but this doesn't help my much. I would have to write code sections for every possible field name that can occur at this level. And that's just what i trying to avoid.
Is there a way to get down to the data I have (myData) without knowing the field names of B?
Traditionally, you can loop over the fieldnames and perform the search of myData at a specific sub-structure of the struct. However, if you don't know which sub-structure you need to search, then you can perform a recursive algorithm. Below is an example. It will return the first match of myData in the struct or an empty matrix if no match found. The code can be improved to find all matches of myData.
function S2=getmyfield(S1,queriedField)
if isstruct(S1)
% Get all fieldnames of S1
fieldArray=fieldnames(S1);
% Find any match with the queried field. You can also use isfield().
% If there is a match return the value of S1.(queriedField),
% else perform a loop and recurse this function.
matchTF=strcmp(queriedField,fieldArray);
if any(matchTF)
S2=S1.(fieldArray{matchTF});
return;
else
S2=[];
i=0; % an iterator count
while isempty(S2)
i=i+1;
S2=getmyfield(S1.(fieldArray{i}),queriedField);
end
end
else
S2=[];
end
end
Cheers.
You just need a recursive function that checks fieldnames at each level for the structure.
This is roughly what you need (it could be improved to supply the path to the found field).
function [ value, found ] = FindField( rootStruct, fieldName )
%FindField - Find a field with a structure
value = [];
found = 0;
if isstruct( rootStruct )
fields = fieldnames(rootStruct);
for fi=1:length(fields)
if strcmp(fields{fi}, fieldName )
value = rootStruct.(fieldName);
found = true;
return;
end
[value, found ] = FindField( rootStruct.(fields{fi}), fieldName );
if found
return;
end
end
end
end
Usage example:
a.b = 1;
a.b.c = 2;
a.b.d = struct('Index',1,'Special',2);
FindField(a,'d')
ans =
Index: 1
Special: 2