diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..a37a86c --- /dev/null +++ b/TODO.md @@ -0,0 +1,35 @@ + # General and Planning + - [ ] might need many validation phases + - [ ] it's conceivable that one could construct a Yosys memory Cell with invalid parameters + - [ ] detect mismatched sizes in assignments + - [ ] need canonical form making it easy to run all these validation passes + - [ ] are recursive slices inclusive + - [ ] what are the semantics of connection ``? Where is `` employed? + - [ ] Validate that `123456789[0:9][0:8]` is valid RTLIL + - [ ] reload VSCode window + - [ ] add validation section to README + - [ ] just support Cell memV2 + - [ ] for value, what happens if we have 0 binary digits + - [ ] ask ChatGPT about how to get my parser to ignore comments... - should probably wait until parser is finished before asking + - [ ] modify AST to support src tracking - needed to allow for human readable and correctable validation errors + - [ ] you could have a concated signal that gets sliced + - [ ] when writing simulator, must specify directions on cell ports + - [ ] in the , why are we allowed to have before and after the optional stmt? + - [ ] make TODO file + - [ ] inspect Chris's mini-RTLIL + - [ ] split/organize imports/exports by section + - [ ] add RST grammar file to repo + - [ ] figure out whitespaces + - [ ] I think only EOL terminated parsers should be responsible for pre-winding the Parsec scanner to the next non-space... + - [ ] lift grammar into prover and show that all EOL terminated parsers are either followed by EOF or a keyword such "module", "autoidx", etc + - [ ] name parsers that that we know where failures occured? + - [ ] first, manually inspect switch parser and try and see if it + can infinitely recurse... Then empirically validate against corpus + + # Simulation + - [ ] dump to VCD + - [ ] Write dynamically typed executor in Haskell + - [ ] Subsequent IR passes may emerge natrually + +# Optimizations + - [ ] squeeze out recursive slices \ No newline at end of file diff --git a/src/RTLILParser/AST.hs b/src/RTLILParser/AST.hs index 3ba776f..881bcd1 100644 --- a/src/RTLILParser/AST.hs +++ b/src/RTLILParser/AST.hs @@ -134,14 +134,14 @@ data AssignStmt = AssignStmt DestSigSpec SrcSigSpec deriving (Show) -- Switches -data Switch = Switch SwitchStmt [AttrStmt] [Case] +data Switch = Switch SwitchStmt [Case] deriving (Show) data SwitchStmt = SwitchStmt SigSpec [AttrStmt] deriving (Show) -data Case = Case CaseStmt [AttrStmt] [AssignStmt] CaseBody +data Case = Case CaseStmt [AttrStmt] CaseBody deriving (Show) data CaseStmt = CaseStmt (Maybe Compare) deriving (Show) -data Compare = Compare SigSpec [SigSpec] +data Compare = Compare [SigSpec] deriving (Show) data CaseBodyVariants = CaseBodySwitchVariant Switch | CaseBodyAssignVariant AssignStmt diff --git a/src/RTLILParser/Parser.hs b/src/RTLILParser/Parser.hs index 599a1aa..8433c3e 100644 --- a/src/RTLILParser/Parser.hs +++ b/src/RTLILParser/Parser.hs @@ -51,6 +51,8 @@ import RTLILParser.Primitives( ,pOctal ,pEscapedChar ) +import Text.Parsec.Token (GenLanguageDef(caseSensitive)) +import GHC.IO.Handle.Types (Handle__(Handle__)) -- taken from: https://yosyshq.readthedocs.io/projects/yosys/en/0.47/appendix/rtlil_text.html -- parsers below are split int sections from the above link @@ -104,17 +106,17 @@ pString = -- Autoindex statements pAutoIdxStmt :: Parser AutoIdxStmt -pAutoIdxStmt = AutoIdxStmt <$> (string "autoidx" *> pWs *> pInteger <* pEol) +pAutoIdxStmt = AutoIdxStmt <$> (string "autoidx" *> pWs *> pInteger <* pEol <* pMaybeWs) -- Module pModuleStmt :: Parser Id -pModuleStmt = string "module" *> pWs *> pId <* pEol +pModuleStmt = string "module" *> pWs *> pId <* pEol <* pMaybeWs pParamStmt :: Parser ParamStmt pParamStmt = ParamStmt <$> (string "parameter" *> pWs *> pId <* pWs) <*> optionMaybe pConstant - <* pEol + <* pEol <* pMaybeWs pConstant :: Parser Constant pConstant = @@ -130,7 +132,7 @@ pAttrStmt :: Parser AttrStmt pAttrStmt = AttrStmt <$> (string "attribute" *> pWs *> pId) <*> (pWs *> pConstant) - <* pEol + <* pEol <* pMaybeWs -- Signal Specifications pSigSpec :: Parser SigSpec @@ -167,7 +169,7 @@ pConnStmt :: Parser ConnStmt pConnStmt = ConnStmt <$> (string "connect" *> pWs *> pSigSpec) <*> (pWs *> pSigSpec) - <* pEol + <* pEol <* pMaybeWs -- Wires pWire :: Parser Wire @@ -184,7 +186,7 @@ pWireStmt = <*> (WireId <$> pId) <* pWs <*> many pWireOption - <* pEol + <* pEol <* pMaybeWs pWireId :: Parser WireId pWireId = WireId <$> pId @@ -214,7 +216,7 @@ pMemoryStmt = <*> (MemoryID <$> pId) <* pWs <*> many pMemoryOption - <* pEol + <* pEol <* pMaybeWs pMemoryOption :: Parser MemoryOption pMemoryOption = @@ -237,7 +239,7 @@ pCellStmt = do cellType <- CellType <$> pId _ <- pWs cellId <- CellId <$> pId - _ <- pEol + _ <- pEol <* pMaybeWs return $ CellStmt cellId cellType pCellBodyStmt :: Parser CellBodyStmt @@ -253,14 +255,14 @@ pCellBodyParameter = do _ <- string "parameter" <* pWs sign <- optionMaybe pParameterSign <* pMaybeWs id <- pId - const <- pConstant <* pEol + const <- pConstant <* pEol <* pMaybeWs return $ CellBodyParameter sign id const pCellBodyConnect :: Parser CellBodyStmt pCellBodyConnect = do _ <- string "connect" <* pWs id <- pId <* pWs - sigSpec <- pSigSpec <* pEol + sigSpec <- pSigSpec <* pEol <* pMaybeWs return $ CellConnect id sigSpec -- Processes @@ -273,22 +275,62 @@ pSrcSigSpec = SrcSigSpec <$> pSigSpec pAssignStmt :: Parser AssignStmt pAssignStmt = AssignStmt <$> (string "assign" *> pWs *> pDestSigSpec) - <*> (pWs *> pSrcSigSpec <* pEol) + <*> (pWs *> pSrcSigSpec <* pEol <* pMaybeWs) -- Switches +-- - [ ] ::= * +-- - [ ] ::= * switch +-- - [ ] ::= * +-- - [x] ::= case ? +-- - [x] ::= (, )* +-- - [ ] ::= ( | )* +-- - [ ] ::= end + +pSwitch :: Parser Switch +pSwitch = Switch + <$> pSwitchStmt + <*> (many pCase <* pSwitchEndStmt) + +pSwitchStmt :: Parser SwitchStmt +pSwitchStmt = do + attrs <- many pAttrStmt + _ <- string "switch" <* pWs + sigspec <- pSigSpec <* pEol <* pMaybeWs + return $ SwitchStmt sigspec attrs + +pCase :: Parser Case +pCase = Case + <$> pCaseStmt + <*> many pAttrStmt + <*> pCaseBody + pCaseStmt :: Parser CaseStmt pCaseStmt = CaseStmt - <$> (string "case" *> pWs *> optionMaybe pCompare <* pEol) + <$> ( + string "case" *> pWs + *> optionMaybe pCompare + <* pEol <* pMaybeWs) pCompare :: Parser Compare pCompare = Compare - <$> pSigSpec - <*> many (char ',' *> pMaybeWs *> pSigSpec) + <$> pSigSpec `sepBy` (pMaybeWs *> char ',' *> pMaybeWs) + +pCaseBody :: Parser CaseBody +pCaseBody = CaseBody <$> many pCaseBodyVariant + +pCaseBodyVariant :: Parser CaseBodyVariants +pCaseBodyVariant = + try (CaseBodySwitchVariant <$> pSwitch ) <|> + (CaseBodyAssignVariant <$> pAssignStmt) + +pSwitchEndStmt :: Parser () +pSwitchEndStmt = void (string "end" *> pEol *> pMaybeWs) + -- Syncs - + -- would correspond to `123456789[0:9][0:8]` exampleSigSpecSlice = SigSpecSlice