Skip to content

Commit

Permalink
Add StoreU8.
Browse files Browse the repository at this point in the history
  • Loading branch information
thealmarty committed Apr 15, 2024
1 parent afce235 commit 44b2438
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 2 deletions.
83 changes: 83 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions assembler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ pub fn assemble(input: &str) -> Result<Vec<u8>, String> {
let opcode = match mnemonic {
// Core CPU
"lw" => LOAD32,
"loadu8" => LOADU8,
"loads8" => LOADS8,
"sw" => STORE32,
"storeu8" => STOREU8,
"jal" => JAL,
"jalv" => JALV,
"beq" | "beqi" => BEQ,
Expand Down
11 changes: 9 additions & 2 deletions basic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ use valida_bus::{
};
use valida_cpu::{
BeqInstruction, BneInstruction, Imm32Instruction, JalInstruction, JalvInstruction,
Load32Instruction, LoadFpInstruction, ReadAdviceInstruction, StopInstruction,
Store32Instruction,
Load32Instruction, LoadU8Instruction, LoadS8Instruction, LoadFpInstruction, ReadAdviceInstruction, StopInstruction,
Store32Instruction, StoreU8Instruction
};
use valida_cpu::{CpuChip, MachineWithCpuChip};
use valida_machine::__internal::p3_challenger::{CanObserve, FieldChallenger};
Expand All @@ -64,6 +64,13 @@ pub struct BasicMachine<F: PrimeField32 + TwoAdicField> {
// Core instructions
load32: Load32Instruction,
store32: Store32Instruction,

loadu8: LoadU8Instruction,

loads8: LoadS8Instruction,

storeu8: StoreU8Instruction,

jal: JalInstruction,
jalv: JalvInstruction,
beq: BeqInstruction,
Expand Down
3 changes: 3 additions & 0 deletions cpu/src/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ pub struct OpcodeFlagCols<T> {
pub is_bus_op_with_mem: T,
pub is_imm_op: T,
pub is_load: T,
pub is_load_u8: T,
pub is_load_s8: T,
pub is_store: T,
pub is_store_u8: T,
pub is_beq: T,
pub is_bne: T,
pub is_jal: T,
Expand Down
66 changes: 66 additions & 0 deletions cpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use valida_machine::{
use valida_memory::{MachineWithMemoryChip, Operation as MemoryOperation};
use valida_opcodes::{
BEQ, BNE, BYTES_PER_INSTR, IMM32, JAL, JALV, LOAD32, LOADFP, READ_ADVICE, STOP, STORE32,
LOADU8, LOADS8, STOREU8
};

use p3_air::VirtualPairCol;
Expand All @@ -31,7 +32,10 @@ pub mod stark;
#[derive(Clone)]
pub enum Operation {
Store32,
StoreU8,
Load32,
LoadU8,
LoadS8,
Jal,
Jalv,
Beq(Option<Word<u8>> /*imm*/),
Expand Down Expand Up @@ -175,6 +179,15 @@ impl CpuChip {
Operation::Load32 => {
cols.opcode_flags.is_load = SC::Val::one();
}
Operation::StoreU8 => {
cols.opcode_flags.is_store_u8 = SC::Val::one();
}
Operation::LoadU8 => {
cols.opcode_flags.is_load_u8 = SC::Val::one();
}
Operation::LoadS8 => {
cols.opcode_flags.is_load_s8 = SC::Val::one();
}
Operation::Jal => {
cols.opcode_flags.is_jal = SC::Val::one();
}
Expand Down Expand Up @@ -349,7 +362,10 @@ pub trait MachineWithCpuChip<F: Field>: MachineWithMemoryChip<F> {

instructions!(
Load32Instruction,
LoadU8Instruction,
LoadS8Instruction,
Store32Instruction,
StoreU8Instruction,
JalInstruction,
JalvInstruction,
BeqInstruction,
Expand Down Expand Up @@ -466,6 +482,56 @@ where
}
}

fn index_of_word(addr: u32) -> usize {
return ((addr & !3) - 1) as usize;
}

impl<M, F> Instruction<M, F> for StoreU8Instruction
where
M: MachineWithCpuChip<F>,
F: Field,
{
const OPCODE: u32 = STOREU8;

fn execute(state: &mut M, ops: Operands<i32>) {
let opcode = <Self as Instruction<M, F>>::OPCODE;
let clk = state.cpu().clock;
let read_addr = (state.cpu().fp as i32 + ops.c()) as u32;
let write_addr_loc = (state.cpu().fp as i32 + ops.b()) as u32;
let pc = state.cpu().pc;
let write_addr = state
.mem_mut()
.read(clk, write_addr_loc.into(), true, pc, opcode, 0, "");

// Read the cell from the read address.
let cell = state
.mem_mut()
.read(clk, read_addr, true, pc, opcode, 1, "");

// index of the word for the byte to read from
let index_of_read = index_of_word(read_addr);

// The byte read from the read address.
let cell_read = cell.0;
let cell_byte = cell_read[index_of_read];

// Index of the word for the byte to write to
let index_of_write = index_of_word(write_addr.into());

// The original content of the cell to write to.
let cell_write = state
.mem_mut()
.read(clk, write_addr.into(), true, pc, opcode, 1, "");

// The Word to write, with one byte overwritten to the read byte
let cell_to_write = cell_write.update_byte(cell_byte, index_of_write);

state.mem_mut().write(clk, write_addr.into(), cell_to_write, true);
state.cpu_mut().pc += 1;
state.cpu_mut().push_op(Operation::StoreU8, opcode, ops);
}
}

impl<M, F> Instruction<M, F> for JalInstruction
where
M: MachineWithCpuChip<F>,
Expand Down
18 changes: 18 additions & 0 deletions machine/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ impl Word<u8> {
}
}

impl Word<u8> {
pub fn update_byte(self, byte: u8, loc: usize) -> Self {
let mut result: [u8; MEMORY_CELL_BYTES] = self.0;
result[MEMORY_CELL_BYTES - loc] = byte;
Self(result)
}
}


impl<F: Copy> Word<F> {
pub fn transform<T, G>(self, mut f: G) -> Word<T>
where
Expand All @@ -39,6 +48,15 @@ impl<F: PrimeField> Word<F> {
}
}

impl Word<u8> {
pub fn to_u8(self) -> u8 {
let result = self.0;
let byte = result[MEMORY_CELL_BYTES - 1];
byte
}
}


impl Into<u32> for Word<u8> {
fn into(self) -> u32 {
let mut result = 0u32;
Expand Down
12 changes: 12 additions & 0 deletions memory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ impl MemoryChip {
self.cells.insert(address, value.into());
}

/// Write a byte value to the least significant byte, and write zeros to the other 3 bytes.
pub fn write_u8(&mut self, clk: u32, address: u32, value: u8, log: bool) {
let value_word = Word::from_u8(value);
if log {
self.operations
.entry(clk)
.or_insert_with(Vec::new)
.push(Operation::Write(address, value_word));
}
self.cells.insert(address, value_word);
}

pub fn write_static(&mut self, address: u32, value: Word<u8>) {
self.cells.insert(address, value.clone());
self.static_data.insert(address, value);
Expand Down
7 changes: 7 additions & 0 deletions opcodes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ pub enum Opcode {
STOP = 8,
READ_ADVICE = 9,
LOADFP = 10,
LOADU8 = 11,
LOADS8 = 12,
STOREU8 = 13,

ADD32 = 100,
SUB32 = 101,
MUL32 = 102,
Expand Down Expand Up @@ -56,6 +60,9 @@ declare_opcode!(BNE);
declare_opcode!(IMM32);
declare_opcode!(STOP);
declare_opcode!(LOADFP);
declare_opcode!(LOADU8);
declare_opcode!(LOADS8);
declare_opcode!(STOREU8);

/// NONDETERMINISTIC
declare_opcode!(READ_ADVICE);
Expand Down

0 comments on commit 44b2438

Please sign in to comment.