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
Fix OTP bitstream splicing #15163
Fix OTP bitstream splicing #15163
Conversation
bd05906
to
fbdc515
Compare
fbdc515
to
cdc96f9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I put in some nits about generalizing scripts, but that probably doesn't have to be in this PR.
@@ -102,6 +91,24 @@ filegroup( | |||
}), | |||
) | |||
|
|||
[ | |||
filegroup( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a "manual" tag to these filegroups? That way, Vivado-dependent targets won't get picked up by wildcards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I added to the other filegroups as well. I think that this hasn't been an issue because these targets aren't tests.
# The scrambled Boot ROM is actually 39 bits wide but the updatemem tool segfaults | ||
# for slice sizes not divisible by 8. | ||
if {[expr {($slice_end - $slice_begin + 1) < 8}]} { | ||
if {$filename eq "rom.mmi" && [expr {($slice_end - $slice_begin + 1) < 8}]} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This hard-coded file name key is awkward. Is there an argument we can add that would specifically point to a different desired behavior for this process? (i.e. something that doesn't require knowing the function of the memory but instead describes how the collection of BRAMs should be processed)
At the top level, we'll have the top-specific stuff hard-coded, but this script will be more readily reused if we don't automatically push those all the way to the leaf processes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, I don't understand why we're messing with slice_end
for rom.mmi. This filename check was just meant to preserve the existing behavior for the ROM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It kind of looks like we're lying to updatemem
and saying that the bitlanes cover 40 bits when they actually cover 39. I wonder if this was because you can't write 39 bits with 10 hex digits. Maybe this special case for ROM would not be necessary if we wrote four 39-bit words at a time (39 hex digits)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I've generalized this a bit and it's no longer dependent on the filename. These changes are contained in the new commit, [fpga] Refactor quirks in MMI file generator
. PTAL!
cdc96f9
to
c2e4c31
Compare
I discovered a few problems with the OTP-specific MMI files we have been generating prior to this commit. (1) The file's bitlanes were overlapping. For instance, the first bitlane claimed to cover bits 0-3 (inclusive) and the second one claimed to cover bits 1-4. This is expressly not allowed by Vivado's updatemem manual, so I knew something was wrong. By poking around the Vivado GUI, I realized that OTP bitlanes should each cover a single bit. I'm not sure whether that logic is correct or necessary for the ROM case, so I left it alone. (2) The MMI file claimed that BRAMS are the type "RAMB32" when the OTP BRAMs are actually RAMB18E1. It's not as simple as just saying "RAMB18" in the MMI file. Ultimately, I got it working after bumping the MMI's minor version from 0 to 1 and configuring an environment variable before calling updatemem. (3) The bitlane "Placement" attributes were all wrong because we were trying to trim the "RAMB36_" prefix from strings that actually began with "RAMB18_". (4) The AddressSpace and and DataWidth tags had inaccurate values. Apparently there is a significant amount of padding between OTP words in the OTP BRAMs. In fact, each word is followed by 15 zeroes. Separately, I also modified the TCL script to dump the OTP BRAMs' INIT_XX strings to a text file. Ultimately, examining these INIT_XX strings helped me crack the way that Vivado lays out data in the BRAMs (more detail in a later commit). However, examining the INIT_XX strings in the Vivado GUI required too much clicking; there are 64 INIT_XX strings per OTP BRAM, and there are 22 BRAMs. This is purely a debugging aid, but it only takes a few seconds to generate. Signed-off-by: Dan McArdle <dmcardle@google.com>
c2e4c31
to
e842d02
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ready for another look :)
# The scrambled Boot ROM is actually 39 bits wide but the updatemem tool segfaults | ||
# for slice sizes not divisible by 8. | ||
if {[expr {($slice_end - $slice_begin + 1) < 8}]} { | ||
if {$filename eq "rom.mmi" && [expr {($slice_end - $slice_begin + 1) < 8}]} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I've generalized this a bit and it's no longer dependent on the filename. These changes are contained in the new commit, [fpga] Refactor quirks in MMI file generator
. PTAL!
I noticed that a few unit test targets outside of //sw/... were not running on CI. This commit ensures that CI runs the following additional targets: * //hw/ip/rom_ctrl/util:gen_vivado_mem_image_test (after lowRISC#15163 merges) * //rules/scripts:bitstreams_workspace_test * //util:generate_compilation_db_test Signed-off-by: Dan McArdle <dmcardle@google.com>
I noticed that a few unit test targets outside of //sw/... were not running on CI. This commit ensures that CI runs the following additional targets: * //hw/ip/rom_ctrl/util:gen_vivado_mem_image_test (after lowRISC#15163 merges) * //rules/scripts:bitstreams_workspace_test * //util:generate_compilation_db_test Signed-off-by: Dan McArdle <dmcardle@google.com>
Rather than enabling quirks based on filename, this commit adds parameters to the `generate_mmi` proc. This also simplifies the interface a bit and improves documentation. Signed-off-by: Dan McArdle <dmcardle@google.com>
This script reads MEM files that can be read by Verilog's $readmemh and produces a MEM file that `updatemem` will understand. It turns out that the transformation for ROM data was not right for OTP data due to differences in the underlying hardware. This caught me by surprise because updatemem was exiting successfully. By comparing //hw/ip/otp_ctrl/data:img_rma, which is passed directly to Vivado, with the INIT_XX strings that Vivado produces, I was able to determine the transformation. This commit also includes a few features that I used to bootstrap my understanding: (1) a function that reads INIT_XX strings from OTP BRAMs and produces their memory content and (2) a mocked out updatemem "simulator" that takes hex strings as input and produces the same INIT_XX lines that the real updatemem would. I used a modified version of the sram_program GDB test[0] to dump relevant sections of OTP memory and verify that the OTP values I modified can actually be read from OTP memory. [0]: //sw/device/examples/sram_program:sram_program_fpga_cw310 Signed-off-by: Dan McArdle <dmcardle@google.com>
The new OTP image sets CREATOR_SW_CFG_ROM_EXEC_EN to zero. This commit also adds the get_otp_images() macro to //rules/otp.bzl, which aims to keep OTP splicing targets in //hw/bitstream and //hw/bitstream/vivdao in sync with OTP image definitions. Signed-off-by: Dan McArdle <dmcardle@google.com>
Now that execution is disabled, OpenOCD connection should not be flaky anymore! This should fix lowRISC#15174. Signed-off-by: Dan McArdle <dmcardle@google.com>
e842d02
to
8f27d78
Compare
Whoops, looks like I introduced a division-by-zero error in the CW305 build because there are no OTP cells. https://dev.azure.com/lowrisc/opentitan/_build/results?buildId=97760&view=logs&j=4bc87d6f-5c28-5789-95a2-5c084ae7a0b2&t=054949bd-ad52-58ee-5229-51b7a2cd10e0&l=17991
Just pushed a fix — returning early from the TCL proc when there are no BRAMs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @dmcardle! Since this is such a substantial improvement over the level of OTP splicing support we have right now, which is none :), and since this will unblock several tests, let's get this merged as soon as CI is green. We can improve this incrementally as needed. Also, IIRC @milesdai was working on OTP overlays. We can look into simplifying the new OTP definitions once this is merged.
CI passed! |
I noticed that a few unit test targets outside of //sw/... were not running on CI. This commit ensures that CI runs the following additional targets: * //hw/ip/rom_ctrl/util:gen_vivado_mem_image_test (after lowRISC#15163 merges) * //rules/scripts:bitstreams_workspace_test * //util:generate_compilation_db_test Signed-off-by: Dan McArdle <dmcardle@google.com>
I noticed that a few unit test targets outside of //sw/... were not running on CI. This commit ensures that CI runs the following additional targets: * //hw/ip/rom_ctrl/util:gen_vivado_mem_image_test (after lowRISC#15163 merges) * //rules/scripts:bitstreams_workspace_test * //util:generate_compilation_db_test Signed-off-by: Dan McArdle <dmcardle@google.com>
I noticed that a few unit test targets outside of //sw/... were not running on CI. This commit ensures that CI runs the following additional targets: * //hw/ip/rom_ctrl/util:gen_vivado_mem_image_test (after #15163 merges) * //rules/scripts:bitstreams_workspace_test * //util:generate_compilation_db_test Signed-off-by: Dan McArdle <dmcardle@google.com>
A series of miracles occurred on Friday, enabling me to deduce how updatemem interprets its input and how Vivado lays out data in the BRAMs. With these changes, I can splice OTP values into a bitstream and observe the result in a GDB test! (Now we can disable ROM execution for the SRAM GDB test and drop the flaky tag!)
I think that OTP splicing never worked. To prevent regressions, I think I'll write an "OTP dumper" functest. We can instantiate the functest a few times with a variety of OTP-spliced bitstreams and assert that it prints the expected values.
Fixes #15162
Fixes #15174