add rtlil processes
This commit is contained in:
parent
b9eb6222de
commit
a6b8429ed0
|
@ -3,6 +3,7 @@ use std::collections::BTreeMap;
|
||||||
use crate::builtin_cells::get_builtins;
|
use crate::builtin_cells::get_builtins;
|
||||||
use crate::parser;
|
use crate::parser;
|
||||||
use crate::rtlil;
|
use crate::rtlil;
|
||||||
|
use crate::rtlil::RtlilWrite;
|
||||||
|
|
||||||
fn make_pubid(id: &str) -> String {
|
fn make_pubid(id: &str) -> String {
|
||||||
"\\".to_owned() + id
|
"\\".to_owned() + id
|
||||||
|
|
50
src/rtlil.rs
50
src/rtlil.rs
|
@ -1,3 +1,5 @@
|
||||||
|
mod sync;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ILWriter {
|
pub struct ILWriter {
|
||||||
data: String,
|
data: String,
|
||||||
|
@ -17,6 +19,13 @@ impl ILWriter {
|
||||||
self.data += "\n";
|
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) {
|
pub fn indent(&mut self) {
|
||||||
self.indent += 1
|
self.indent += 1
|
||||||
}
|
}
|
||||||
|
@ -33,11 +42,8 @@ impl ILWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the proper way
|
pub trait RtlilWrite {
|
||||||
#[derive(Debug)]
|
fn write_rtlil(&self, writer: &mut ILWriter);
|
||||||
pub enum PortOption {
|
|
||||||
Input(i32),
|
|
||||||
Output(i32),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -50,6 +56,12 @@ pub struct Wire {
|
||||||
port_info: Option<PortOption>,
|
port_info: Option<PortOption>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum PortOption {
|
||||||
|
Input(i32),
|
||||||
|
Output(i32),
|
||||||
|
}
|
||||||
|
|
||||||
impl Wire {
|
impl Wire {
|
||||||
pub fn new(id: impl Into<String>, width: u32, port_info: Option<PortOption>) -> Self {
|
pub fn new(id: impl Into<String>, width: u32, port_info: Option<PortOption>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -58,7 +70,9 @@ impl Wire {
|
||||||
port_info,
|
port_info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RtlilWrite for Wire {
|
||||||
fn write_rtlil(&self, writer: &mut ILWriter) {
|
fn write_rtlil(&self, writer: &mut ILWriter) {
|
||||||
let mut line = String::from("wire ");
|
let mut line = String::from("wire ");
|
||||||
|
|
||||||
|
@ -111,27 +125,25 @@ impl Module {
|
||||||
self.cells.push(cell)
|
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.write_line(&format!("module {}", self.name));
|
||||||
writer.indent();
|
writer.indent();
|
||||||
for wire in &self.wires {
|
writer.write_iter(&self.wires);
|
||||||
wire.write_rtlil(writer);
|
writer.write_iter(&self.cells);
|
||||||
}
|
|
||||||
for cell in &self.cells {
|
|
||||||
cell.write_rtlil(writer);
|
|
||||||
}
|
|
||||||
for conn in &self.connections {
|
for conn in &self.connections {
|
||||||
writer.write_line(&format!("connect {} {}", conn.0, conn.1))
|
writer.write_line(&format!("connect {} {}", conn.0, conn.1))
|
||||||
}
|
}
|
||||||
writer.dedent();
|
writer.dedent();
|
||||||
writer.write_line("end");
|
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)]
|
#[derive(Debug)]
|
||||||
|
@ -159,7 +171,9 @@ impl Cell {
|
||||||
pub fn add_connection(&mut self, from: &str, to: &str) {
|
pub fn add_connection(&mut self, from: &str, to: &str) {
|
||||||
self.connections.push((from.into(), to.into()))
|
self.connections.push((from.into(), to.into()))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RtlilWrite for Cell {
|
||||||
fn write_rtlil(&self, writer: &mut ILWriter) {
|
fn write_rtlil(&self, writer: &mut ILWriter) {
|
||||||
writer.write_line(&format!("cell {} {}", self.celltype, self.id));
|
writer.write_line(&format!("cell {} {}", self.celltype, self.id));
|
||||||
writer.indent();
|
writer.indent();
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue