I get incompatible types in the assignment? - iphone

int k[4] = {1,2,3,4};
int kk[4];
kk=k;
I get incompatible types in the assignment??
Do I have to loop and assign each value in the array, or is there an easier way?
Thank you

You have to loop, or use a library call.
One option would be memcpy(kk, k, sizeof(k));. For this you must #include <string.h>.

Yes. Arrays don't behave like primitive data types in C. You have to loop over the array and assign each value. You can't just assign one array to another (especially since kk is really an int pointer). Not too hard though:
int i;
for (i = 0; i < 4; i++)
kk[i] = k[i];

There is no copy assignment of good old C arrays. So yes, you have to loop through and copy each element.

Related

Merging associative arrays

Assuming I have two associative arrays, is there a way to use something like a concatenation operator to merge them? I tried this and it doesn't work:
module tb;
initial begin
int a[int] = '{1:1, 2:2};
int b[int] = '{3:3, 4:4};
$display("a = ", a);
$display("b = ", b);
b = {a,b};
$display("b = ", b);
end
endmodule
I know I can iterate over the it and assign, but I'm essentially looking for a one-liner if it's doable. I couldn't find anything in the LRM.
No, the LRM specifically excludes associative arrays from array concatenation (section 10.10).
A target of any other type (including associative array) shall be
illegal.
It's also illegal to use any kind of casting. You'll have a foreach loop.

How to allocate contiguous memory for dynamic multidimensional arrays in SystemVerilog?

Is there a way in SystemVerilog to create a dynamic array that allocates its memory contiguously? I'm trying to read in data from a file into a dynamic array. The problem appears to be that the dynamic array is not in contiguous memory locations, so the file is not read properly into the array.
When I declare the variable reading the file as a non-dynamic array it works fine, so I assume the problem is contiguous memory. Here's the code:
This works fine, but does not use a dynamic array:
// Reads frame from a binary file
task t_Read_File(input string i_File_Name);
int n_Temp[10][10];
int n_File_ID;
n_File_ID = $fopen(i_File_Name, "rb");
$fread(n_Temp, n_File_ID);
$fclose(n_File_ID);
r_Frame = n_Temp;
endtask : t_Read_File
This uses a dynamic array (r_Frame) but does not work
// Reads frame from a binary file
task t_Read_File(input string i_File_Name);
int n_File_ID;
n_File_ID = $fopen(i_File_Name, "rb");
$fread(r_Frame, n_File_ID);
$fclose(n_File_ID);
endtask : t_Read_File
FYI, r_Frame is declared previously as a local variable to my class as follows:
int r_Frame[][];
Using $fread on a dynamic array is an open issue in the standard. It's even more problematic for multi-dimensional dynamic arrays as there is no way to know how to shape the array. To make matters more complicated, SystemVerilog does not really have multi-dimensional array; instead it has arrays of arrays. This means each indexed dimension could have a different size.
You could try allocating the array first, then calling $fread.
r_Frame = new[10];
foreach (r_Frame[i]) r_Frame[i] = new[10];
Here's the solution that I had to end up implementing. Basically I read the text file one line at a time into n_Temp, which was just a large temporary array structure. Then I put it into the multidimensional dynamic array r_Frame one value at a time. Despite previously calling new for r_Frame and setting the dimensions, $fread was not writing the values into r_Frame. I had to go through this extra step using a temporary variable to get it to work. Also I did have to write an endian swap function to convert the little-endian data file to big-endian format.
task t_Read_File(input string i_File_Name);
int n_Temp[5000]; // arbitrary, large
int n_File_ID;
n_File_ID = $fopen(i_File_Name, "rb");
for (int i=0; i<n_Active_Rows; i++)
begin
void'($fread(n_Temp, n_File_ID, , n_Active_Cols));
for (int j=0; j<n_Active_Cols; j++)
r_Frame[i][j] = Sim_Support_Pkg::f_Endian_Swap(n_Temp[j]);
end
$fclose(n_File_ID);
endtask : t_Read_File

How to convert a string to a variable name?

I would like to have a construct like below to declare variable names based on a string queue. The below doesn't compile. So I would like to know if a similar approach is possible in Systemverilog.
Below is a simplified version of what I want to actually implement.
`define declare_int(NAME) int ``NAME`` = 1;
string str_q[$] = {"a", "b", "c"};
foreach (str_q[i]) begin
`declare_int(str_q[i])
end
NOTE: I am aware that `declare_int(a) will translate to int a = 1;. But as shown in the example above, I need a foreach loop to call this macro multiple times and so the input of the macro has to be some datatype, like a string in this case. The purpose is to auto-declare stuff as the queue changes with time.
In other words, how can I define the `declare_int macro so that `declare_int("a") translates to int a = 1;?
As Verilog is not interpreted but compiled in simulation, I doubt theres any way to dynamically declare variables at runtime. However, there are work arounds that achieve a similar effect.
I think the closest thing you could get is an associative array with the keys as your names (a, b, c) and your values for the values. For example, instead of your code, you'd have:
int vars[string];
string str_q[$] = {"a", "b", "c"};
foreach (str_q[i]) begin
vars[str_q[i]] = 1;
end
...
// To use the variable, just do:
vars["a"];
For more on associative arrays: http://www.asic-world.com/systemverilog/data_types13.html

loop starting from given index

Considering the following javascript, what's the best way to write this loop in coffee script, given the initial index is greater than 0:
function mixin(target, source, methods) {
for (var i = 2, l = arguments.length; i < l; i++){
var method = arguments[i];
target[method] = source[method].bind(source)
}
}
Automatic code converters suggest use a while loop like this:
mixin = (target, source, methods) ->
i = 2
l = arguments.length
while i < l
method = arguments[i]
target[method] = source[method].bind(source)
i++
Is there a cleaner way to do this?
You'd usually use a splat in CoffeeScript when defining your mixing function:
The JavaScript arguments object is a useful way to work with functions that accept variable numbers of arguments. CoffeeScript provides splats ..., both for function definition as well as invocation, making variable numbers of arguments a little bit more palatable.
So you'd say:
mixin = (target, source, methods...) ->
# splat ----------------------^^^
for method in methods
target[method] = source[method].bind(source)
and your problem goes away. The splat in the argument list will collect all the arguments after source into a methods array for you so you won't have to worry about arguments at all; the splat also makes the function's signature nice and obvious.
Use an exclusive range (triple dot, excludes the number at the highest.
for i in [2...arguments.length]
method = arguments[i]
target[method] = source[method].bind(source)
If you have 5 things in your args, this will hit indexes 2, 3 and 4.

What does the & symbol mean in Objective-C?

What does the & symbol mean in Objective-C? I am currently looking at data constucts and am getting really confused by it.
I have looked around the web for it but have not found an answer at all. I know this is possibly a basic Objective-C concept, but I just can't get my head around it.
For example:
int *pIntData = (int *)&incomingPacket[0];
What is the code doing with incoming packet here?
& is the C address-of unary operator. It returns the memory address of its operand.
In your example, it will return the address of the first element of the incomingPacket array, which is then cast to an int* (pointer to int)
Same thing it means in C.
int *pIntData = (int *)&incomingPacket[0];
Basically this says that the address of the beginning of incomingPacket (&incomingPacket[0]) is a pointer to an int (int *). The local variable pIntData is defined as a pointer to an int, and is set to that value.
Thus:
*pIntData will equal to the first int at the beginning of incomingPacket.
pIntData[0] is the same thing.
pIntData[5] will be the 6th int into the incomingPacket.
Why do this? If you know the data you are being streamed is an array of ints, then this makes it easier to iterate through the ints.
This statement, If I am not mistaken, could also have been written as:
int *pIntData = (int *) incomingPacket;