ab_riscv_interpreter/
zkr.rs1#[cfg(test)]
4mod tests;
5pub mod zkr_helpers;
6
7use crate::zicsr::zicsr_helpers;
8use crate::{
9 CsrError, Csrs, ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands,
10 ExecutionError, ExecutionResult, FetchInstructionResult, InstructionFetcher,
11 OpaqueThreadedExecutionResult, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
12 ThreadedExecutableInstruction, ThreadedExecutionResult,
13};
14use ab_riscv_macros::instruction_execution;
15use ab_riscv_primitives::prelude::*;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum ZkrSeedPoll {
21 Bist,
26 Wait,
31 Es16(u16),
34 Dead,
38}
39
40pub const trait ZkrSeedSource {
44 fn poll_seed(&mut self) -> ZkrSeedPoll;
46}
47
48const impl<T> ZkrSeedSource for &mut T
50where
51 T: [const] ZkrSeedSource,
52{
53 #[inline(always)]
54 fn poll_seed(&mut self) -> ZkrSeedPoll {
55 T::poll_seed(self)
56 }
57}
58
59#[instruction_execution]
60const impl<Reg, Hart> ExecutableInstructionOperands for ZkrInstruction<Hart>
61where
62 Reg: [const] Register,
63 Hart: HartConfig<Reg = Reg>,
64{
65}
66
67#[instruction_execution]
68const impl<Reg, Hart, Env> ExecutableInstructionCsr<Env> for ZkrInstruction<Hart>
69where
70 Reg: [const] Register,
71 Hart: HartConfig<Reg = Reg>,
72 Env: [const] ZkrSeedSource,
73{
74 #[inline(always)]
80 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
81 fn prepare_csr_read(
82 _env: &Env,
83 csr_index: u16,
84 will_write: bool,
85 raw_value: Reg::Type,
86 output_value: &mut Reg::Type,
87 ) -> Result<bool, CsrError> {
88 if csr_index == SEED_CSR_INDEX {
89 if will_write {
90 *output_value = raw_value;
91 Ok(true)
92 } else {
93 Err(CsrError::IllegalRead { csr_index })
94 }
95 } else {
96 Ok(false)
97 }
98 }
99
100 #[inline(always)]
104 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
105 fn prepare_csr_write(
106 env: &mut Env,
107 csr_index: u16,
108 write_value: Reg::Type,
109 output_value: &mut Reg::Type,
110 ) -> Result<bool, CsrError> {
111 let _: Reg::Type = write_value;
113
114 if csr_index == SEED_CSR_INDEX {
115 *output_value = zkr_helpers::encode_seed_poll::<Reg>(env.poll_seed());
116 Ok(true)
117 } else {
118 Ok(false)
119 }
120 }
121}
122
123#[instruction_execution]
124const impl<Reg, Hart, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
125 for ZkrInstruction<Hart>
126where
127 Reg: Register,
128 Hart: HartConfig<Reg = Reg>,
129 Env: [const] ZkrSeedSource,
130{
131 #[inline(always)]
132 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
133 fn execute(
134 self,
135 Rs1Rs2OperandValues {
136 rs1_value,
137 rs2_value: _,
138 }: Rs1Rs2OperandValues<Reg::Type>,
139 _regs: &mut Regs,
140 env: &mut Env,
141 _memory: &mut Memory,
142 _program_counter: &PC,
143 ) -> ExecutionResult<Reg> {
144 ExecutionResult::ContinueNoWrite
145 }
146}