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
boards/opentitan: Build OpenTitan with target device specific parameters #1741
boards/opentitan: Build OpenTitan with target device specific parameters #1741
Conversation
8354610
to
f6b97cd
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.
I'm not sure if the values for the different configuration constants should come from the top (i.e. from a verilator.config file that lives in the board repo) or be set in the chip crate (as they currently are in this PR). Does it make sense for users to be able to easily customize them, or is the number of options reasonably fixed?
In the case where the configuration settings are in the chip crate, I think they should be in their own file (like config.rs in the kernel crate) where we can specify what the different versions are and what the different settings are.
boards/opentitan/src/main.rs
Outdated
@@ -126,7 +126,7 @@ pub unsafe fn reset_handler() { | |||
// Create a shared UART channel for the console and for kernel debug. | |||
let uart_mux = components::console::UartMuxComponent::new( | |||
&ibex::uart::UART0, | |||
230400, | |||
ibex::uart::UART0_BAUDRATE, |
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.
Why is this variable? Why would different board versions want to use different baud rates? Shouldn't this be set to 115200 like the other boards?
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.
I think the idea was to have fast baud rate for the FPGA, and then the standard rate for the verialtor.
I guess we probably could use 115200, but for consistency with OT I wanted to have the same values. I think it could be a good idea to make this more flexible for users to set up, along with the target device frequency.
chips/ibex/src/chip.rs
Outdated
pub const CHIP_FREQ: u32 = 50_000_000; | ||
|
||
#[cfg(target_device = "verilator")] | ||
pub const CHIP_FREQ: u32 = 500_000; |
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.
This type of configuration makes using other cargo tools (like clippy for example) difficult, because things outside of the makefile flow end up with no CHIP_FREQ
set, which makes rust complain.
I'm generally very opposed to cfgs as their use makes embedded code bases very difficult to comprehend. At least in this use determining which to use is at least based on hardware, which makes tracking down the correct setting somewhat reasonable, even for a new user. However, there are still weaknesses:
- Someone looking at this file has to reason about how
target_device
is set. In other cases it comes from a Cargo.toml file, but now it also could be from a makefile flag. This adds complexity, which is particularly difficult for new users. - cfgs in general don't seem to have a good way to document them. What is a target_device? And what is nexysvideo/verliator? What are all of the choices for what is a valid
target_device
?
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.
I agree. I was thinking to make a split something along the lines of what boards/nordic
and others do. However it is slightly awkward as nexysvideo and verilator is the same Opentitan RTL. That also brings me to a separate question, whether in chips split into lowrisc and ibex is right, or should be done somewhat differently?
The purpose of this PR was to test out the waters, and get some advice. Thanks.
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.
because things outside of the makefile flow end up with no
CHIP_FREQ
set
I think this is the primary issue: statements are not being generated. I think this problem can be circumvented or at least reduced by resorting to the cfg!(...)
macro. I guess using something like this in the code should work:
let chip_freq =
if cfg!(target_device = "verilator") {
500_000
} else {
other_freq
};
As every if
is an expression, this forces you to provide a return value in every case and shouldn't be able to cause compile errors (although you can of course deliberately panic or abort compilation in a branch). Even within runtime code, this would be inlined as to have no performance impact.
Maybe it would be better to just make the clock speed settable for all targets? When running the HiFive1 executables on QEMU there are issues with clock speed as well. Some way to override the default from the command line would be useful and would apply to all platforms instead of just OT. |
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.
I agree with @alistair23 it seems like a useful feature overall, however, maybe it is worth instead of a single value be able to supply more data? We could have a config file/files under board
or chip
directories, and during the build point Cargo
, or build.rs,
or some other means to one of them? There could be a default config that is built, if nothing is specified or something similar.
At the moment it is thinking out loud, does what I said above make sense? :)
bd017d3
to
fcc1ac9
Compare
I have completely refactored my change, now it uses What I have noticed in |
Could someone please help me out with the error travis is getting: Local build seems to work without any issues. |
I'm not sure what exactly travis is doing, but doing a Something like
This allows |
I see, thank you @jon-flatley , my bad - I was only looking at this from the perspective of build being triggered through Your suggestion makes sense, but I think I will refactor my change a little to (probably) move the |
Overall this looks fine to me, it seems pretty clear but still flexible. |
i think difference is primarily in a way CARGO_FLAGS or CARGO_OPTIONS are constructed. CARGO_FLAGS allows redefinition of all flags, while CARGO_OPTIONS relies on some defaults. I can add CARGO_OPTIONS to #1771 CARGO_FLAGS. |
Add CARGO_OPTIONS from tock#1741 to CARGO_FLAGS to unify both approaches. Few more comments to explain use for CARGO_OPTIONS and RUSTFLAGS_FOR_BOARD
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.
@silvestrst Are you okay waiting for #1771 to merge (after 1.5 release) and then rebasing this on that?
@ppannuto no problem, this PR is not urgent. Thank you for letting me know. |
fcc1ac9
to
59cfb3e
Compare
It seems that there are fair amount of people asking for extending In the latest push:
My approach is to specify additional feature in This is more or less what @jon-flatley suggested, but without the need to explicitly check all of the features to figure out whether none of them are requested. |
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.
I think this is pretty reasonable, but I find cargo features to be terribly confusing. Is this really the only way to have a default option?
The problem is that I couldn't find any way to pass It would be best to not have a Do you find how features are used here confusing in general, or just the |
I agree it's not the best, the alternative would be to obtain these values runtime like @lschuermann suggested. The problem with that is then you wouldn't be able to simply do this: Meanwhile will push what I have got now. |
I don't think that is possible. Cargo features don't take any additional parameters, and in general are very rigid. There is fair amount of discussion around different ways of improving Cargo "features" feature, however most of these threads and issues are stale. To name few: To be honest I still think that Ibex is not an appropriate name for the chip level crate, which in my opinion should be With this change An alternative could be to change peripheral instantiation from compile time to runtime, and also passing configuration into |
I guess this PR is now blocked on #1997. I think when const context control flow Rust upstream change propagates in the nightly toolchain, this change probably could be made more elegant. |
1997: chip: rename Ibex to EarlGrey r=ppannuto a=silvestrst Currently EarlGrey is the first and only OpenTitan SoC design, with Ibex CPU at the heart. Ibex being a CPU does not have any knowledge of EarlGrey peripherals, and hence was misrepresented in Tock. This has caused some confusion to how exactly it was intended to be used, and did not achieve the goals of being stand alone crate, as it was coupled to heavily with the OpenTitan board. ### Pull Request Overview This pull request renames Ibex crate to EarlGrey, because de facto - that's what it is. This change also makes #1741 more reasonable. ### Testing Strategy - [x] Should be tested on FPGA or verilator before merging. ### Documentation Updated - [x] Updated the relevant files in `/docs`, or no updates are required. ### Formatting - [x] Ran `make prepush`. Co-authored-by: Silvestrs Timofejevs <silvestrst@lowrisc.org>
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.
Looks good.
f69f264
to
71ce625
Compare
There is currently no way to pass build options to cargo. This change adds a make variable that allows board specific makefiles to pass down build options. For example, in 'board/<custom_board>/Makefile': 'CARGO_FLAGS += --features=foo' would pass feature 'foo' to the top level Cargo.toml.
OpenTitan can run on a physical chip, an FPGA or simulated on verilator. These devices require different configuration: cock speed, uart baudrate, etc... This change allows to pass configuration options to different OpenTitan components.
Use target specific configuration parameters instead of hardcoded values.
71ce625
to
f564570
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.
This looks good. It would be nice to eventually have a make verilator
target that runs the kernel in verilator in the same way make qemu
runs the kernel in qemu. But that would require documentation in Tock on how users can get verilator working, so I it probably deserves to be a separate PR.
No explicit default copy.
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.
I added some more documentation, and removed the explicit default configuration copy.
I also added the configuration name to the debug printout.
@bradjc thank you for polishing this change, especially the documentation changes! |
Thank you guys for your help with pushing this change over the hump! |
I think Pat's request was for 1.5, which is long in the past. |
Related to 1.5 which is long since been released.
bors r+ |
Pull Request Overview
I think it is useful to be able to pass options to cargo from the board specific makefiles. This PR does it in a controlled way, by not getting the
CARGO_FLAGS
from the environment, but modified from within the board makefiles.Rust features add some flexibility. In this case they serve as simple
#[cfg(feature = "sim_verilator")]
, but could be used to pull in optional dependencies.This pull request consists of three changes:
makefile
change to pass features to Cargo.boards/opentitan
,chips/earlgrey)
to pass requested features. It also adds a configuration file, which based on the requested feature initialises a structure with the device specific information.Testing Strategy
This pull request was tested by running on the verilator with environment variable
BOARD_CONFIGURATION=sim_verilator
, and observing the expected UART output. When built for the fpga, and ran on verilator, no output was observed (expected).TODO or Help Wanted
Documentation Updated
No updates are required?
Formatting
make formatall
.