how to print integral value in decimal format using uvm_printer rather default hex format - uvm

class dpcfg extends uvm_object;
rand int num_lanes;
function new(string name="");
super.new(name);
endfunction
function void do_print(uvm_printer printer);
printer.print_string("dpcfg", "dpcfg");
printer.print_field("num_lanes", num_lanes, $bits(num_lanes));
endfunction
endclass
//Instantiating the above class
dpcfg cfg;
cfg = new("cfg");
cfg.print();
I am getting the print output as below
----------------------------------------------
Name Type Size Value
----------------------------------------------
cfg dpcfg - #2579
dpcfg string 5 dpcfg
num_lanes integral 32 'hA
----------------------------------------------
where I need print output as below
----------------------------------------------
Name Type Size Value
----------------------------------------------
cfg dpcfg - #2579
dpcfg string 5 dpcfg
num_lanes integral 32 'd10
----------------------------------------------

How about:
printer.print_field("num_lanes", num_lanes, $bits(num_lanes), UVM_DEC);
The prototype for print_field is:
// Function: print_field
//
// Prints an integral field (up to 4096 bits).
//
// name - The name of the field.
// value - The value of the field.
// size - The number of bits of the field (maximum is 4096).
// radix - The radix to use for printing. The printer knob for radix is used
// if no radix is specified.
// scope_separator - is used to find the leaf name since many printers only
// print the leaf name of a field. Typical values for the separator
// are . (dot) or [ (open bracket).
extern virtual function void print_field (string name,
uvm_bitstream_t value,
int size,
uvm_radix_enum radix=UVM_NORADIX,
byte scope_separator=".",
string type_name="");
How do I know this? From the HTML documentation that comes with UVM. It's really, really good and then, if in doubt, you can click through to the UVM code itself.

adding UVM_DEC solved the issue
function void do_print(uvm_printer printer);
printer.print_string("dpcfg", "dpcfg");
printer.print_field("num_lanes", num_lanes, $bits(num_lanes), UVM_DEC);
endfunction

Related

my simple intrest calculator is not working for some reason

my simple intrest calculator that I create used c programming is not working for some reason. i want to bring me the answer but always returns zero and i literally don't know what should I do. I am kinda new to c and I really cannot figur it out
i would really appreciate if any of you could help me out. thanks
// Assignment - 1, Section - 2.
/** Please read the instructions in the comment and
write the code accordingly.
This assignment will test your understanding with console input and output.
Just in case if you do not know the meaning of the term 'console', we typically
indicate it to mean keyboard and terminal. Input console indicates to keyboard and
output console indicates terminal.
This will also test your ability to use variables.
*/
int main()
{
// Please follow the instructions and write the code chronologically.
// 1. Declare a double type variable named rate and assign 0.06 to it
double rate=0.06;
// 2. Declare an integer variable, name it duration.
int duration;
// 3. Declare a double variable and name it principal_amount
double principal_amount;
// 4. Declare a double variable and name it total_interest
double total_interest;
// 5. Prompt user to input duration in year. Read the year value in duration using
// scanf. Since duration is integer you must use %d.
printf("input duration in year");
scanf("%d", &duration);
// 6. Prompt user to input principal amount of loan. Read the value in the
// variable principal_amount. Think about the format specifier this time.
// principal_amount is not an integer, it is a double, so use the format specifier
// of double.
printf("input the amount of loan:\n");
scanf("%f", &principal_amount);
// 7. Now you will calculate the total interest, if R is rate, D is duration and P
// is principal then the total interest should be calculated as follows:
// I = (P * D * R)
int I= (rate*duration*principal_amount);
printf("%d", I);
// Use the above formula to calculate the total interest and finally print the
// amount into the console. Your output should be like the following:
// Output:
// Your total payable interest is $3000.000000 when principal_amount given as 1000.0, duration is 5
//
return 0;
}```
Use %lf format specifier for double and %d format specifier for int. This solves the issue and prints the required answer.
scanf("%lf", &principal_amount);
double I= (rate*duration*principal_amount);
printf("%lf", I);

SHA256 digest differs between array initializer and string

I use the sha256 function of Microchip ATECC508A security chip. My code looks like this:
int main(void) {
uint8_t message[32] = {0}; // Method 1
//uint8_t message[32] = "00000000000000000000000000000000"; // Method 2
foobar(message, sizeof(message));
}
void foobar(uint8_t *message, int length) {
uint8_t digest[32];
sha256(message, length, digest);
// printf statements for calculated hashes ...
}
Method 1: 66687AADF862BD776C8FC18B8E9F8E20089714856EE233B3902A591D0D5F2925
Method 2: 84E0C0EAFAA95A34C293F278AC52E45CE537BAB5E752A00E6959A13AE103B65A
Method 2 delievers the corresponding hash I expect for 32 zeros, but when I use the static array initializer in method 1, the hash is wrong and I don't know why. I've checked the resulting sha256 hashes here.
I would appreciate any help, thank you very much.
EDIT:
I was able to to initialize the whole array with characters of zeros with:
uint8_t message[32] = { [0 ... 31] = '0'}.
This only works on gcc compilers.
In the second case, the array is not filled with the number 0 but is filled with the character '0'.
In ASCII, the encoding for '0' is 48, so assuming your system uses ASCII then every element of your array has the value 48.

Printing formatted string in C

So I have a string of length 10. And I want to print the letters from 4-6[including both], and I want to span the output over a particular length L, with the digits being placed on the right side.
For eg
If I had the original String 123456789, then the following code should display in the subsequent manner.
printf(Original);
printf(from 4-6, over 5 spaces)
Output:
123456789
456
That is 456 is spread over 5 spaces and indented right.
How do I do it in C?
EDIT 1 : What if my width is not constant, and I have a variable, that dictates, the width. Similarly for the length of the substring is a variable. Any way of doing it now?
Can I do something like
printf("%%d.%ds",width,precision,expression);
Very direct:
printf("%5.3s\n", Original + 4);
^ ^
| |
| +--- precision, causes only 3 characters to be printed
|
+----- field width, sets total width of printed item
Since right-adjusting is the default, you get the desired output.
The precision "saves" us from having to extract the three characters into a properly terminated string of their own, very handy.
You can use dynamic values for either precision or field width (or both, of course) by specifying the width as * and passing an int argument:
const int width = 5, precision = 3;
printf("%*.*s\n", width, precision, Original + 4);
#include <stdio.h>
int main(void)
{
char *original = "123456789";
printf("%5.3s\n", original + 3);
return 0;
}
EDIT:
if you want a precision based on a variable:
int prec = 2;
printf("%5.*s\n", prec, original + 3);
... same for width

Need help in C printf formatted output

I am displaying a partition table, and the table is displayed somewhat like:
Number Device name Partition type Size in MB
------------------------------------------------------------
1 /dev/sda1 NTFS 300
2 /dev/sda2 *Win95 FAT32 99
3 /dev/sda3 Unknown 128
4 /dev/sda4 NTFS 19472
120 /dev/sda120 NTFS 3000
*=Active partition
Now for displaying the above, we are using formatted output printf and the format string is
"%-6d=partition number %-25.25s=device name %c=active partition %-30.30s=part type %7Ld=size"
Now i want to display the same partition table, but with some slight modification, such that the gaps in partition slots would be displayed by a range, like:
5-119 /dev/sda5.../dev/sda119 Empty 0
I am using the formatted string as:
%d-%-6d=partition range %s%d...%s%d=(/dev/sda5.../dev/sda119) %c %-30.30s %7Ld
but it does not help me.
What should be the correct format string? I am using a gcc compiler.
I think you need to use snprintf() to prepare the two composite strings, and then a simpler printf() to do the actual printing. Since you've not shown your actual code, we have to guess at everything, which is a nuisance...
int min = 5;
int max = 119;
char *dev = "/dev/sda";
char num_range[32];
char dev_range[60];
snprintf(num_range, sizeof(num_range), "%d-%d", min, max);
snprintf(dev_range, sizeof(dev_range), "%s%d...%s%d", dev, min, dev, max);
printf("%-10s %-50.50s %c%-30.30s %7d", num_range, dev_range, ' ', "Empty", 0);
You specified %-25.25s for a single device, so it isn't clear whether you should double that for the range, or you should use some other value (or even the same value); you'll need to tweak that part of the format string to suit yourself. This technique is also how I get a colon at the end of a name — format the name and the colon into a string, and then format that string into the final print operation.

How to read float from a file in C

Suppose the file is organized in this way:
1.2 # 3.4 # 4.0
2.3 # 2.3 # 1.2
Read the file in C and store data in an array. Meanwhile, you should judge how many lines there are.
My problem is 1) I don't know how to declare the array as I don't know how many numbers exist in the file, so should I go over the file previously and count the number?
2) I don't know how to judge line number as the last '\n' in the file may exist or may not.
The answer to 1) How to declare the array if you don't know the number of elements in advance, is unsolvable with primitive vectors, you'll have to create your own growing-capable vector.
typedef struct {
double * v;
unsigned int size;
} Vector;
This struct is the basis of the new data type. You'll need an API such as:
Vector createVector();
void addToVector(Vector *v, double x);
double getFromVector(Vector *v, unsigned int pos);
void modifyInVector(Vector *v, unsigned int pos, double x);
unsigned int sizeOfVector(Vector * v);
void destroyVector(Vector *v);
The key members of the API are createVector, destroyVector and addToVector. Since this is probably homework, I won't resolve this to you.
In createVector, you basically have to put all fields to 0.
In destroyVector, you have to free() v;
In addToVector, you'll have to resize() the reserved space so another new item fits:
size_t newSize = ( v->size +1 ) * sizeof( double );
Now you have to call realloc() with the new size.
And that's basically all. If you want better performance, you can introduce also the capacity of the vector, so you don't have to make it grow each time you add a new value. For example, the people that built the STL in C++ make the vector class grow to its double each time the capacity is exceeded. But, anyway, that's another story.
atof (ascii to float):
http://en.wikipedia.org/wiki/Atof
Use fscanf:
The fscanf() function shall read from the named input stream. [...] Each function reads bytes, interprets them according to a format, and stores the results in its arguments. Each expects, as arguments, a control string format described below, and a set of pointer arguments indicating where the converted input should be stored.
The following code reads from the stdin console, processes the numbers in the format you gave and prints them out again so one can check for correctness.
#include <stdio.h>
int main(int ac, char *av[])
{
float a, b, c;
scanf("%f # %f # %f", &a, &b, &c);
printf("%f # %f # %f", a, b, c);
printf("\n");
}
Albeit this code works, it is not very robust. It requires the EXACT sequence ' # ' of characters between numbers and there is nothing but a newline allowed after the last number in a row.
For a more robust solution you would have to find the character index of the start of each number and do a fscanf on that location.
Floating point has precision loss for decimal fractions. For example, a simple number like "0.1" needs an infinite number of bits to represent it accurately.
For the numbers you've shown (only one digit after the decimal point), a better idea would be to multiply each number by 10 to avoid the precision loss that floating point would cause. This would involve writing your own "ASCII to integer" conversion routine that pretends the decimal point is one place to the right of where it actually is. It would also save space, as (for the numbers you've shown, where no number is greater than 25.6) you could store them in an array of 8-bit integers (chars).
Good luck with your homework!

Resources