perilus

RISC-V processor built with Chisel
git clone https://git.bradleygannon.com/perilus.git
Log | Files | Refs | Submodules | README

state.rs (3475B)


      1 #[derive(Clone, Copy, PartialEq, Eq)]
      2 pub(crate) enum RunState {
      3     Idle,
      4     FreeRun,
      5     RunToPc(u32),
      6 }
      7 
      8 impl std::fmt::Display for RunState {
      9     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     10         match self {
     11             RunState::Idle => write!(f, "Idle"),
     12             RunState::FreeRun => write!(f, "Running"),
     13             RunState::RunToPc(pc) => write!(f, "Run to 0x{pc:08x}"),
     14         }
     15     }
     16 }
     17 
     18 #[derive(Clone, Copy, PartialEq, Eq)]
     19 pub(crate) enum ViewMode {
     20     Word,
     21     Byte,
     22 }
     23 
     24 /// Which pane receives keyboard editing.
     25 #[derive(Clone, Copy, PartialEq, Eq)]
     26 pub(crate) enum Focus {
     27     Registers,
     28     Memory,
     29 }
     30 
     31 pub(crate) fn register_alias(index: usize) -> &'static str {
     32     match index {
     33         0 => "zero",
     34         1 => "ra",
     35         2 => "sp",
     36         3 => "gp",
     37         4 => "tp",
     38         5 => "t0",
     39         6 => "t1",
     40         7 => "t2",
     41         8 => "s0/fp",
     42         9 => "s1",
     43         10 => "a0",
     44         11 => "a1",
     45         12 => "a2",
     46         13 => "a3",
     47         14 => "a4",
     48         15 => "a5",
     49         16 => "a6",
     50         17 => "a7",
     51         18 => "s2",
     52         19 => "s3",
     53         20 => "s4",
     54         21 => "s5",
     55         22 => "s6",
     56         23 => "s7",
     57         24 => "s8",
     58         25 => "s9",
     59         26 => "s10",
     60         27 => "s11",
     61         28 => "t3",
     62         29 => "t4",
     63         30 => "t5",
     64         31 => "t6",
     65         _ => "??",
     66     }
     67 }
     68 
     69 pub(crate) fn printable(byte: u8) -> char {
     70     if (b' '..=b'~').contains(&byte) {
     71         byte as char
     72     } else {
     73         '.'
     74     }
     75 }
     76 
     77 pub(crate) fn hex_char(nibble: u8) -> char {
     78     std::char::from_digit(nibble as u32, 16).unwrap_or('?')
     79 }
     80 
     81 /// Screen order of the 64 hex digits in one memory row, as
     82 /// `(byte offset within the row, nibble index)` where nibble 0 is the high
     83 /// nibble of the byte and 1 is the low nibble.
     84 ///
     85 /// Word view prints each 32-bit word big-endian, so the bytes within a word
     86 /// appear in descending address order. Byte view prints bytes in ascending
     87 /// memory order.
     88 pub(crate) fn row_digits(view: ViewMode) -> [(u32, u8); 64] {
     89     let mut out = [(0u32, 0u8); 64];
     90     let mut i = 0;
     91     match view {
     92         ViewMode::Word => {
     93             for word in 0..8u32 {
     94                 for byte in (0..4u32).rev() {
     95                     out[i] = (word * 4 + byte, 0);
     96                     i += 1;
     97                     out[i] = (word * 4 + byte, 1);
     98                     i += 1;
     99                 }
    100             }
    101         }
    102         ViewMode::Byte => {
    103             for byte in 0..32u32 {
    104                 out[i] = (byte, 0);
    105                 i += 1;
    106                 out[i] = (byte, 1);
    107                 i += 1;
    108             }
    109         }
    110     }
    111     out
    112 }
    113 
    114 #[cfg(test)]
    115 mod tests {
    116     use super::*;
    117 
    118     #[test]
    119     fn aliases_cover_register_file() {
    120         assert_eq!(register_alias(0), "zero");
    121         assert_eq!(register_alias(8), "s0/fp");
    122         assert_eq!(register_alias(17), "a7");
    123         assert_eq!(register_alias(31), "t6");
    124     }
    125 
    126     #[test]
    127     fn printable_only_decodes_ascii() {
    128         assert_eq!(printable(b'A'), 'A');
    129         assert_eq!(printable(b' '), ' ');
    130         assert_eq!(printable(0), '.');
    131         assert_eq!(printable(0x7f), '.');
    132     }
    133 
    134     #[test]
    135     fn row_digit_order() {
    136         let word = row_digits(ViewMode::Word);
    137         assert_eq!(word[0], (3, 0));
    138         assert_eq!(word[7], (0, 1));
    139         let byte = row_digits(ViewMode::Byte);
    140         assert_eq!(byte[0], (0, 0));
    141         assert_eq!(byte[63], (31, 1));
    142     }
    143 }