futilehdl/src/rtlil/sync.rs

88 lines
2.2 KiB
Rust
Raw Permalink Normal View History

2022-01-16 19:13:04 +00:00
use crate::rtlil::{RtlilWrite, SigSpec};
2022-01-16 18:11:56 +00:00
2022-01-16 20:46:44 +00:00
#[derive(Debug)]
2022-01-16 18:11:56 +00:00
pub struct Process {
2022-01-17 00:15:27 +00:00
pub id: String,
pub root_case: CaseRule,
pub sync_rules: Vec<SyncRule>,
2022-01-16 18:11:56 +00:00
}
2022-01-16 20:46:44 +00:00
#[derive(Debug)]
2022-01-16 18:11:56 +00:00
pub struct CaseRule {
2022-01-17 00:15:27 +00:00
pub assign: Vec<(SigSpec, SigSpec)>,
pub switches: Vec<SwitchRule>,
2022-01-16 18:11:56 +00:00
}
2022-01-16 20:46:44 +00:00
#[derive(Debug)]
2022-01-16 18:11:56 +00:00
pub struct SwitchRule {
pub signal: SigSpec,
pub cases: Vec<(SigSpec, CaseRule)>,
2022-01-16 18:11:56 +00:00
}
2022-01-16 20:46:44 +00:00
#[derive(Debug)]
2022-01-16 18:11:56 +00:00
pub struct SyncRule {
2022-01-17 00:15:27 +00:00
pub cond: SyncCond,
pub assign: Vec<(SigSpec, SigSpec)>,
2022-01-16 18:11:56 +00:00
}
2022-01-16 20:46:44 +00:00
#[derive(Debug)]
2022-01-16 18:11:56 +00:00
pub enum SyncCond {
Always,
Init,
2022-01-17 23:11:37 +00:00
Posedge(SigSpec),
Negedge(SigSpec),
2022-01-16 18:11:56 +00:00
}
impl RtlilWrite for Process {
fn write_rtlil(&self, writer: &mut super::ILWriter) {
writer.write_line(&format!("process {}", self.id));
2022-01-17 00:15:27 +00:00
writer.indent();
2022-01-16 18:11:56 +00:00
self.root_case.write_rtlil(writer);
writer.write_iter(&self.sync_rules);
2022-01-17 00:15:27 +00:00
writer.dedent();
writer.write_line("end");
2022-01-16 18:11:56 +00:00
}
}
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();
}
2022-01-16 18:11:56 +00:00
writer.dedent();
2022-01-17 23:11:37 +00:00
writer.write_line("end");
2022-01-16 18:11:56 +00:00
}
}
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(),
2022-01-16 18:11:56 +00:00
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();
}
}