87 lines
2.2 KiB
Rust
87 lines
2.2 KiB
Rust
use crate::rtlil::{RtlilWrite, SigSpec};
|
|
|
|
#[derive(Debug)]
|
|
pub struct Process {
|
|
pub id: String,
|
|
pub root_case: CaseRule,
|
|
pub sync_rules: Vec<SyncRule>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct CaseRule {
|
|
pub assign: Vec<(SigSpec, SigSpec)>,
|
|
pub switches: Vec<SwitchRule>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct SwitchRule {
|
|
pub signal: SigSpec,
|
|
pub cases: Vec<(SigSpec, CaseRule)>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct SyncRule {
|
|
pub cond: SyncCond,
|
|
pub assign: Vec<(SigSpec, SigSpec)>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum SyncCond {
|
|
Always,
|
|
Init,
|
|
Posedge(String),
|
|
Negedge(String),
|
|
}
|
|
|
|
impl RtlilWrite for Process {
|
|
fn write_rtlil(&self, writer: &mut super::ILWriter) {
|
|
writer.write_line(&format!("process {}", self.id));
|
|
writer.indent();
|
|
self.root_case.write_rtlil(writer);
|
|
writer.write_iter(&self.sync_rules);
|
|
writer.dedent();
|
|
writer.write_line("end");
|
|
}
|
|
}
|
|
|
|
impl RtlilWrite for CaseRule {
|
|
fn write_rtlil(&self, writer: &mut super::ILWriter) {
|
|
for assign in &self.assign {
|
|
writer.write_line(&format!("assign {} {}", assign.0, assign.1));
|
|
}
|
|
writer.write_iter(&self.switches);
|
|
}
|
|
}
|
|
|
|
impl RtlilWrite for SwitchRule {
|
|
fn write_rtlil(&self, writer: &mut super::ILWriter) {
|
|
writer.write_line(&format!("switch {}", self.signal));
|
|
writer.indent();
|
|
for case in &self.cases {
|
|
writer.write_line(&format!("case {}", case.0));
|
|
writer.indent();
|
|
case.1.write_rtlil(writer);
|
|
writer.dedent();
|
|
}
|
|
writer.dedent();
|
|
}
|
|
}
|
|
|
|
impl RtlilWrite for SyncRule {
|
|
fn write_rtlil(&self, writer: &mut super::ILWriter) {
|
|
let sync_expr = match &self.cond {
|
|
SyncCond::Always => "always".to_owned(),
|
|
SyncCond::Init => "always".to_owned(),
|
|
SyncCond::Posedge(sig) => format!("posedge {}", sig),
|
|
SyncCond::Negedge(sig) => format!("negedge {}", sig),
|
|
};
|
|
writer.write_line(&format!("sync {}", sync_expr));
|
|
writer.indent();
|
|
|
|
for update in &self.assign {
|
|
writer.write_line(&format!("update {} {}", update.0, update.1));
|
|
}
|
|
writer.dedent();
|
|
}
|
|
}
|