add rtlil processes

This commit is contained in:
NotAFile 2022-01-16 19:11:56 +01:00
parent b9eb6222de
commit a6b8429ed0
3 changed files with 104 additions and 18 deletions

View File

@ -3,6 +3,7 @@ use std::collections::BTreeMap;
use crate::builtin_cells::get_builtins;
use crate::parser;
use crate::rtlil;
use crate::rtlil::RtlilWrite;
fn make_pubid(id: &str) -> String {
"\\".to_owned() + id

View File

@ -1,3 +1,5 @@
mod sync;
#[derive(Debug, Default)]
pub struct ILWriter {
data: String,
@ -17,6 +19,13 @@ impl ILWriter {
self.data += "\n";
}
// TODO: make this actually take an iterator
pub fn write_iter(&mut self, iter: &[impl RtlilWrite]) {
for item in iter {
item.write_rtlil(self)
}
}
pub fn indent(&mut self) {
self.indent += 1
}
@ -33,11 +42,8 @@ impl ILWriter {
}
}
// the proper way
#[derive(Debug)]
pub enum PortOption {
Input(i32),
Output(i32),
pub trait RtlilWrite {
fn write_rtlil(&self, writer: &mut ILWriter);
}
#[derive(Debug)]
@ -50,6 +56,12 @@ pub struct Wire {
port_info: Option<PortOption>,
}
#[derive(Debug)]
pub enum PortOption {
Input(i32),
Output(i32),
}
impl Wire {
pub fn new(id: impl Into<String>, width: u32, port_info: Option<PortOption>) -> Self {
Self {
@ -58,7 +70,9 @@ impl Wire {
port_info,
}
}
}
impl RtlilWrite for Wire {
fn write_rtlil(&self, writer: &mut ILWriter) {
let mut line = String::from("wire ");
@ -111,27 +125,25 @@ impl Module {
self.cells.push(cell)
}
pub fn write_rtlil(&self, writer: &mut ILWriter) {
pub fn make_genid(&mut self, stem: &str) -> String {
let res = format!("${}${}", stem, self.gen_id);
self.gen_id += 1;
res
}
}
impl RtlilWrite for Module {
fn write_rtlil(&self, writer: &mut ILWriter) {
writer.write_line(&format!("module {}", self.name));
writer.indent();
for wire in &self.wires {
wire.write_rtlil(writer);
}
for cell in &self.cells {
cell.write_rtlil(writer);
}
writer.write_iter(&self.wires);
writer.write_iter(&self.cells);
for conn in &self.connections {
writer.write_line(&format!("connect {} {}", conn.0, conn.1))
}
writer.dedent();
writer.write_line("end");
}
pub fn make_genid(&mut self, stem: &str) -> String {
let res = format!("${}${}", stem, self.gen_id);
self.gen_id += 1;
res
}
}
#[derive(Debug)]
@ -159,7 +171,9 @@ impl Cell {
pub fn add_connection(&mut self, from: &str, to: &str) {
self.connections.push((from.into(), to.into()))
}
}
impl RtlilWrite for Cell {
fn write_rtlil(&self, writer: &mut ILWriter) {
writer.write_line(&format!("cell {} {}", self.celltype, self.id));
writer.indent();

71
src/rtlil/sync.rs Normal file
View File

@ -0,0 +1,71 @@
use crate::rtlil::RtlilWrite;
pub struct Process {
id: String,
root_case: CaseRule,
sync_rules: Vec<SyncRule>,
}
pub struct CaseRule {
assign: Vec<(String, String)>,
switches: Vec<SwitchRule>,
}
pub struct SwitchRule {
signal: String,
cases: Vec<CaseRule>,
}
pub struct SyncRule {
cond: SyncCond,
assign: Vec<(String, String)>,
}
pub enum SyncCond {
Always,
Posedge(String),
Negedge(String),
}
impl RtlilWrite for Process {
fn write_rtlil(&self, writer: &mut super::ILWriter) {
writer.write_line(&format!("process {}", self.id));
self.root_case.write_rtlil(writer);
writer.write_iter(&self.sync_rules);
}
}
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();
writer.write_iter(&self.cases);
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::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();
}
}