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

Pattern internals #30

Closed
wants to merge 12 commits into from
7 changes: 7 additions & 0 deletions rust/origen/Cargo.lock

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

1 change: 1 addition & 0 deletions rust/origen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ serde = {version = "1.0", features = ["derive"]}
path-clean = "0.1.0"
time = "0.1.42"
pyo3 = "^0.8"
id-arena = "2.2.1"

[build-dependencies]
built = "0.3"
1 change: 1 addition & 0 deletions rust/origen/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ pub mod os;
pub mod status;
pub mod term;
pub mod utility;
pub mod pattern;
29 changes: 29 additions & 0 deletions rust/origen/src/core/pattern/action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//! Defines the set of actions associated with pattern generation
// String is used for data to allow very large (ex. 300-bit) numbers
// Enum Structs will be defined for most action types to hold their associated info
//

use super::operation::Operation;
use super::pinaction::PinAction;

pub enum Action {
Pin(PinAction),
// Below this line are just test types for now
Timeset(String),
Cycle{repeat: u32},
// These are place holders of action types as I think of them
// Register{name: String, address: u32, data: u32, operation: Operation, start_stop: Operation},
// Driver{name: String, operation: Operation, data: u32, size: u32, target: String, start_stop: Operation},
// Comment(String),
// Instrument{name: String, data: String, operation: Operation},
}

impl Action {
pub fn to_string(&self) -> String {
match self {
Action::Pin(p) => format!("PinAction -> {}", p.to_string()),
Action::Timeset(s) => format!("Timeset -> {}", s.to_string()),
Action::Cycle{repeat: r} => format!("Cycle -> repeat: {}", r.to_string()),
}
}
}
59 changes: 59 additions & 0 deletions rust/origen/src/core/pattern/actions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! This file is now obsolete and will be deleted
//! Collects actions
pub use super::*;

pub struct Actions {
list: Vec<action::Action>
}

impl Actions {
pub fn new() -> Actions {
Actions {
list: Vec::new(),
}
}

pub fn push(& mut self, pa: action::Action) {
self.list.push(pa);
}

pub fn vec(&self) -> &Vec<action::Action> {
&self.list
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn actions_struct_loads_reads() {
let mut pattern_actions = Actions::new();
pattern_actions.push(action::Action::Timeset("tp0".to_string()));
pattern_actions.push(action::Action::Pin(pinaction::PinAction::new("pa0", "1", operation::Operation::Read)));
assert_eq!((pattern_actions.vec()[0]).to_string(), "Timeset -> tp0");
assert_eq!((pattern_actions.vec()[1]).to_string(), "PinAction -> pin: pa0, data: 1, operation: read");
}


// here is how the pattern actions would be consumed
#[test]
fn actions_can_be_consumed() {
// creating some actions
let mut pattern_actions = Actions::new();
pattern_actions.push(action::Action::Timeset("tp0".to_string()));
pattern_actions.push(action::Action::Cycle{repeat: 35});
pattern_actions.push(action::Action::Pin(pinaction::PinAction::new("pin1", "1", operation::Operation::Read)));
pattern_actions.push(action::Action::Pin(pinaction::PinAction::new("pin2", "0", operation::Operation::Read)));
pattern_actions.push(action::Action::Cycle{repeat: 2});

// consume the actions:
for op in pattern_actions.vec() {
match op {
action::Action::Pin(p) => println!("consuming stored pin action on {}", p.name.to_string()),
action::Action::Timeset(s) => println!("consuming timeset data for {}", s.to_string()),
action::Action::Cycle{repeat: r} => println!("consuming cycle action with repeat {}", r.to_string()),
}
}
}
}
18 changes: 18 additions & 0 deletions rust/origen/src/core/pattern/ast_node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use id_arena::{Arena, Id};
use super::operation::Operation;
use super::pinaction::PinAction;

type AstNodeId = Id<AstNode>;

#[derive(Debug, Eq, PartialEq)]
pub enum AstNode {
Pin(PinAction),

// Below this line are just test types for now
Timeset(String),
Cycle{repeat: u32},
Comment(String),
Instrument{name: String, data: String, operation: Operation},
Register{name: String, address: u64, data: String, operation: Operation, children: Operation},
// Driver{name: String, operation: Operation, data: u32, size: u32, target: String, start_stop: Operation},
}
6 changes: 6 additions & 0 deletions rust/origen/src/core/pattern/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod action;
pub mod operation;
pub mod pinaction;
pub mod actions;
pub mod ast_node;
pub mod register_action;
54 changes: 54 additions & 0 deletions rust/origen/src/core/pattern/operation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! Defines the set of operation types associated with pattern generation
// This enum will be used by all action types

// May need to be more of these and more precise names
// TODO: The operation/action type enum should come from the module that models the object (pins, regs, protocol, etc.)
#[derive(Debug, Eq, PartialEq)]
pub enum Operation {
Read,
Write,
Store,
Capture,
DriveMem,
ReadMem,
DriveFromSrc,
StoreToCap,
Start,
Stop,
}

impl Operation {
pub fn to_string(&self) -> String {
match self {
Operation::Read => "read".to_string(),
Operation::Write => "write".to_string(),
Operation::Store => "store".to_string(),
Operation::Capture => "capture".to_string(),
Operation::DriveMem => "drive_mem".to_string(),
Operation::ReadMem => "read_mem".to_string(),
Operation::DriveFromSrc => "drive_from_src".to_string(),
Operation::StoreToCap => "store_to_cap".to_string(),
Operation::Start => "start".to_string(),
Operation::Stop => "stop".to_string(),
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn converts_to_string() {
assert_eq!(Operation::Read.to_string(), "read");
assert_eq!(Operation::Write.to_string(), "write");
assert_eq!(Operation::Store.to_string(), "store");
assert_eq!(Operation::Capture.to_string(), "capture");
assert_eq!(Operation::DriveMem.to_string(), "drive_mem");
assert_eq!(Operation::ReadMem.to_string(), "read_mem");
assert_eq!(Operation::DriveFromSrc.to_string(), "drive_from_src");
assert_eq!(Operation::StoreToCap.to_string(), "store_to_cap");
assert_eq!(Operation::Start.to_string(), "start");
assert_eq!(Operation::Stop.to_string(), "stop");
}
}
52 changes: 52 additions & 0 deletions rust/origen/src/core/pattern/pinaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! Defines the set of actions associated with a pattern pin action
pub use super::operation::Operation;

#[derive(Debug, Eq, PartialEq)]
pub struct PinAction {
pub name: String,
pub data: String,
pub operation: Operation,
}

impl PinAction {
// This exists to add window dressing to the data string. Default expected will be hex.
// TODO: "0x" will be added if no format designator is present.
pub fn new(name: &str, data: &str, operation: Operation) -> PinAction {
PinAction {
name: name.to_string(),
data: data.to_string(),
operation: operation,
}
}

pub fn to_string(&self) -> String {
format!("pin: {}, data: {}, operation: {}", self.name, self.data, self.operation.to_string())
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn pinaction_readable() {
let pa = PinAction { name: "porta_01".to_string(), data: "0".to_string(), operation: Operation::Read, };
assert_eq!(pa.name, "porta_01");
assert_eq!(pa.data, "0");
assert_eq!(pa.operation.to_string(), "read");
}

#[test]
fn new_creates_struct() {
let pa = PinAction::new("pingroup_name", "0x55", Operation::DriveMem);
assert_eq!(pa.name, "pingroup_name");
assert_eq!(pa.data, "0x55");
assert_eq!(pa.operation.to_string(), Operation::DriveMem.to_string());
}

#[test]
fn converts_to_string() {
let pa = PinAction::new("pingroup_name", "0x55", Operation::DriveMem);
assert_eq!(pa.to_string(), "pin: pingroup_name, data: 0x55, operation: drive_mem");
}
}
50 changes: 50 additions & 0 deletions rust/origen/src/core/pattern/register_action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! Defines the set of actions associated with a register action
pub use super::operation::Operation;
use id_arena::Arena;
pub use super::ast_node::AstNode;

#[derive(Debug, Eq, PartialEq)]
pub struct RegisterAction {
pub name: String,
pub address: u64,
pub data: String,
pub operation: Operation,
// register action can contain arbitrary number of child actions
pub children: Arena::<AstNode>,
}

impl RegisterAction {
// This exists to add window dressing to the data string. Default expected will be hex.
// TODO: "0x" will be added if no format designator is present.
pub fn new(name: &str, address: &u64, data: &str, operation: Operation) -> RegisterAction {
RegisterAction {
name: name.to_string(),
address: *address,
data: data.to_string(),
operation: operation,
children: Arena::<AstNode>::new(),
}
}

pub fn to_string(&self) -> String {
format!("register: {}, address: {}, data: {}, operation: {}, num children: {}", self.name, self.address, self.data, self.operation.to_string(), self.children.len())
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn converts_to_string(){
let ra_node = RegisterAction::new("cntrl", &300, "0x40", Operation::Read);
assert_eq!(ra_node.to_string(), "register: cntrl, address: 300, data: 0x40, operation: read, num children: 0");
}

#[test]
fn instantiates_new_mutable_arena() {
let mut ra_node = RegisterAction::new("cntrl", &300, "0x40", Operation::Read);
ra_node.children.alloc(AstNode::Timeset("tp0".to_string()));
assert_eq!(ra_node.children.len(), 1);
}
}