opentitanlib/test_utils/
load_bitstream.rs1use anyhow::Result;
6use clap::Args;
7use std::path::{Path, PathBuf};
8use std::time::Duration;
9
10use crate::app::{StagedProgressBar, TransportWrapper};
11use crate::transport::common::fpga::FpgaProgram;
12
13#[derive(Debug, Args)]
15pub struct LoadBitstream {
16 #[arg(long)]
18 pub clear_bitstream: bool,
19
20 #[arg(long)]
22 pub bitstream: Option<PathBuf>,
23
24 #[arg(long, value_parser = humantime::parse_duration, default_value = "50ms")]
26 pub rom_reset_pulse: Duration,
27
28 #[arg(long, value_parser = humantime::parse_duration, default_value = "2s")]
30 pub rom_timeout: Duration,
31}
32
33impl LoadBitstream {
34 pub fn init(&self, transport: &TransportWrapper) -> Result<()> {
35 if self.clear_bitstream {
37 log::info!("Clearing bitstream.");
38 transport.fpga_ops()?.clear_bitstream()?;
39 }
40 if let Some(bitstream) = &self.bitstream {
42 self.load(transport, bitstream)?;
43 }
44
45 Ok(())
46 }
47
48 pub fn load(&self, transport: &TransportWrapper, file: &Path) -> Result<()> {
49 log::info!("Loading bitstream: {:?}", file);
50 let payload = std::fs::read(file)?;
51 let progress = StagedProgressBar::new();
52 let operation = FpgaProgram {
53 bitstream: payload,
54 rom_reset_pulse: self.rom_reset_pulse,
55 rom_timeout: self.rom_timeout,
56 progress: Box::new(progress),
57 };
58
59 if operation.should_skip(transport)? {
60 return Ok(());
61 }
62
63 transport
64 .fpga_ops()?
65 .load_bitstream(&operation.bitstream, &*operation.progress)
66 }
67}