SystemVerilog: Automatic variables cannot have non-blocking assignments appearing for static reg - static

I start getting this error after I actually make a register static.
This complies fine in Quartus:
task InitAutoRefresh;
reg [$clog2(AUTOREFRESH_CLOCKS):0] AutoRefreshCounter = 0;
AutoRefreshCounter <= AutoRefreshCounter + 1;
InitState <= (AutoRefreshCounter < AUTOREFRESH_CLOCKS) ? InitState : InitState + 1;
InitCmd <= (AutoRefreshCounter == 0) ? CMD_AR : CMD_NOP;
endtask
But Modelsim gives me this error:
# ** Error (suppressible): C:/projects/Camera-RAM-VGA/Ram.sv(137): (vlog-2244) Variable 'AutoRefreshCounter' is implicitly static. You must either explicitly declare it as static or automatic
# or remove the initialization in the declaration of variable.
Now when I add static in front of reg [$clog2(AUTOREFRESH_CLOCKS):0] AutoRefreshCounter = 0; Quartus gives me this error (which looks to be the opposite of my change):
Error (10959): SystemVerilog error at Ram.sv(139): illegal assignment - automatic variables can't have non-blocking assignments
And this points to the register that I've just added the static keyword for!
The only possible explanation I can think of is that when I add static to this single reg it starts treating other regs as automatic, but then the line number in the error message is wrong.

I would simply move the declaration of AutoRefreshCounter outside of the task. Then it is clear that the variable is to be initialized only once at time 0. (That is the reason for the "Implicitly static" error message in the first place).

Related

C file not instrumented for coverage, bad expr node kind

I am using the legacy_code tool in MATLAB, to generate some S Functions, then I want the S Functions to be under analysis by the simulink coverage toolbox.
I am asking also here because maybe this is a C issue and not MATLAB related.
I am setting to true the flag to use the coverage toolbox when generating the S functions using the legacy_code tool.
def.Options.supportCoverage = true;
But I get the following error at compilation, I am using the MinGW 64 bits compiler for MATLAB in windows.
“lib_control.c", line 254: error: bad expr node kind (b:\matlab\polyspace\src\shared\cxx_front_end_kernel\edg\src\cp_gen_be.c, line 14084)
Warning: File "lib_control.c" not instrumented for coverage because of previous error
In codeinstrum.internal.LCInstrumenter/instrumentAllFiles
In codeinstrum.internal.SFcnInstrumenter/instrument
In slcovmexImpl
In slcovmex (line 48)
In legacycode.LCT/compile
In legacycode.LCT.legacyCodeImpl
In legacy_code (line 101)
In generate_sfun (line 70)
In the C code I have the following kind of functions:
void controller( int n_var,
double my_input,
double my_output )
{
double my_var[n_var];
for ( int i=0; i<n_var; i++ )
{
my_output = my_input + my_var[i];
}
}
The compiler is complaining about this line:
double my_var[n_var];
Do I have to do something to declare variables like this, so they can be included in the coverage analysis?
Is this error from MATLAB or is it a C error for instrumentation of files?
If I compile without the coverage flag there is no problems and the S Functions is generated without warnings.
Seems your code won't work because of issues.
First try to declare my_var like this
double *my_var = malloc(n_var * sizeof(double));
memset(my_var, 0, n_var * sizeof(double));
This is the correct way to allocate memory according to function parameter.
And there is also an issue.
my_output = my_input + my_var[i];
So it is correct solution.
*my_output = *my_input + my_var[i];
You are going to change value of parameter which is stack register variable
In C language, parameters are saved in to stack register so it will be freed after function ends.
so it won't reflect any changes
To do this, you need to send pointer of variable as parameter
void controller( int n_var,
double *my_input,
double *my_output ) {
*my_output = ....; // like this
}
and in caller side, you can do like this.
double a, b;
controller(10, &a, &b);
Hope this helps you

How to initialize structure in flash at compile time?

I'm working on an embedded C project and would like to initialize, at compile-time, a structure that is stored in flash (0x1200u), but I keep getting weird compile errors.
typedef struct {
float foo[2];
...other stuff...
} MY_STRUCT_DATA_TYPE
#define MY_FLASH_STRUCT ((MY_STRUCT_DATA_TYPE *)(0x1200u)) // <-- error here
MY_FLASH_STRUCT MY_InitdStruct = {
.foo[0] = 0.12345f;
.foo[1] = 0.54321f;
...other stuff...
};
The error I'm getting is "expected '{' before '(' token." Anyone know how to make this work?
Update
Added to linker file...
MEMORY
{
... other stuff ...
m_my_data_section (RW) : ORIGIN = 0x00001200, LENGTH = 0x00000400
... other stuff ...
}
SECTIONS
{
... other stuff ..
.my_data_section :
{
. = ALIGN(4);
KEEP(*(.my_data_section))
. = ALIGN(4);
} > m_my_data_section
... other stuff ...
}
C code...
static volatile const MY_STRUCT_DATA_TYPE __attribute__ ((section (".my_data_section"))) MY_InitdStruct = {
.foo[0] = 0.12345f;
.foo[1] = 0.54321f;
...other stuff...
};
I'm not sure the static or const keywords are necessary, since it's intended only for one-time use to initialize that section of flash memory at compile-time, but it doesn't hurt to restrict the label's usage.
That makes no sense at all, syntactically that is.
What you need to do is figure out how your compiler supports this, since it's not something you can do with just standard C.
With GCC, you use __attribute() to put the symbol in a particular segment, then use the linker script to put that segment in a particular piece of actual memory.
Or, just give your compiler the benefit of the doubt and try a static const structure, that should end up in flash.
In the example you gave, a ";" is missing after the declaration of MY_STRUCT_DATA_TYPE
typedef struct {
float foo[2];
...other stuff...
} MY_STRUCT_DATA_TYPE;
If it's not a copie/paste mistake, it's the kind of error which could lead to the type of error message you have
I'm working on an embedded C project and would like to initialize, at
compile-time, a structure that is stored in flash (0x1200u), but I
keep getting weird compile errors.
That's unsurprising, as C does not support what you're trying to do. You can provide initializers for objects that C allocates, including pointers, but the C language has no concept of objects that exist independently. Indeed, C makes no guarantees whatever about what happens when you do anything with (MY_STRUCT_DATA_TYPE *)(0x1200u) other than convert it back to an integer.
The error I'm getting is "expected '{' before '(' token."
The compiler is complaining because in
MY_FLASH_STRUCT MY_InitdStruct = {
, the expansion of MY_FLASH_STRUCT is not a type, therefore the construct is not a valid declaration. Nor is it a valid assignment, but even if it were, assignment statements are executable, and therefore may appear only inside functions.
Assigning an object to a specific address would be a function of the linker. Whether you can assign an object to the particular address you want is system-dependent, and the mechanism, if any, for doing so depends on your toolchain.

Issue when customizing select_sequence in sequence library

Please help to understand one issue that I am facing when trying to customize the “select_sequence” of the sequence_library.
So I need to customize the “select_sequence” and make my sequences to run in exact order, which is written in external file.
For that reason I am stepping on the container of all registered sequence types: sequences[$]. And doing dynamic casting. If casting matches with my needed sequence I return number from the select_sequence function i.e. making the library to run the sequence.
This is the part from my code:
class cfgSeqncLib extends uvm_sequence_library #(seqItem_cfg);
`uvm_object_utils(cfgSeqncLib)
`uvm_sequence_library_utils(cfgSeqncLib)
rstSeqnc resetSequence;
function int unsigned select_sequence(int unsigned max);
static int unsigned counter;
select_sequence = counter;
counter++;
if (counter > max)
counter = 0;
foreach (sequences[i])
begin
if ($cast(resetSequence, sequences[i]) )
$display("%t: <><><>><>< ResetSeq: Casting IS Successfull", $time);
else
$display("%t: >>>>>>>>ResetSeq: Casting is NOT Successfull", $time);
end // foreach
endfunction
endclass
And I have added the reset sequence in the library using : `uvm_add_to_seq_lib(rstSeqnc, cfgSeqncLib) command.
The thing is that the $case never return 1 i.e. during simulation it always print
\ >>>>>>>>ResetSeq: Casting is NOT Successfull
Even though I can see that reset sequence is being run by the sequence_lib, but never casting returns true.
Can you please explain why?
If using the UVM code, I change the select_sequence function to following, than casting works:
function int unsigned select_sequence(int unsigned max);
static int unsigned counter;
uvm_object_wrapper wrap;
uvm_object obj;
select_sequence = counter;
counter++;
if (counter > max)
counter = 0;
foreach (sequences[i])
begin
wrap = sequences[i];
obj = factory.create_object_by_type(wrap,get_full_name(),
$sformatf("%s:%0d",wrap.get_type_name(),sequences_executed+1));
if ($cast(resetSequence, obj) )
$display("%t: !!!!!!! ResetSeq: Casting IS Successfull", $time);
else
$display("%t: >>>>>>>>ResetSeq: Casting is NOT Successfull", $time);
end // foreach
endfunction
During Simulaiton I am getting:
!!!!!!! ResetSeq: Casting IS Successfull
I cannot understand why casting in the the first version of select_sequence does not work but in second case it works. Can someone explain this to me please.
using the macro uvm_add_to_seq_lib to add the sequence into the library [`uvm_add_to_seq_lib(rstSeqnc, cfgSeqncLib) ] gives us the feeling that its adding an instance of the sequence into an array present in the sequence library and this instance can be used later in the sequence library.
But that is not the case and like the commonly used style within the uvm, the macro is adding a object of the type uvm_object_registry. This object is created (statically) once per class within the uvm_object_utils macros [ uvm_object_registry#(T,"S") type_id; ].
This mechanism is used within the factory classes/mechanism to create and use a lightweight wrapper(uvm_object_registry) of the object. This ensures that uvm framework is not creating the complete class till its actually needed. The instance of the class is only created at the time of calling the type_id::create function ( or other factory create functions).
So $cast(resetSequence, sequences[i]) in case 1 is really trying to cast the object_wrapper for the type resetSequence [uvm_object_registry#(resetSequence,"resetSequence") ] into resetSequence which fails .
resetSequence != uvm_object_registry#(resetSequence,"resetSequence")
Examining the macro itself we can see its not adding an instance of TYPE ( sequence) instead is calling get_type function which returns an object wrapper.
`define uvm_add_to_seq_lib(TYPE,LIBTYPE) \
static bit add_``TYPE``_to_seq_lib_``LIBTYPE =\
LIBTYPE::m_add_typewide_sequence(TYPE::get_type());
Also examining the code ( case 2 ) below we can see that its using the factory mechanism to create the instance of the class. This ensures that any type override in the environment will work and the sequence library will then use the new sequence over the registered one in the sequence library. In example 1 such a case is not possible as its attempting to directly use the instance of the class [ even if the code was fixed ] . So case 2 has advantages.
wrap = sequences[i];
obj = factory.create_object_by_type(wrap,get_full_name(),
$sformatf("%s:%0d",wrap.get_type_name(),sequences_executed+1));
if ($cast(resetSequence, obj) )

Confusion about static function pointer in c

Look at the the following code snippet. It was written in 2005 but I am compiling it with latest gcc.
xln_merge_nodes_without_lindo(coeff, cand_node_array, match1_array, match2_array)
sm_matrix *coeff;
array_t *cand_node_array, *match1_array, *match2_array;
{
node_t *n1, *n2;
sm_row *row1, *row2;
static sm_row *xln_merge_find_neighbor_of_row1_with_minimum_neighbors();
while (TRUE) {
row1 = sm_shortest_row(coeff);
if (row1 == NIL (sm_row)) return;
n1 = array_fetch(node_t *, cand_node_array, row1->row_num);
row2 = xln_merge_find_neighbor_of_row1_with_minimum_neighbors(row1, coeff);
n2 = array_fetch(node_t *, cand_node_array, row2->row_num);
array_insert_last(node_t *, match1_array, n1);
array_insert_last(node_t *, match2_array, n2);
xln_merge_update_neighbor_info(coeff, row1, row2);
}
}
While compiling,it complains,
xln_merge.c:299:18: error: invalid storage class for function ‘xln_merge_find_neighbor_of_row1_with_minimum_neighbors’
(xln_merger.c:299 is line 3 here after definition starts).
Line 3 function definition seems to be a function declaration (isn't it???). Does the programmer intended to write a function pointer (static)? Or some syntax has changed over the time in c why this is not compiling.
This code is from sis package here
At least for GCC it will give the "invalid storage class for function" if there is a broken declaration in an included file. You may want to go back to your header files and look for what was intended to be a declaration and instead is a hanging function such as
in included xxx.h file:
void foo(int stuff){ <<<<<<<<< this is the problem, replace { with ;
void bar(uint other stuff);
the open "{" really confuses GCC and will throw random errors latter. It is real easy to do a copy and paste of a function and forget to replace the { with a ;
Especially, if you use my beloved 1TBS
I faced the same problem as the error message keep on say that:
libvlc.c:507:11: warning: “/*” within comment
libvlc.c:2154: error: invalid storage class for function ‘AddIntfInternal’
libvlc.c:2214: error: invalid storage class for function ‘SetLanguage’
libvlc.c:2281: error: invalid storage class for function ‘GetFilenames’
libvlc.c:2331: error: invalid storage class for function ‘Help’
libvlc.c:2363: error: invalid storage class for function ‘Usage’
libvlc.c:2647: error: invalid storage class for function ‘ListModules’
libvlc.c:2694: error: invalid storage class for function ‘Version’
libvlc.c:2773: error: invalid storage class for function ‘ConsoleWidth’
libvlc.c:2808: error: invalid storage class for function ‘VerboseCallback’
libvlc.c:2824: error: invalid storage class for function ‘InitDeviceValues’
libvlc.c:2910: error: expected declaration or statement at end of input
The Simple Fix to this problem is "there is some brace missing in the file from which I am getting these errors."
Just go through the below example.
For example:
#include<stdio.h>
int test1()
{
int a = 2;
if ( a == 10)
{
}
will give
test.c:7: error: expected declaration or statement at end of input
Following the "invalid storage class for function" errors.
So.. Just keeping a watch on the braces could probably resolve this error.
Though uncommon, it's completely valid and standard to declare a function inside another one. However the static modifier makes no sense in a declaration without a body, and you can't* define your function inside another function.
Does the programmer intended to write a function pointer (static)?
I can't know the original programmer's intentions but in no way can that be a function pointer since there's no assignment to it.
* Actually you can as a GCC extension

In a C program, is it possible to reset all global variables to default vaues?

I have a legacy C Linux application that I need to reuse . This application uses a lot of global variables. I want to reuse this application's main method and invoke that in a loop. I have found that when I call the main method( renamed to callableMain) in a loop , the application behavior is not consistent as the values of global variables set in previous iteration impact the program flow in the new iteration.
What I would like to do is to reset all the global variables to the default value before the execution of the the new iteration.
for example , the original program is like this
OriginalMain.C
#include <stdio.h>
int global = 3; /* This is the global variable. */
void doSomething(){
global++; /* Reference to global variable in a function. */
}
// i want to rename this main method to callableMain() and
// invoke it in a loop
int main(void){
if(global==3) {
printf(" All Is Well \n");
doSomething() ;
}
else{
printf(" Noooo\n");
doNothing() ;
}
return 0;
}
I want to change this program as follows:
I changed the above file to rename the main() to callableMain()
And my new main methods is as follows:
int main(){
for(int i=0;i<20;i++){
callableMain();
// this is where I need to reset the value of global vaiables
// otherwise the execution flow changes
}
}
Is this possible to reset all the global variables to the values before main() was invoked ?
The short answer is that there is no magical api call that would reset global variables. The global variables would have to be cached and reused.
I would invoke it as a subprocess, modifying its input and output as needed. Let the operating system do the dirty work for you.
The idea is to isolate the legacy program from your new program by relegating it to its own process. Then you have a clean separation between the two. Also, the legacy program is reset to a clean state every time you run it.
First, modify the program so that it reads the input data from a file, and writes its output in a machine-readable format to another file, with the files being given on the command line.
You can then create named pipes (using the mkfifo call) and invoke the legacy program using system, passing it the named pipes on the command line. Then you feed it its input and read back its output.
I am not an expert on these matters; there is probably a better way of doing the IPC. Others here have mentioned fork. However, the basic idea of separating out the legacy code and invoking it as a subprocess is probably the best approach here.
fork() early?
You could fork(2) at some early point when you think the globals are in a good state, and then have the child wait on a pipe or something for some work to do. This would require writing any changed state or at least the results back to the parent process but would decouple your worker from your primary control process.
In fact, it might make sense to fork() at least twice, once to set up a worker controller and save the initialized (but not too initialized :-) global state, and then have this worker controller fork() again for each loop you need run.
A simpler variation might be to just modify the code so that the process can start in a "worker mode", and then use fork() or system() to start the application at the top, but with an argument that puts it in to the slave mode.
There is a way to do this on certain platforms / compilers, you'd basically be performing the same initialization your compiler performs before calling main().
I have done this for a TI DSP, in that case I had the section with globals mapped to a specific section of memory and there were linker directives available that declared variables pointing to the start and end of this section (so you can memset() the whole area to zero before starting initialization). Then, the compiler provided a list of records, each of which comprised of an address, data length and the actual data to be copied into the address location. So you'd just loop through the records and do memcpy() into the target address to initialize all globals.
Very compiler specific, so hopefully the compiler you're using allows you to do something similar.
In short, no. What I would do in this instance is create definitions, constants if you will, and then use those to reset the global variables with.
Basically
#define var1 10
int vara = 10
etc... basic C right?
You can then go ahead and wrap the reinitialization in a handy function =)
I think you must change the way you see the problem.
Declare all the variables used by callableMain() inside callableMain()'s body, so they are not global anymore and are destroyed after the function is executed and created once again with the default values when you call callableMain() on the next iteration.
EDIT:
Ok, here's what you could do if you have the source code for callableMain(): in the beginning of the function, add a check to verify if its the first time the function its being called. Inside this check you will copy the values of all global variables used to another set of static variables (name them as you like). Then, on the function's body replace all occurences of the global variables by the static variables you created.
This way you will preserve the initial values of all the global variables and use them on every iteration of callableMain(). Does it makes sense to you?
void callableMain()
{
static bool first_iter = true;
if (first_iter)
{
first_iter = false;
static int my_global_var1 = global_var1;
static float my_global_var2 = global_var2;
..
}
// perform operations on my_global_var1 and my_global_var2,
// which store the default values of the original global variables.
}
for (int i = 0; i < 20; i++) {
int saved_var1 = global_var1;
char saved_var2 = global_var2;
double saved_var3 = global_var3;
callableMain();
global_var1 = saved_var1;
global_var2 = saved_var2;
global_var3 = saved_var2;
}
Or maybe you can find out where global variables start memcpy them. But I would always cringe when starting a loop ...
for (int i = 0; i < 20; i++) {
static unsigned char global_copy[SIZEOFGLOBALDATA];
memcpy(global_copy, STARTOFGLOBALDATA, SIZEOFGLOBALDATA);
callableMain();
memcpy(STARTOFGLOBALDATA, global_copy, SIZEOFGLOBALDATA);
}
If you don't want to refactor the code and encapsulate these global variables, I think the best you can do is define a reset function and then call it within the loop.
Assuming we are dealing with ELF on Linux, then the following function to reset the variables works
// these extern variables come from glibc
// https://github.com/ysbaddaden/gc/blob/master/include/config.h
extern char __data_start[];
extern char __bss_start[];
extern char _end[];
#define DATA_START ((char *)&__data_start)
#define DATA_END ((char *)&__bss_start)
#define BSS_START ((char *)&__bss_start)
#define BSS_END ((char *)&_end)
/// first call saves globals, subsequent calls restore
void reset_static_data();
// variable for quick check
static int pepa = 42;
// writes to memory between global variables are reported as buffer overflows by asan
ATTRIBUTE_NO_SANITIZE_ADDRESS
void reset_static_data()
{
// global variable, ok to leak it
static char * x;
size_t s = BSS_END - DATA_START;
// memcpy is always sanitized, so access memory as chars in a loop
if (x == NULL) { // store current static variables
x = (char *) malloc(s);
for (size_t i = 0; i < s; i++) {
*(x+i) = *(DATA_START + i);
}
} else { // restore previously saved static variables
for (size_t i = 0; i < s; i++) {
*(DATA_START + i) = *(x+i);
}
}
// quick check, see that pepa does not grow in stderr output
fprintf(stderr, "pepa: %d\n", pepa++);
}
The general approach is based on answer in How to get the data and bss address space in run time (In Unix C program), see the linked ysbaddaden/gc GitHub repo for macOS version of the macros.
To test the above code, just call it a few times and note that the incremented global variable pepa still keeps the value of 42.
reset_static_data();
reset_static_data();
reset_static_data();
Saving current state of the globals is convenient in that it does not require rerunning __attribute__((constructor)) functions which would be necessary if I set everything in .bss to zero (which is easy) and everything in .data to the initial values (which is not so easy). For example, if you load libpython3.so in your program, it does do run-time initialization which is lost by zeroing .bss. Calling into Python then crashes.
Sanitizers
Writing into areas of memory immediately before or after a static variable will trigger buffer-overflow warning from Address Sanitizer. To prevent this, use the ATTRIBUTE_NO_SANITIZE_ADDRESS macro the way the code above does. The macro is defined in sanitizer/asan_interface.h.
Code coverage
Code coverage counters are implemented as global variables. Therefore, resetting globals will cause coverage information to be forgotten. To solve this, always dump the coverage-to-date before restoring the globals. There does not seem to be a macro to detect whether code coverage is enabled or not in the compiler, so use your build system (CMake, ...) to define suitable macro yourself, such as QD_COVERAGE below.
// The __gcov_dump function writes the coverage counters to gcda files
// and the __gcov_reset function resets them to zero.
// The interface is defined at https://github.com/gcc-mirror/gcc/blob/7501eec65c60701f72621d04eeb5342bad2fe4fb/libgcc/libgcov-interface.c
extern "C" void __gcov_reset();
extern "C" void __gcov_dump();
void flush_coverage() {
#if defined(QD_COVERAGE)
__gcov_dump();
__gcov_reset();
#endif
}

Resources