Skip to content

Commit d4d503a

Browse files
authored
feat: exec opcode spec table (#13594)
This adds some foundational stuff for the execution instruction specfication table and a basic use-case within the execution loop. ### Trace Changes - A precomputed table for the exec instruction specs. - Register information in execution trace and supports up to 7 operands in addressing. ### Simulation - Adds the (temporary) `set_inputs` and `set_output` so that `TaggedValue` that are needed in the execution registers can be emitted as part of the ExecutionEvent. ### Tracegen - Added new tables `SUBTRACE_INFO_MAP` `REGISTER_INFO_MAP`, these contain information used in tracegen when placing values into their respective registers - Updated `ExecutionTraceBuilder::process` to properly handle placing the `inputs/outputs` from the execution event into respective registers. NOTE: Operands likely need the same treatment but this hasnt been done yet. ### Testing - There is a new `ExecutionConstrainingTest` that tests the basic decoding and allocation of registers for a simple `ADD`
1 parent cf637dc commit d4d503a

18 files changed

+482
-39
lines changed

barretenberg/cpp/pil/vm2/addressing.pil

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ pol commit sel_op1_is_address;
1313
pol commit sel_op2_is_address;
1414
pol commit sel_op3_is_address;
1515
pol commit sel_op4_is_address;
16+
pol commit sel_op5_is_address;
17+
pol commit sel_op6_is_address;
18+
pol commit sel_op7_is_address;
1619
// operands after relative resolution
1720
pol commit op1_after_relative;
1821
pol commit op2_after_relative;
1922
pol commit op3_after_relative;
2023
pol commit op4_after_relative;
24+
pol commit op5_after_relative;
25+
pol commit op6_after_relative;
26+
pol commit op7_after_relative;
2127
// operands after indirect resolution are the resolved_operands rop1, ...

barretenberg/cpp/pil/vm2/execution.pil

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,39 @@ include "nullifier_check.pil";
2828
namespace execution;
2929

3030
pol commit sel; // subtrace selector
31+
// Subtrace operation id
32+
pol commit subtrace_operation_id;
33+
34+
// Subtrace Dispatch selectors
35+
// These boolean selectors are constrained via the precomputed Execution Instruction Spec Table
36+
pol commit sel_alu;
37+
pol commit sel_bitwise;
38+
pol commit sel_to_radix;
39+
pol commit sel_ecc_add;
40+
pol commit sel_poseidon2_perm;
3141

3242
pol commit ex_opcode;
3343
pol commit indirect;
3444
// operands
3545
pol commit op1, op2, op3, op4;
46+
pol commit op5, op6, op7;
3647
// resolved operands
3748
pol commit rop1, rop2, rop3, rop4;
49+
pol commit rop5, rop6, rop7;
50+
// Registers
51+
pol commit reg1, reg2, reg3, reg4;
52+
pol commit reg5, reg6, reg7;
53+
// Memory Acccesses
54+
pol commit mem_op1, mem_op2, mem_op3, mem_op4;
55+
pol commit mem_op5, mem_op6, mem_op7;
56+
// Memory Tag
57+
pol commit mem_tag1, mem_tag2, mem_tag3, mem_tag4;
58+
pol commit mem_tag5, mem_tag6, mem_tag7;
59+
// Read / Write selectors
60+
pol commit rw1, rw2, rw3, rw4;
61+
pol commit rw5, rw6, rw7;
3862

3963
pol commit bytecode_id;
40-
pol commit clk;
4164
pol commit last;
4265

4366
// Selector constraints

barretenberg/cpp/pil/vm2/precomputed.pil

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,30 @@ pol constant sel_p_decomposition;
9595
pol constant p_decomposition_radix;
9696
pol constant p_decomposition_limb_index;
9797
pol constant p_decomposition_limb;
98+
99+
// EXECUTION INSTRUCTION SPEC table
100+
// Maps an execution opcode value to useful information used during execution
101+
// - Gas Costs
102+
// - Opcode memory operations and destination registers
103+
pol constant exec_opcode_value; // Would be nice to re-use exec_opcode but that has duplicate lines (i.e. ADD_8 & ADD_16 map to ADD)
104+
pol constant exec_opcode_base_l2_gas;
105+
pol constant exec_opcode_base_da_gas;
106+
pol constant exec_opcode_dynamic_l2_gas;
107+
pol constant exec_opcode_dynamic_da_gas;
108+
// Memory Access + Register mappings
109+
pol constant mem_op_reg1, rw_1;
110+
pol constant mem_op_reg2, rw_2;
111+
pol constant mem_op_reg3, rw_3;
112+
pol constant mem_op_reg4, rw_4;
113+
pol constant mem_op_reg5, rw_5;
114+
pol constant mem_op_reg6, rw_6;
115+
pol constant mem_op_reg7, rw_7;
116+
// Subtrace/Gadget Selector
117+
pol constant sel_dispatch_alu;
118+
pol constant sel_dispatch_bitwise;
119+
pol constant sel_dispatch_poseidon_perm;
120+
pol constant sel_dispatch_to_radix;
121+
pol constant sel_dispatch_ecc;
122+
// Add more here
123+
pol constant subtrace_operation_id;
124+

barretenberg/cpp/src/barretenberg/vm2/common/tagged_value.hpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@
66
#include <variant>
77

88
#include "barretenberg/numeric/uint128/uint128.hpp"
9+
#include "barretenberg/vm2/common/aztec_constants.hpp"
910
#include "barretenberg/vm2/common/field.hpp"
1011
#include "barretenberg/vm2/common/uint1.hpp"
1112

1213
namespace bb::avm2 {
1314

1415
enum class ValueTag {
15-
FF,
16-
U1,
17-
U8,
18-
U16,
19-
U32,
20-
U64,
21-
U128,
16+
FF = MEM_TAG_FF,
17+
U1 = MEM_TAG_U1,
18+
U8 = MEM_TAG_U8,
19+
U16 = MEM_TAG_U16,
20+
U32 = MEM_TAG_U32,
21+
U64 = MEM_TAG_U64,
22+
U128 = MEM_TAG_U128,
2223
MAX = U128,
2324
};
2425

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/execution.test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ TEST(ExecutionConstrainingTest, Basic)
2121
{
2222
// clang-format off
2323
TestTraceContainer trace({
24-
{{ C::execution_sel, 1 }, {C::execution_clk, 0}, { C::execution_pc, 0 }},
25-
{{ C::execution_sel, 1 }, {C::execution_clk, 1}, { C::execution_pc, 20 }, { C::execution_last, 1 }}
24+
{{ C::execution_sel, 1 }, { C::execution_pc, 0 }},
25+
{{ C::execution_sel, 1 }, { C::execution_pc, 20 }, { C::execution_last, 1 }}
2626
});
2727
// clang-format on
2828

barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@
5050
namespace bb::avm2 {
5151

5252
struct AvmFlavorVariables {
53-
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 45;
54-
static constexpr size_t NUM_WITNESS_ENTITIES = 2026;
53+
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 70;
54+
static constexpr size_t NUM_WITNESS_ENTITIES = 2071;
5555
static constexpr size_t NUM_SHIFTED_ENTITIES = 135;
5656
static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES;
57-
static constexpr size_t NUM_ALL_ENTITIES = 2206;
57+
static constexpr size_t NUM_ALL_ENTITIES = 2276;
5858

5959
// Need to be templated for recursive verifier
6060
template <typename FF_>

barretenberg/cpp/src/barretenberg/vm2/simulation/events/execution_event.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "barretenberg/vm2/common/aztec_types.hpp"
77
#include "barretenberg/vm2/common/memory_types.hpp"
88
#include "barretenberg/vm2/common/opcodes.hpp"
9+
#include "barretenberg/vm2/common/tagged_value.hpp"
910
#include "barretenberg/vm2/simulation/events/addressing_event.hpp"
1011
#include "barretenberg/vm2/simulation/events/bytecode_events.hpp"
1112
#include "barretenberg/vm2/simulation/events/context_events.hpp"
@@ -22,6 +23,11 @@ struct ExecutionEvent {
2223
ExecutionOpCode opcode;
2324
std::vector<Operand> resolved_operands;
2425

26+
// Inputs and Outputs for a gadget/subtrace used when allocating registers in the execution trace.
27+
std::vector<TaggedValue> inputs;
28+
// todo(ilyas): this is a vector because GETCONTRACTINSTANCE has 2 outputs, we should change this to 1
29+
std::vector<TaggedValue> output;
30+
2531
// Sub-events.
2632
AddressingEvent addressing_event;
2733
ContextEvent context_event;

barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,27 @@ void Execution::add(ContextInterface& context, MemoryAddress a_addr, MemoryAddre
2020
MemoryValue b = memory.get(b_addr);
2121
MemoryValue c = alu.add(a, b);
2222
memory.set(dst_addr, c);
23+
24+
set_inputs({ a, b });
25+
set_outputs({ c });
2326
}
2427

2528
// TODO: My dispatch system makes me have a uint8_t tag. Rethink.
2629
void Execution::set(ContextInterface& context, MemoryAddress dst_addr, uint8_t tag, FF value)
2730
{
28-
context.get_memory().set(dst_addr, MemoryValue::from_tag(static_cast<ValueTag>(tag), value));
31+
TaggedValue tagged_value = TaggedValue::from_tag(static_cast<ValueTag>(tag), value);
32+
context.get_memory().set(dst_addr, tagged_value);
33+
set_outputs({ tagged_value });
2934
}
3035

3136
void Execution::mov(ContextInterface& context, MemoryAddress src_addr, MemoryAddress dst_addr)
3237
{
3338
auto& memory = context.get_memory();
3439
auto v = memory.get(src_addr);
3540
memory.set(dst_addr, v);
41+
42+
set_inputs({ v });
43+
set_outputs({ v });
3644
}
3745

3846
void Execution::call(ContextInterface& context, MemoryAddress addr, MemoryAddress cd_offset, MemoryAddress cd_size)
@@ -89,6 +97,8 @@ void Execution::jumpi(ContextInterface& context, MemoryAddress cond_addr, uint32
8997
if (!resolved_cond.as_ff().is_zero()) {
9098
context.set_next_pc(loc);
9199
}
100+
101+
set_inputs({ resolved_cond });
92102
}
93103

94104
// This context interface is an top-level enqueued one
@@ -135,6 +145,9 @@ ExecutionResult Execution::execute_internal(ContextInterface& context)
135145

136146
// Execute the opcode.
137147
dispatch_opcode(opcode, context, resolved_operands);
148+
// TODO: we set the inputs and outputs here and into the execution event, but maybe there's a better way
149+
ex_event.inputs = get_inputs();
150+
ex_event.output = get_outputs();
138151

139152
// Move on to the next pc.
140153
context.set_pc(context.get_next_pc());

barretenberg/cpp/src/barretenberg/vm2/simulation/execution.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "barretenberg/vm2/common/field.hpp"
1111
#include "barretenberg/vm2/common/memory_types.hpp"
1212
#include "barretenberg/vm2/common/opcodes.hpp"
13+
#include "barretenberg/vm2/common/tagged_value.hpp"
1314
#include "barretenberg/vm2/simulation/addressing.hpp"
1415
#include "barretenberg/vm2/simulation/alu.hpp"
1516
#include "barretenberg/vm2/simulation/context.hpp"
@@ -66,6 +67,13 @@ class Execution : public ExecutionInterface {
6667
void call(ContextInterface& context, MemoryAddress addr, MemoryAddress cd_offset, MemoryAddress cd_size);
6768
void ret(ContextInterface& context, MemoryAddress ret_offset, MemoryAddress ret_size_offset);
6869

70+
// TODO(#13683): This is leaking circuit implementation details. We should have a better way to do this.
71+
// Setters for inputs and outputs for gadgets/subtraces. These are used for register allocation.
72+
void set_inputs(std::vector<TaggedValue> inputs) { this->inputs = std::move(inputs); }
73+
void set_outputs(std::vector<TaggedValue> outputs) { this->outputs = std::move(outputs); }
74+
const std::vector<TaggedValue>& get_inputs() const { return inputs; }
75+
const std::vector<TaggedValue>& get_outputs() const { return outputs; }
76+
6977
private:
7078
void set_execution_result(ExecutionResult exec_result) { this->exec_result = exec_result; }
7179
ExecutionResult get_execution_result() const { return exec_result; }
@@ -89,6 +97,9 @@ class Execution : public ExecutionInterface {
8997
EventEmitterInterface<ContextStackEvent>& ctx_stack_events;
9098

9199
ExecutionResult exec_result;
100+
101+
std::vector<TaggedValue> inputs;
102+
std::vector<TaggedValue> outputs;
92103
};
93104

94105
} // namespace bb::avm2::simulation

barretenberg/cpp/src/barretenberg/vm2/simulation/execution.test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ TEST_F(ExecutionSimulationTest, Add)
5858

5959
TEST_F(ExecutionSimulationTest, Call)
6060
{
61-
6261
AztecAddress parent_address = 1;
6362
AztecAddress nested_address = 2;
6463
MemoryValue nested_address_value = MemoryValue::from<FF>(nested_address);

0 commit comments

Comments
 (0)