Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poseidon - update with new release #10

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion configs/c1100_cfg.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
"ctrl_dfx_decoupler_baseaddr": "0x04090000",
"dma_baseaddr": "0x0000000000000000",
"dma_hbicap_baseaddr": "0x1000000000000000"
}
}
39 changes: 36 additions & 3 deletions src/driver_client/dclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use crate::{
driver_client::dclient_code::*,
error::*,
utils::{deserialize_hex, open_channel, AccessFlags},
utils::{deserialize_hex, open_channel, AccessFlags}, ingo_hash::dma_buffer::DmaBuffer,
};
use serde::Deserialize;
use std::{fmt::Debug, os::unix::fs::FileExt, thread::sleep, time::Duration};
Expand All @@ -26,7 +26,7 @@ pub trait ParametersAPI {
/// The generic type parameters `T`, `P`, `I`, and `O` represent
/// the primitive type, parameter for initialization, input data, and output data respectively.
/// All methods return a `Result` indicating success or failure.
pub trait DriverPrimitive<T, P, I, O> {
pub trait DriverPrimitive<T, P, I, O, R> {
/// The `new` method creates a new instance of the driver primitive type with the given primitive type and driver client.
fn new(ptype: T, dclient: DriverClient) -> Self;
/// The `loaded_binary_parameters` method returns
Expand All @@ -43,7 +43,7 @@ pub trait DriverPrimitive<T, P, I, O> {
fn wait_result(&self) -> Result<()>;
/// The `result` method returns the output data from the driver primitive,
/// optionally with a specific parameter. If there is no output data available, it returns `None`.
fn result(&self, _param: Option<usize>) -> Result<Option<O>>;
fn result(&self, _param: Option<R>) -> Result<Option<O>>;
}

/// The [`DriverConfig`] is a struct that defines a set of 64-bit unsigned integer (`u64`)
Expand Down Expand Up @@ -173,6 +173,16 @@ impl DriverClient {
Ok(())
}

pub fn monitor_temperature(&self) -> Result<(u32, u32, u32)> {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + 0x028000;
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved

let temp_max = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::TEMP_MAX).unwrap();
let temp_avg = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::TEMP_AVG).unwrap();
let temp_inst = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::TEMP_INST).unwrap();

Ok((temp_inst, temp_avg, temp_max))
}

// HBICAP
/// Checking HBICAP status register. Return `true` if zero (previous operation done) and
/// second (Indicates that the EOS is complete) bit setting to 1.
Expand Down Expand Up @@ -290,6 +300,12 @@ impl DriverClient {
}
}

pub fn set_dma_firewall_prescale(&self, pre_scale: i32) -> Result<()> {
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved
self.ctrl_write(self.cfg.dma_firewall_baseaddr, 0x230 as u64, &pre_scale.to_le_bytes())?;
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}

pub fn unblock_firewalls(&self) -> Result<()> {
self.set_firewall_block(self.cfg.ctrl_firewall_baseaddr, false)?;
self.set_firewall_block(self.cfg.dma_firewall_baseaddr, false)?;
Expand Down Expand Up @@ -495,6 +511,23 @@ impl DriverClient {
Ok(read_data)
}

pub fn dma_read_into<T: Debug + Into<u64> + Copy>(
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved
&self,
base_address: u64,
offset: T,
// todo: add optional size
buffer: &mut DmaBuffer,
) {
self.dma_c2h_read
.read_exact_at(buffer.as_mut_slice(), base_address + offset.into())
.map_err(|e| DriverClientError::ReadError {
offset: format!("{:?}", offset),
source: e,
});

crate::getter_log!(buffer, offset);
}

/// The method for writing data from host memory into FPGA.
///
/// The location is determined by adding the `offset` to the `base_address`.
Expand Down
3 changes: 3 additions & 0 deletions src/driver_client/dclient_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ impl From<FIREWALL_ADDR> for u64 {
pub enum CMS_ADDR {
ADDR_CPU2HIF_CMS_INITIALIZE = 0x020000,
ADDR_HIF2CPU_CMS_CONTROL_REG = 0x0018,
TEMP_MAX = 0x00F8,
TEMP_AVG = 0x00FC,
TEMP_INST = 0x0100,
}
impl From<CMS_ADDR> for u64 {
fn from(addr: CMS_ADDR) -> Self {
Expand Down
55 changes: 55 additions & 0 deletions src/ingo_hash/dma_buffer.rs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this file be moved to the driver_client folder since it more specific to the HW integration than the primitive itself?

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use std::mem;

#[repr(C, align(4096))]
pub struct Align4K([u8; 4096]);

#[derive(Debug)]
pub struct DmaBuffer(Vec<u8>);

impl DmaBuffer {
pub fn new<T>(n_bytes: usize) -> Self {
Self(unsafe { aligned_vec::<T>(n_bytes) })
}

pub fn extend_from_slice(&mut self, slice: &[u8]) {
self.0.extend_from_slice(slice);
}

pub fn as_slice(&self) -> &[u8] {
self.0.as_slice()
}

pub fn as_mut_slice(&mut self) -> &mut [u8] {
self.0.as_mut_slice()
}

pub fn get(&self) -> &Vec<u8> {
&self.0
}

pub fn get_mut(&mut self) -> &mut Vec<u8> {
&mut self.0
}

pub fn len(&self) -> usize {
self.0.len()
}
}

pub unsafe fn aligned_vec<T>(n_bytes: usize) -> Vec<u8> {
let n_units = (n_bytes / mem::size_of::<T>()) + 1;

let mut aligned: Vec<T> = Vec::with_capacity(n_units);
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved

let ptr = aligned.as_mut_ptr();
let len_units = aligned.len();
let cap_units = aligned.capacity();

mem::forget(aligned);

Vec::from_raw_parts(
ptr as *mut u8,
len_units * mem::size_of::<T>(),
cap_units * mem::size_of::<T>(),
)
}
1 change: 1 addition & 0 deletions src/ingo_hash/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod hash_hw_code;
pub mod poseidon_api;
pub mod utils;
pub mod dma_buffer;
35 changes: 19 additions & 16 deletions src/ingo_hash/poseidon_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use crate::{
use csv;
use num::{bigint::BigUint, Num};

use super::dma_buffer::DmaBuffer;

pub enum Hash {
Poseidon,
}
Expand All @@ -31,6 +33,11 @@ pub struct PoseidonResult {
pub layer_id: u32,
}

pub struct PoseidonReadResult<'a> {
pub expected_result: usize,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the size of the result and not the actual expected result?

pub result_store_buffer: &'a mut DmaBuffer,
}

impl PoseidonResult {
/// The function parses poseidon hash result
///
Expand Down Expand Up @@ -73,7 +80,7 @@ impl PoseidonResult {
}
}

impl DriverPrimitive<Hash, PoseidonInitializeParameters, &[u8], Vec<PoseidonResult>>
impl DriverPrimitive<Hash, PoseidonInitializeParameters, &[u8], Vec<PoseidonResult>, PoseidonReadResult<'_>>
for PoseidonClient
{
fn new(_ptype: Hash, dclient: DriverClient) -> Self {
Expand Down Expand Up @@ -116,6 +123,9 @@ impl DriverPrimitive<Hash, PoseidonInitializeParameters, &[u8], Vec<PoseidonResu
self.set_merkle_tree_height(param.tree_height)?;
self.set_tree_start_layer_for_tree(param.tree_mode)?;
log::debug!("set merkle tree height: {:?}", param.tree_height);

self.dclient.initialize_cms()?;
self.dclient.set_dma_firewall_prescale(0xFFFF)?;
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}

Expand All @@ -130,22 +140,15 @@ impl DriverPrimitive<Hash, PoseidonInitializeParameters, &[u8], Vec<PoseidonResu
todo!()
}

fn result(&self, expected_result: Option<usize>) -> Result<Option<Vec<PoseidonResult>>> {
let mut results: Vec<PoseidonResult> = vec![];

loop {
let num_of_pending_results = self.get_num_of_pending_results()?;

if results.len() >= expected_result.unwrap() {
break;
}

let res = self.get_raw_results(num_of_pending_results)?;

let mut result = PoseidonResult::parse_poseidon_hash_results(res);
results.append(&mut result);
}
fn result(&self, _param: Option<PoseidonReadResult>) -> Result<Option<Vec<PoseidonResult>>> {
let params = _param.unwrap();

self.dclient.dma_read_into(self.dclient.cfg.dma_baseaddr, DMA_RW::OFFSET, params.result_store_buffer);

assert_eq!(params.result_store_buffer.len(), params.expected_result * 64);

let results = PoseidonResult::parse_poseidon_hash_results(params.result_store_buffer.get().to_vec());

Ok(Some(results))
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ingo_msm/msm_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub struct MSMResult {
pub result_label: u32,
}

impl DriverPrimitive<MSMInit, MSMParams, MSMInput, MSMResult> for MSMClient {
impl DriverPrimitive<MSMInit, MSMParams, MSMInput, MSMResult, usize> for MSMClient {
/// Creates a new [`MSMClient`].
fn new(init: MSMInit, dclient: DriverClient) -> Self {
MSMClient {
Expand Down
Loading