From 3a271db7fc1c96778dd6382a9aa16eeec72fc98a Mon Sep 17 00:00:00 2001 From: saji Date: Thu, 4 Apr 2024 15:13:38 -0500 Subject: [PATCH] more wpi --- src/yosys_parser.rs | 128 ++++++++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/src/yosys_parser.rs b/src/yosys_parser.rs index 17d34e7..d42eacb 100644 --- a/src/yosys_parser.rs +++ b/src/yosys_parser.rs @@ -1,6 +1,5 @@ use crate::gal::Pin; use crate::pcf::PcfFile; -use itertools::Itertools; use log::info; use serde::{de::Error, Deserialize, Deserializer, Serialize}; use serde_with::{serde_as, BoolFromInt}; @@ -14,6 +13,26 @@ use std::str; #[serde(transparent)] pub struct Net(u32); +#[derive(Debug, Serialize, Clone, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub enum NetSpecial { + N(u32), + Special(String), // constant ("1", "0") or NC ("x") +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct GalInputConnections { + #[serde(rename = "A")] + pub input: [NetSpecial; 1], + #[serde(rename = "Y")] + pub output: [NetSpecial; 1], // sop Y has exactly one output +} + + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct GalInput { + pub connections: GalInputConnections, +} + // for some reason the json outputs 00000000000111 for some numbers. // this converts them back into binary. fn from_binstr<'de, D>(deserializer: D) -> Result @@ -26,7 +45,7 @@ where #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "UPPERCASE")] -pub struct SoPParameters { +pub struct GalSopParameters { #[serde(deserialize_with = "from_binstr")] pub depth: u32, pub table: String, @@ -34,57 +53,61 @@ pub struct SoPParameters { pub width: u32, } + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub struct SoPConnections { +pub struct GalSopConnections { #[serde(rename = "A")] - pub inputs: Vec, + pub inputs: Vec, #[serde(rename = "Y")] - pub output: [Net; 1], // sop Y has exactly one output + pub output: [NetSpecial; 1], // sop Y has exactly one output } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub struct SoPCell { - pub parameters: SoPParameters, - pub connections: SoPConnections, +pub struct GalSop { + pub connections: GalSopConnections, + pub parameters: GalSopParameters, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub struct DffConnections { - #[serde(rename = "C")] - pub clock: [Net; 1], - #[serde(rename = "D")] - pub input: [Net; 1], - #[serde(rename = "Q")] - pub output: [Net; 1], -} +#[serde_as] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub struct DffCell { - connections: DffConnections, +#[serde(rename_all = "UPPERCASE")] +pub struct GALOLMCParameters { + #[serde_as(as = "BoolFromInt")] + inverted: bool, + #[serde_as(as = "BoolFromInt")] + registered: bool, + } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -#[serde(rename_all = "UPPERCASE")] -pub struct NotConnections { - pub a: [Net; 1], - pub y: [Net; 1], +pub struct GalOLMCConnections { + #[serde(rename = "C")] + pub clock: [NetSpecial; 1], + #[serde(rename = "A")] + pub input: [NetSpecial; 1], + #[serde(rename = "Y")] + pub output: [NetSpecial; 1], + #[serde(rename = "E")] + pub tristate: [NetSpecial; 1], } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub struct NotCell { - connections: NotConnections, +pub struct GalOLMC { + pub parameters: GALOLMCParameters, + pub connections: GalOLMCConnections, } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(deny_unknown_fields)] #[serde(tag = "type")] pub enum YosysCell { - #[serde(rename = "DFF_P")] - DffCell(DffCell), - #[serde(rename = "$sop")] - SoPCell(SoPCell), - #[serde(rename = "$_NOT_")] - NotCell(NotCell), + #[serde(rename = "GAL_SOP")] + Sop(GalSop), + #[serde(rename = "GAL_INPUT")] + Input(GalInput), + #[serde(rename = "GAL_OLMC")] + OLMC(GalOLMC), } #[serde_as] @@ -114,7 +137,7 @@ pub struct YosysDoc { pub modules: HashMap, } -impl SoPCell { +impl GalSop { // extract the logic table using the parameters. pub fn parse_table(self) -> Vec> { // get the list of inputs which is a Vec @@ -250,11 +273,9 @@ type NetAdjPair = (usize, usize, Net); /// A Node is an entry in our graph. A node has inputs and outputs. #[derive(Debug, PartialEq, Clone)] pub enum Node { - Input(NamedPort), - Output(NamedPort), - Sop(SoPCell), - Not(NotCell), - Dff(DffCell), + Input(GalInput), + Sop(GalSop), + Olmc(GalOLMC), } impl Node { @@ -263,22 +284,18 @@ impl Node { * internally. So get_outputs returns values on input_cells, since those are driven already. * Likewise we reverse this for get_inputs, since the chip's outputs are our inputs. */ - fn get_outputs(&self) -> Vec { + fn get_outputs(&self) -> Vec { match self { - Self::Input(i) => vec![i.net.clone()], - Self::Output(_) => Vec::new(), + Self::Input(i) => i.connections.output.to_vec(), Self::Sop(s) => s.connections.output.to_vec(), - Self::Not(n) => n.connections.y.to_vec(), - Self::Dff(d) => d.connections.output.to_vec(), + Self::Olmc(o) => o.connections.output.to_vec(), } } - fn get_inputs(&self) -> Vec { + fn get_inputs(&self) -> Vec { match self { - Self::Input(_) => Vec::new(), - Self::Output(o) => vec![o.net.clone()], - Self::Sop(s) => s.connections.inputs.to_vec(), - Self::Not(n) => n.connections.a.to_vec(), - Self::Dff(d) => d.connections.input.to_vec(), + Self::Input(gi) => gi.connections.input.to_vec(), + Self::Sop(gs) => gs.connections.inputs.to_vec(), + Self::Olmc(go) => go.connections.input.to_vec(), } } } @@ -334,21 +351,6 @@ impl Graph { (inputs, output.unwrap()) } - fn validate(&self) -> Result<(), String> { - let nets: Vec<&Net> = self - .adjlist - .iter() - .map(|(_, _, n)| n) - .unique() - .collect_vec(); - // back-travel - // find output ports, find their drivers - // output port -> Vec -> Vec<(Net,Pin)> - // for each node that connects to output port, get the output NET of that node. - // there should only be one. Then damage that node with a pin tag. - - Ok(()) - } } impl From for Graph {