@@ -19,7 +19,7 @@ use crate::{
1919} ;
2020use ceno_emul:: FullTracer as Tracer ;
2121use multilinear_extensions:: { Expression , ToExpr , WitIn } ;
22- use std:: { iter, marker:: PhantomData } ;
22+ use std:: { array , iter, marker:: PhantomData } ;
2323
2424#[ derive( Debug ) ]
2525pub struct StateInOut < E : ExtensionField > {
@@ -108,6 +108,34 @@ impl<E: ExtensionField> ReadRS1<E> {
108108 } )
109109 }
110110
111+ pub fn construct_conditional_circuit (
112+ circuit_builder : & mut CircuitBuilder < E > ,
113+ is_enable : Expression < E > ,
114+ rs1_read : RegisterExpr < E > ,
115+ cur_ts : WitIn ,
116+ ) -> Result < Self , ZKVMError > {
117+ let id = circuit_builder. create_witin ( || "rs1_id" ) ;
118+ let prev_ts = circuit_builder. create_witin ( || "prev_rs1_ts" ) ;
119+ circuit_builder
120+ . conditional_rw_selector ( is_enable, |circuit_builder| {
121+ let ( _, lt_cfg) = circuit_builder. register_read (
122+ || "read_rs1" ,
123+ id,
124+ prev_ts. expr ( ) ,
125+ cur_ts. expr ( ) + Tracer :: SUBCYCLE_RS1 ,
126+ rs1_read,
127+ ) ?;
128+
129+ Ok ( ReadRS1 {
130+ id,
131+ prev_ts,
132+ lt_cfg,
133+ _field_type : PhantomData ,
134+ } )
135+ } )
136+ . map_err ( ZKVMError :: CircuitBuilderError )
137+ }
138+
111139 pub fn assign_instance (
112140 & self ,
113141 instance : & mut [ <E as ExtensionField >:: BaseField ] ,
@@ -175,6 +203,34 @@ impl<E: ExtensionField> ReadRS2<E> {
175203 } )
176204 }
177205
206+ pub fn construct_conditional_circuit (
207+ circuit_builder : & mut CircuitBuilder < E > ,
208+ is_enable : Expression < E > ,
209+ rs2_read : RegisterExpr < E > ,
210+ cur_ts : WitIn ,
211+ ) -> Result < Self , ZKVMError > {
212+ let id = circuit_builder. create_witin ( || "rs2_id" ) ;
213+ let prev_ts = circuit_builder. create_witin ( || "prev_rs2_ts" ) ;
214+ circuit_builder
215+ . conditional_rw_selector ( is_enable, |circuit_builder| {
216+ let ( _, lt_cfg) = circuit_builder. register_read (
217+ || "read_rs2" ,
218+ id,
219+ prev_ts. expr ( ) ,
220+ cur_ts. expr ( ) + Tracer :: SUBCYCLE_RS2 ,
221+ rs2_read,
222+ ) ?;
223+
224+ Ok ( ReadRS2 {
225+ id,
226+ prev_ts,
227+ lt_cfg,
228+ _field_type : PhantomData ,
229+ } )
230+ } )
231+ . map_err ( ZKVMError :: CircuitBuilderError )
232+ }
233+
178234 pub fn assign_instance (
179235 & self ,
180236 instance : & mut [ <E as ExtensionField >:: BaseField ] ,
@@ -245,6 +301,36 @@ impl<E: ExtensionField> WriteRD<E> {
245301 } )
246302 }
247303
304+ pub fn construct_conditional_circuit (
305+ circuit_builder : & mut CircuitBuilder < E > ,
306+ is_enable : Expression < E > ,
307+ rd_written : RegisterExpr < E > ,
308+ cur_ts : WitIn ,
309+ ) -> Result < Self , ZKVMError > {
310+ let id = circuit_builder. create_witin ( || "rd_id" ) ;
311+ let prev_ts = circuit_builder. create_witin ( || "prev_rd_ts" ) ;
312+ let prev_value = UInt :: new_unchecked ( || "prev_rd_value" , circuit_builder) ?;
313+ circuit_builder
314+ . conditional_rw_selector ( is_enable, |circuit_builder| {
315+ let ( _, lt_cfg) = circuit_builder. register_write (
316+ || "write_rd" ,
317+ id,
318+ prev_ts. expr ( ) ,
319+ cur_ts. expr ( ) + Tracer :: SUBCYCLE_RD ,
320+ prev_value. register_expr ( ) ,
321+ rd_written,
322+ ) ?;
323+
324+ Ok ( WriteRD {
325+ id,
326+ prev_ts,
327+ prev_value,
328+ lt_cfg,
329+ } )
330+ } )
331+ . map_err ( ZKVMError :: CircuitBuilderError )
332+ }
333+
248334 pub fn assign_instance (
249335 & self ,
250336 instance : & mut [ <E as ExtensionField >:: BaseField ] ,
@@ -436,6 +522,83 @@ impl WriteMEM {
436522 }
437523}
438524
525+ #[ derive( Debug ) ]
526+ pub struct RWMEM {
527+ pub prev_ts : WitIn ,
528+ pub lt_cfg : AssertLtConfig ,
529+ }
530+
531+ impl RWMEM {
532+ pub fn construct_circuit < E : ExtensionField > (
533+ circuit_builder : & mut CircuitBuilder < E > ,
534+ is_read : Expression < E > ,
535+ mem_addr : AddressExpr < E > ,
536+ prev_value : MemoryExpr < E > ,
537+ new_value : MemoryExpr < E > ,
538+ cur_ts : WitIn ,
539+ ) -> Result < Self , ZKVMError > {
540+ let prev_ts = circuit_builder. create_witin ( || "prev_ts" ) ;
541+
542+ let ( _, lt_cfg) = circuit_builder. memory_write (
543+ || "write_memory" ,
544+ & mem_addr,
545+ prev_ts. expr ( ) ,
546+ cur_ts. expr ( ) + Tracer :: SUBCYCLE_MEM ,
547+ prev_value. clone ( ) ,
548+ array:: from_fn ( |i| {
549+ is_read. expr ( ) * prev_value[ i] . expr ( )
550+ + ( Expression :: ONE - is_read. expr ( ) ) * new_value[ i] . expr ( )
551+ } ) ,
552+ ) ?;
553+
554+ Ok ( RWMEM { prev_ts, lt_cfg } )
555+ }
556+
557+ pub fn assign_instance < E : ExtensionField > (
558+ & self ,
559+ instance : & mut [ <E as ExtensionField >:: BaseField ] ,
560+ shard_ctx : & mut ShardContext ,
561+ lk_multiplicity : & mut LkMultiplicity ,
562+ step : & StepRecord ,
563+ ) -> Result < ( ) , ZKVMError > {
564+ let op = step. memory_op ( ) . unwrap ( ) ;
565+ self . assign_op ( instance, shard_ctx, lk_multiplicity, step. cycle ( ) , & op)
566+ }
567+
568+ pub fn assign_op < F : SmallField > (
569+ & self ,
570+ instance : & mut [ F ] ,
571+ shard_ctx : & mut ShardContext ,
572+ lk_multiplicity : & mut LkMultiplicity ,
573+ cycle : Cycle ,
574+ op : & WriteOp ,
575+ ) -> Result < ( ) , ZKVMError > {
576+ let shard_prev_cycle = shard_ctx. aligned_prev_ts ( op. previous_cycle ) ;
577+ let current_shard_offset_cycle = shard_ctx. current_shard_offset_cycle ( ) ;
578+ let shard_cycle = cycle - current_shard_offset_cycle;
579+ set_val ! ( instance, self . prev_ts, shard_prev_cycle) ;
580+
581+ self . lt_cfg . assign_instance (
582+ instance,
583+ lk_multiplicity,
584+ shard_prev_cycle,
585+ shard_cycle + Tracer :: SUBCYCLE_MEM ,
586+ ) ?;
587+
588+ shard_ctx. send (
589+ RAMType :: Memory ,
590+ op. addr ,
591+ op. addr . baddr ( ) . 0 as u64 ,
592+ cycle + Tracer :: SUBCYCLE_MEM ,
593+ op. previous_cycle ,
594+ op. value . after ,
595+ Some ( op. value . before ) ,
596+ ) ;
597+
598+ Ok ( ( ) )
599+ }
600+ }
601+
439602#[ derive( Debug ) ]
440603pub struct MemAddr < E : ExtensionField > {
441604 addr : UInt < E > ,
0 commit comments