1use std::sync::Arc;
2
3use crate::{
4 DummyMemPlanner, InputDataSM, MemAlignByteInstance, MemAlignByteSM, MemAlignInstance,
5 MemAlignReadByteInstance, MemAlignSM, MemAlignWriteByteInstance, MemModuleInstance, MemPlanner,
6 MemSM, RomDataSM,
7};
8use fields::PrimeField64;
9use mem_common::MemCounters;
10use pil_std_lib::Std;
11use proofman_common::ProofCtx;
12use zisk_common::{BusDeviceMetrics, ComponentBuilder, Instance, InstanceCtx, Plan, Planner};
13use zisk_pil::{
14 InputDataTrace, MemAlignByteTrace, MemAlignReadByteTrace, MemAlignTrace,
15 MemAlignWriteByteTrace, MemTrace, RomDataTrace, ZiskProofValues,
16};
17
18pub struct Mem<F: PrimeField64> {
19 // Secondary State machines
20 mem_sm: Arc<MemSM<F>>,
21 mem_align_sm: Arc<MemAlignSM<F>>,
22 mem_align_byte_sm: Arc<MemAlignByteSM<F>>,
23 input_data_sm: Arc<InputDataSM<F>>,
24 rom_data_sm: Arc<RomDataSM<F>>,
25}
26
27impl<F: PrimeField64> Mem<F> {
28 pub fn new(std: Arc<Std<F>>) -> Arc<Self> {
29 let mem_align_sm = MemAlignSM::new(std.clone());
30 let mem_sm = MemSM::new(std.clone());
31 let input_data_sm = InputDataSM::new(std.clone());
32 let rom_data_sm = RomDataSM::new(std.clone());
33 let mem_align_byte_sm = MemAlignByteSM::new(std.clone());
34
35 Arc::new(Self { mem_align_sm, mem_sm, input_data_sm, rom_data_sm, mem_align_byte_sm })
36 }
37
38 pub fn build_mem_counter(&self) -> MemCounters {
39 MemCounters::new()
40 }
41
42 // This method is used to create a dummy planner when using count-and-plan in C++
43 pub fn build_dummy_planner(&self) -> Box<dyn Planner> {
44 Box::new(DummyMemPlanner::new())
45 }
46}
47
48impl<F: PrimeField64> ComponentBuilder<F> for Mem<F> {
49 fn build_counter(&self) -> Option<Box<dyn BusDeviceMetrics>> {
50 Some(Box::new(MemCounters::new()))
51 }
52
53 fn build_planner(&self) -> Box<dyn Planner> {
54 Box::new(MemPlanner::new())
55 }
56
57 fn configure_instances(&self, pctx: &ProofCtx<F>, plannings: &[Plan]) {
58 let enable_input_data = plannings.iter().any(|p| p.air_id == InputDataTrace::<F>::AIR_ID);
59 let enable_rom_data = plannings.iter().any(|p| p.air_id == RomDataTrace::<F>::AIR_ID);
60 let mut proof_values = ZiskProofValues::from_vec_guard(pctx.get_proof_values());
61 proof_values.enable_input_data = F::from_bool(enable_input_data);
62 proof_values.enable_rom_data = F::from_bool(enable_rom_data);
63 }
64
65 /// Builds an instance of the Memory state machine.
66 ///
67 /// # Arguments
68 /// * `ictx` - The context of the instance, containing the plan and its associated
69 ///
70 /// # Returns
71 /// A boxed implementation of a Memory Instance.
72 fn build_instance(&self, ictx: InstanceCtx) -> Box<dyn Instance<F>> {
73 match ictx.plan.air_id {
74 MemTrace::<F>::AIR_ID => Box::new(MemModuleInstance::new(self.mem_sm.clone(), ictx)),
75 RomDataTrace::<F>::AIR_ID => {
76 Box::new(MemModuleInstance::new(self.rom_data_sm.clone(), ictx))
77 }
78 InputDataTrace::<F>::AIR_ID => {
79 Box::new(MemModuleInstance::new(self.input_data_sm.clone(), ictx))
80 }
81 MemAlignTrace::<F>::AIR_ID => {
82 Box::new(MemAlignInstance::new(self.mem_align_sm.clone(), ictx))
83 }
84 MemAlignByteTrace::<F>::AIR_ID => {
85 Box::new(MemAlignByteInstance::new(self.mem_align_byte_sm.clone(), ictx))
86 }
87 MemAlignReadByteTrace::<F>::AIR_ID => {
88 Box::new(MemAlignReadByteInstance::new(self.mem_align_byte_sm.clone(), ictx))
89 }
90 MemAlignWriteByteTrace::<F>::AIR_ID => {
91 Box::new(MemAlignWriteByteInstance::new(self.mem_align_byte_sm.clone(), ictx))
92 }
93 _ => panic!("Memory::get_instance() Unsupported air_id: {:?}", ictx.plan.air_id),
94 }
95 }
96}