$readmemh to load subblocks of memory - system-verilog

Sorry if the question is too newbie. I have been looking for information on readmemh and I haven't been able to find a suitable solution to my problem.
I have a large hex file with the contents of a memory to read from it. But since the file is just too large I want to be able to bring to my program just a smaller memory block every time. For example, if my memory has addresses 32 bits long, being able to load only chunks of 2048 addresses and storing in a variable the upper part to know if I'm in the right chunk or not.
Or more or less, if my hex file is as follows:
#00000000 1212
#00000001 3434
#00000002 5656
...
#ffffffff 9a9a
I want to be able to save it in a structure with the following fields:
logic [15:0] chunck [11:0]; // Keeps 2048 entries
logic [20:0] address_top; // Keeps the top part of the address
Looking at the documentation, I see that readmemh allows me to indicate a start and an end address, but what I am seeing is that it refers to the position in the destination array, not from the source.
How can I do it?
Thanks in advance!

If you are using SystemVerilog, then you can use an associative array to model your memory, and let it take care a allocating and mapping the physical memory as needed, instead of doing it yourself.

Related

EFI_FILE_HANDLE->Write crashes when writing more than about 3.4 GiB

I'm writing an UEFI application that should be able to write a lot of data to disk.
I'm aware of the FAT-32 file size limitations and number of files per directory etc. That should not be the problem. The memory region I'm trying to write is marked as usable by the memory map und I can read/write to it without problems but after a certain amount of data my vm just reboots without any error messages.
The following line makes problems:
uefi_call_wrapper(handle->Write, 3, handle, size, content);
handle is initialized a few lines earlier, size is always max 128MiB and content a valid memory region with read/write access.
I've already rewritten the whole thin on Windows with EDK2 and got the same problems.
Can anyone help me with this?
Thank you in advance and have a nice evening
Assuming that handle is a pointer to EFI_FILE_PROTOCOL, the BufferSize parameter to Write is passed by reference. When the function returns, BufferSize contains the number of bytes written. You didn't give enough context in your question, but it looks like you are passing it by value.
Hi guys and thank you for you answeres. The size argument is a pointer. I've just found the solution for the problem. I didn't know I have to reset the watchdog timer.
After calling uefi_call_wrapper(ST->BootServices->SetWatchdogTimer, 4, 0, 0, 0, NULL); everything works as expected
Cheers!

C socket programming recv size

I am a newbie in socket programming(in C), maybe this question is a litter bit stupid. In C socket programming, how should I determine the size of buffer of the function recv()/read()? As in many cases, we don't know the size of data sent using send()/write(). Thanks a lot!
how should I determine the size of buffer of the function
recv()/read()
Ideally one shouldn't look at these buffers and keep to the olden TCP model: keep reading bytes while bytes are available.
If you are asking this question for things like: "how big should be the buffer into which I receive?", the simple answer is to pick a size and just pass that. If there's more data you can read again.
Back to your original question, different stacks give you different APIs. For example on some Unixes you have things like SIOCINQ and FIONREAD. These give you the amount of data the kernel has in its receive buffer, waiting for you to copy it out.
If you don't really know how many bytes are expected, use a large buffer and pass a large buffer size to recv/read. These functions will return how many bytes were put into the buffer. Then you can deal with this data printing it, for example.
But keep in mind that data is often either sent in chunks of known size or sent with a message-size in the first bytes, so the receiver side is able to identify how many bytes should be read.

Which addressing mode permits relocation without any change whatsoever in the code?

The options are :
Indexed addressing
Base register addressing
PC relative addressing
Indexed and Base register addressing both work by adding the content of their respective register (Index / Base register) to the address mentioned in the address code.
[Though the subtle difference is Index register has its content as "index" of the array while the Base register has its content as "base" address of the array]
To make the code relocatable, only the content of the Base / Index register needs to be changed, but that too can only be accomplished by executing some additional code.
PC relative mode just references the other instructions relative to the current PC contents.
So, is option 3 the best answer ?
Thanks !!
There are multiple parts:
- Data: this is about loading values that are in a binary
- Code: this is about jumps and calls
Data doesn't matter much. Code is more interesting.
In the absolute case you call . You write the code so is right most of the time. If it is not, the loader patches it right there in the code.
In the relative case, you have to call which then calls So one extra hop.
In the end 3 is more flexible but might have a small runtime overhead.
Another reason why PC relative all the time can have extra costs is that the PC distance might not be the whole address space.
Absolute addressing can be a small optimization. But also costs more to start when things go wrong.

What makes NSdata advantageous?

I've been looking through the apple documentation for the NSdata class, and I didn't really find it too enlightening. I know how to use the class but I don't really understand the gravity of the advantages that it may or may not provide. I know its a simple question but perhaps it would be good to have such information as a reference.
Advantages over what? Certainly, it's useful to represent an arbitrary block of data as an object just as it's useful to represent a string, a number, or a value as an object. Memory management becomes simpler and is consistent with memory management for all other objects, and there are a number of useful methods defined.
Say you want to read a binary file into memory. We won't worry about the reasons why -- there are as many reasons as there are data file formats. You'll have to:
Check the size of the file
Allocate a block of memory of the proper size
Open the file
Read the contents into memory
Close the file
Remember to free the memory when you're done with it (a condition that can sometimes be tricky to detect)
(Optional) Worry about whether the block of memory has been modified
With NSData, you can just create a new instance from a path or URL and not have to think about the rest.

Why syncblk is located at -4 and not at 0?

So if you want to look at sync block for an object, under sos you have to look at -4 bytes (on 32 bit machines) before the object address. Does anyone know what is the wisdom for going back 4 bytes? I mean they could have sync block at 0, then type handle at +4 and then object fields at +8.
This is an implementation detail, so I can't give you the exact reason for the placement of the syncblock. However, if you look at the shared source CLI, you'll see that the runtime has all sorts of optimizations for how objects are allocated and used, and actually the data associated with a single instance is located in several different places. The syncblock for instance is just an index value for a structure located elsewhere. Similarly the MethodTable and the EEClass are stored elsewhere. These are all implementation details. The important point IMO is understanding how to dig out the information needed during debugging. It is of much less importance to understand why the implementation details are as they are.
I'd say it matches expectations, especially for structs that have been explicitly laid out. As Brian says, it's just an implementation detail though. It's similar to how many implementations of malloc will allocate more space than requested, store the allocation size in the first four (or eight) bytes, and then return a pointer that is offset to point to the next byte beyond that.