<commit_before>{-# LANGUAGE TypeOperators, ConstraintKinds #-}

{-# OPTIONS_GHC -Wall #-}
----------------------------------------------------------------------
-- |
-- Module      :  Circat.Circuit
-- Copyright   :  (c) 2013 Tabula, Inc.
-- License     :  BSD3
-- 
-- Maintainer  :  <EMAIL>
-- Stability   :  experimental
-- 
-- Circuit to Netlist conversion
----------------------------------------------------------------------
module Circat.Netlist 
  ( toNetlist, mk_module
  , genVHDL, V.ppModule
  , toV, outV) where

import Data.Functor ((<$>))
import Data.Maybe(fromMaybe)
import Data.Map (Map)
import qualified Data.Map as M

import System.Directory (createDirectoryIfMissing)

import Circat.Circuit ((:>), IsSource2, Comp', simpleComp, runC
                      , tagged, CompNum
                      , Pin)

import Language.Netlist.AST ( Module(..), Ident, Range, Decl(..)
                            , BinaryOp(..), UnaryOp(..), Expr(..)
                            , ExprLit (..), Bit (..))

import Language.Netlist.GenVHDL(genVHDL)
import Language.Netlist.GenVerilog(mk_module)
import qualified Language.Verilog as V

type PinToWireName   = (Pin,String) 

outV :: IsSource2 a b => String -> (a :> b) -> IO ()
outV cirName cir = 
  do createDirectoryIfMissing False outDir
     writeFile filePath (toV cirName cir)
  where
    outDir = "out"
    filePath = outDir ++ "/" ++ cirName ++ ".v"

toV :: IsSource2 a b => String -> (a :> b) -> String
toV cirName cir = show . V.ppModule . mk_module $ toNetlist cirName cir

-- | Converts a Circuit to a Module
toNetlist :: IsSource2 a b => String -> (a :> b) -> Module
toNetlist circuitName cir = Module circuitName ins outs [] (nets++assigns)
  where comps  = simpleComp <$> runC cir
        ncomps      = tagged comps
        (p2wM,ins)  = modulePorts (portComp "In" comps)
        (_,outs)    = modulePorts (portComp "Out" comps)
        (p2wI,nets) = moduleNets ncomps
        p2w         = M.fromList (p2wM ++ p2wI)
        assigns     = moduleAssigns p2w ncomps 

-- | Produces the assign statements for every Comp except "In"
-- Assign statements bind the result of a function (and,or,add etc.)
-- to a variable name which is a wire in verilog parlance
-- eg. w_xor_I1 = In_0 ^ In_1 // (`^` is xor)
moduleAssigns :: Map Pin String -> [(CompNum,Comp')] -> [Decl]
moduleAssigns p2w = concatMap (moduleAssign p2w)

moduleAssign :: Map Pin String -> (CompNum,Comp') -> [Decl]
-- "In" comps are never assigned
moduleAssign _ (_,("In",_,_)) = [] 
-- binary operations
moduleAssign p2w (_,(name,[i0,i1],[o])) = 
  [NetAssign (lw o p2w) (ExprBinary binOp i0E i1E)]
  where
    i0E = expVar i0 p2w
    i1E = expVar i1 p2w
    binOp = 
      case name of
        "and"  -> And
        "or"   -> Or
        "nor"  -> Nor
        "xor"  -> Xor
        "xnor" -> Xnor
        "eq"   -> Equals
        "neq"  -> NotEquals
        _      -> err 
    err = error $ "Circat.Netlist.moduleAssign: BinaryOp " 
          ++ show name ++ " not supported."
-- unary operations                                                  
moduleAssign p2w c@(_,(name,[i],[o])) = 
  [NetAssign (lw o p2w) (ExprUnary unaryOp iE)]
  where
    iE = expVar i p2w
    unaryOp = 
      case name of
        "not" -> Neg
        "False" -> Neg
        _ -> err
    err = error $ "Circat.Netlist.moduleAssign: UnaryOp " 
          ++ show name ++ " not supported." ++ show c

-- constant sources
moduleAssign p2w (_,(name,[],[o])) = [NetAssign (lw o p2w) (ExprLit (Just 1) exprBit)] 
  where exprBit = case name of 
                    "True"  -> ExprBit T
                    "False" -> ExprBit F

-- output assignments
moduleAssign p2w (_,("Out",ps,[])) =
  map (\(n,p) -> NetAssign (outPortName n) (expVar p p2w)) (tagged ps)
  where
     outPortName = portName "Out" ps
     
moduleAssign _ c = error $ "Circat.Netlist.moduleAssign: Comp " ++ show c 
                   ++ " not supported."

expVar :: Pin -> Map Pin String -> Expr
expVar p p2w = ExprVar (lw p p2w)

lw :: Pin -> Map Pin String -> String
lw = lookupWireName

lookupWireName :: Pin -> Map Pin String -> String
lookupWireName pin p2w = fromMaybe err (M.lookup pin p2w)
  where
    err = error ("Circat.Netlist.lookupWireName: Pin " ++ show pin
                 ++ " does not have a wire name.")
    
-- | Generates a wire declaration for all Comp outputs along with 
-- a map from Pin to wire name
moduleNets :: [(CompNum,Comp')] -> ([PinToWireName],[Decl])
moduleNets = unzip . concatMap moduleNet<commit_msg>Stopped passing the size field to ExprLit as it was causing emitting illegal verilog constructs. TODO file issue in github<commit_after>{-# LANGUAGE TypeOperators, ConstraintKinds #-}

{-# OPTIONS_GHC -Wall #-}
----------------------------------------------------------------------
-- |
-- Module      :  Circat.Circuit
-- Copyright   :  (c) 2013 Tabula, Inc.
-- License     :  BSD3
-- 
-- Maintainer  :  <EMAIL>
-- Stability   :  experimental
-- 
-- Circuit to Netlist conversion
----------------------------------------------------------------------
module Circat.Netlist 
  ( toNetlist, mk_module
  , genVHDL, V.ppModule
  , toV, outV) where

import Data.Functor ((<$>))
import Data.Maybe(fromMaybe)
import Data.Map (Map)
import qualified Data.Map as M

import System.Directory (createDirectoryIfMissing)

import Circat.Circuit ((:>), IsSource2, Comp', simpleComp, runC
                      , tagged, CompNum
                      , Pin)

import Language.Netlist.AST ( Module(..), Ident, Range, Decl(..)
                            , BinaryOp(..), UnaryOp(..), Expr(..)
                            , ExprLit (..), Bit (..))

import Language.Netlist.GenVHDL(genVHDL)
import Language.Netlist.GenVerilog(mk_module)
import qualified Language.Verilog as V

type PinToWireName   = (Pin,String) 

outV :: IsSource2 a b => String -> (a :> b) -> IO ()
outV cirName cir = 
  do createDirectoryIfMissing False outDir
     writeFile filePath (toV cirName cir)
  where
    outDir = "out"
    filePath = outDir ++ "/" ++ cirName ++ ".v"

toV :: IsSource2 a b => String -> (a :> b) -> String
toV cirName cir = show . V.ppModule . mk_module $ toNetlist cirName cir

-- | Converts a Circuit to a Module
toNetlist :: IsSource2 a b => String -> (a :> b) -> Module
toNetlist circuitName cir = Module circuitName ins outs [] (nets++assigns)
  where comps  = simpleComp <$> runC cir
        ncomps      = tagged comps
        (p2wM,ins)  = modulePorts (portComp "In" comps)
        (_,outs)    = modulePorts (portComp "Out" comps)
        (p2wI,nets) = moduleNets ncomps
        p2w         = M.fromList (p2wM ++ p2wI)
        assigns     = moduleAssigns p2w ncomps 

-- | Produces the assign statements for every Comp except "In"
-- Assign statements bind the result of a function (and,or,add etc.)
-- to a variable name which is a wire in verilog parlance
-- eg. w_xor_I1 = In_0 ^ In_1 // (`^` is xor)
moduleAssigns :: Map Pin String -> [(CompNum,Comp')] -> [Decl]
moduleAssigns p2w = concatMap (moduleAssign p2w)

moduleAssign :: Map Pin String -> (CompNum,Comp') -> [Decl]
-- "In" comps are never assigned
moduleAssign _ (_,("In",_,_)) = [] 
-- binary operations
moduleAssign p2w (_,(name,[i0,i1],[o])) = 
  [NetAssign (lw o p2w) (ExprBinary binOp i0E i1E)]
  where
    i0E = expVar i0 p2w
    i1E = expVar i1 p2w
    binOp = 
      case name of
        "and"  -> And
        "or"   -> Or
        "nor"  -> Nor
        "xor"  -> Xor
        "xnor" -> Xnor
        "eq"   -> Equals
        "neq"  -> NotEquals
        _      -> err 
    err = error $ "Circat.Netlist.moduleAssign: BinaryOp " 
          ++ show name ++ " not supported."
-- unary operations                                                  
moduleAssign p2w c@(_,(name,[i],[o])) = 
  [NetAssign (lw o p2w) (ExprUnary unaryOp iE)]
  where
    iE = expVar i p2w
    unaryOp = 
      case name of
        "not" -> Neg
        "False" -> Neg
        _ -> err
    err = error $ "Circat.Netlist.moduleAssign: UnaryOp " 
          ++ show name ++ " not supported." ++ show c

-- constant sources
moduleAssign p2w (_,(name,[],[o])) = [NetAssign (lw o p2w) (ExprLit Nothing exprBit)] 
  where exprBit = case name of 
                    "True"  -> ExprBit T
                    "False" -> ExprBit F

-- output assignments
moduleAssign p2w (_,("Out",ps,[])) =
  map (\(n,p) -> NetAssign (outPortName n) (expVar p p2w)) (tagged ps)
  where
     outPortName = portName "Out" ps
     
moduleAssign _ c = error $ "Circat.Netlist.moduleAssign: Comp " ++ show c 
                   ++ " not supported."

expVar :: Pin -> Map Pin String -> Expr
expVar p p2w = ExprVar (lw p p2w)

lw :: Pin -> Map Pin String -> String
lw = lookupWireName

lookupWireName :: Pin -> Map Pin String -> String
lookupWireName pin p2w = fromMaybe err (M.lookup pin p2w)
  where
    err = error ("Circat.Netlist.lookupWireName: Pin " ++ show pin
                 ++ " does not have a wire name.")
    
-- | Generates a wire declaration for all Comp outputs along with 
-- a map from Pin to wire name
moduleNets :: [(CompNum,Comp')] -> ([PinToWireName],[Decl])
moduleNets = unzip . concatMap moduleNet
{'fraction_non_alphanumeric': 0.15704565408252855, 'fraction_numerical': 0.009547848990342406, 'mean_word_length': 2.099659863945578, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2719878', 'n_tokens_mistral': 3066, 'n_tokens_neox': 2946, 'n_words': 905}