bitsy_lang/sim/ext/
riscv_decoder.rs

1use super::*;
2
3/// Debug monitor for a RISC-V core.
4/// On reset and on clock, decodes the 32-bit value presented to `in` as a RV32I instruction and
5/// prints it to the screen.
6#[derive(Debug)]
7pub struct RiscVDecoder(Option<String>);
8
9impl RiscVDecoder {
10  pub fn new() -> RiscVDecoder {
11      RiscVDecoder(None)
12  }
13}
14
15impl ExtInstance for RiscVDecoder {
16    fn incoming_ports(&self) -> Vec<PortName> { vec!["in".to_string()] }
17    fn outgoing_ports(&self) -> Vec<PortName> { vec![] }
18
19    fn update(&mut self, _port: &PortName, value: Value) -> Vec<(PortName, Value)> {
20        if let Value::Word(32, v) = value {
21            let instr = riscy::decode(v as u32);
22            self.0 = Some(format!("{instr:?}"));
23//            println!("RiscVDecoder: {instr:?}");
24        } else if let Value::X = value {
25            // do nothing
26        } else {
27            panic!("RiscVDecoder expected Word<32>: {value:?}")
28        }
29        vec![]
30    }
31
32    fn clock(&mut self) -> Vec<(PortName, Value)> {
33        if let Some(s) = &self.0 {
34            println!("{s}");
35            self.0 = None;
36        }
37        vec![]
38    }
39
40    fn reset(&mut self) -> Vec<(PortName, Value)> {
41        if let Some(s) = &self.0 {
42            println!("{s}");
43            self.0 = None;
44        }
45        vec![]
46    }
47}