-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make enum encoded FPGA register fields more flexible (#1766)
I'll start off with a bit of context since this is a corner of the system that doesn't get looked at often. We use SystemRDL to define registers in the FPGA. When we build an FPGA, one of the outputs is a JSON file that describes the registers. We commit that JSON file alongside the bitfile in this repo, which then gets turned into Rust by `build/fpga-regmap`. A neat part of this is that we can define enums as a register field in the RTL and carry them into the Rust code via a property we call `encode`. For example, consider the [`STATUS_PORT0` register](https://github.com/oxidecomputer/hubris/blob/master/drv/sidecar-front-io/sidecar_qsfp_x32_controller_regs.json#L1154-L1213). Today, that would generate the following code: ```rust ... #[allow(non_snake_case)] pub mod STATUS_PORT0 { #[allow(dead_code)] #[allow(non_upper_case_globals)] pub const ERROR: u8 = 0b00001111; use num_derive::{ToPrimitive, FromPrimitive}; #[derive(Copy, Clone, Eq, PartialEq, FromPrimitive, ToPrimitive)] #[allow(dead_code)] #[allow(non_camel_case_types, clippy::upper_case_acronyms)] pub enum Encoded { NoError = 0x00, NoModule = 0x01, NoPower = 0x02, PowerFault = 0x03, NotInitialized = 0x04, I2cAddressNack = 0x05, I2cByteNack = 0x06, } #[allow(dead_code)] #[allow(non_upper_case_globals)] pub const BUSY: u8 = 0b00010000; } ... ``` The presence of `encode` in the JSON yields an `Encoded` enum for the register in the Rust. This has a couple of sharp corners, both of which come from behavior that assumes an `encode` type is the only field in a register. 1. You can't have two `encoded` fields within the same register because we currently just name the enum `Encoded`. 2. If you `encoded` field lives alongside any other fields, such as is the case with `BUSY` and `ERROR` above, you need to make sure you're masking off the bits for the `encoded` field only when attempting to resolve to an `Encoded` variant. This PR addresses both of these points by: 1. Naming the enum after the field it is encoding, i.e. `<field>_Encoded`. 2. Implementing `TryFrom<u8>` for the enum and having that automatically handle the bit masking for the field so the programmer doesn't have to remember that. After this PR, that would look like: ```rust ... #[allow(non_snake_case)] pub mod STATUS_PORT0 { #[allow(dead_code)] #[allow(non_upper_case_globals)] pub const ERROR: u8 = 0b00001111; #[derive(Copy, Clone, Eq, PartialEq)] #[allow(dead_code)] pub enum ErrorEncoded { NoError = 0x00, NoModule = 0x01, NoPower = 0x02, PowerFault = 0x03, NotInitialized = 0x04, I2CAddressNack = 0x05, I2CByteNack = 0x06, } impl TryFrom<u8> for ErrorEncoded { type Error = (); fn try_from(x: u8) -> Result<Self, Self::Error> { use crate::Reg::QSFP::STATUS_PORT0::ErrorEncoded::*; let x_masked = x & ERROR; match x_masked { 0x00 => Ok(NoError), 0x01 => Ok(NoModule), 0x02 => Ok(NoPower), 0x03 => Ok(PowerFault), 0x04 => Ok(NotInitialized), 0x05 => Ok(I2CAddressNack), 0x06 => Ok(I2CByteNack), _ => Err(()), } } } #[allow(dead_code)] #[allow(non_upper_case_globals)] pub const BUSY: u8 = 0b00010000; } ... ```
- Loading branch information
1 parent
0c001d4
commit bc3727d
Showing
7 changed files
with
114 additions
and
40 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters