Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluesim leaves junk in loaded registers if the full range of hex digits isn't specified #650

Open
nanavati opened this issue Dec 13, 2023 · 3 comments

Comments

@nanavati
Copy link
Collaborator

When using RegFileLoad Bluesim appears to only initialize the digits of the data value that are explicitly specified in the file, rather than zero-extending the specified number to the full data word. So if you have an 80-bit value you want to load you have to specify all 20 hex digits even if some of the high digits are zero.

Icarus Verilog, on the other hand, interprets the value as a number and zero-extends so the attached test passes with it, while it fails with Bluesim.

regfile_load_bug.zip

@quark17
Copy link
Collaborator

quark17 commented Dec 13, 2023

The values should be zero-extended; if Bluesim is not doing that, that's a bug. Your example is showing a bug specifically for reading in "wide" data (width > 64), but it would be worth checking the behavior for all the types that Bluesim supports: tUInt8 (for bit vectors up to width 8), tUInt32 (up to 32), tUInt64 (up to 64), and tUWide (65+). Your example is not predictable -- sometimes the values in memory are already zero, so no error is reported -- so I'm unsure how we can add it to the testsuite. Also, we should test the situation when too many digits are provided -- Bluesim should at least report a warning, and it shouldn't overflow the storage and keep writing the digits into memory (but, again, I'm unsure how to test that). We should at least do a manual inspection of the Bluesim code, though.

The code for reading in a memhex file is in bsc/src/bluesim/mem_file.cxx, specifically in the overloaded functions parse_hex and parse_bin (as declared in the header bs_mem_file.h). These are overloaded for each the data types (tUInt8, tUInt32, tUInt64, and tUWide). Wide data is an array of unsigned int. For parsing in wide data, the function goes to the last digit in the string and works its way to front; it accumulates the value for each unsigned int and then writes it to the place in the array. If there is not a full word of digits left at the end, the code writes the value to the full word -- so it is zero-extending up to the word boundary. The problem is that there may be more words in the wide value, and nothing writes zeros into those final words.

I would guess that, at line 649 in mem_file.cxx (for parsing hex) and line 591 (for parsing binary), we should adjust/add something like this (note the addition of ++ in the partial word assignment):

// write partial word at end
if (idx != 0)
  (*value)[word++] = x;

// zero extend any unspecified words
while (word < (data_bits % WORD_SIZE))
  (*value)[word++] = 0;

@quark17
Copy link
Collaborator

quark17 commented Dec 13, 2023

FYI, some testing of RegFile load for Bluesim happens in bsc.bluesim/misc/ in the files WideRF.bsv, WindowsRF.bsv, and SparseRF.bsv. I would guess that tests for fewer and greater digits (for bin and hex, and for each of the data types) would go in that directory as well.

@rossc719g
Copy link

FWIW, I believe it already does complain if you provide too many digits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants