opentitanlib/test_utils/
load_bitstream.rs1use anyhow::Result;
6use clap::Args;
7use std::path::{Path, PathBuf};
8
9use crate::app::{StagedProgressBar, TransportWrapper};
10use crate::io::jtag::JtagParams;
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)]
26 pub force: bool,
27}
28
29impl LoadBitstream {
30 pub fn init(&self, transport: &TransportWrapper, jtag_params: &JtagParams) -> Result<()> {
31 if self.clear_bitstream {
33 log::info!("Clearing bitstream.");
34 transport.fpga_ops()?.clear_bitstream()?;
35 }
36 if let Some(bitstream) = &self.bitstream {
38 self.load(transport, bitstream, jtag_params)?;
39 }
40
41 Ok(())
42 }
43
44 pub fn load(
45 &self,
46 transport: &TransportWrapper,
47 file: &Path,
48 jtag_params: &JtagParams,
49 ) -> Result<()> {
50 log::info!("Loading bitstream: {:?}", file);
51 let payload = std::fs::read(file)?;
52 let progress = StagedProgressBar::new();
53 let operation = FpgaProgram {
54 bitstream: payload,
55 progress: Box::new(progress),
56 };
57
58 if !self.force && operation.should_skip(transport, jtag_params)? {
59 return Ok(());
60 }
61
62 transport
63 .fpga_ops()?
64 .load_bitstream(&operation.bitstream, &*operation.progress)
65 }
66}