Skip to content

Commit 9bc9e78

Browse files
committed
rewrite ProessDecl to be more specific - a sequential process with explicit clock and (optional) reset
1 parent 6d99f56 commit 9bc9e78

File tree

5 files changed

+67
-107
lines changed

5 files changed

+67
-107
lines changed

netlist-to-verilog/Language/Netlist/GenVerilog.hs

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
-- AST permits left- and right-rotate operators, which are not supported in
1818
-- Verilog.
1919
--------------------------------------------------------------------------------
20+
{-# LANGUAGE ViewPatterns #-}
2021

2122
-- TODO: endianness - currently we're hardcoded to little endian verilog
2223

@@ -86,51 +87,34 @@ mk_decl (InitProcessDecl stmt)
8687
mk_decl (CommentDecl str)
8788
= [V.CommentItem str]
8889

89-
-- nothing to do here
90-
mk_decl (ProcessDecl [])
91-
= []
92-
93-
mk_decl (ProcessDecl xs)
90+
mk_decl (ProcessDecl (Event (mk_expr -> clk) edge) Nothing stmt)
9491
= [V.AlwaysItem (V.EventControlStmt e (Just s))]
9592
where
96-
s = mk_process_stmt xs
97-
e = V.EventControlExpr $ mk_trigger (map fst xs)
93+
e = V.EventControlExpr event
94+
s = V.IfStmt cond (Just (mk_stmt stmt)) Nothing
95+
96+
(event, cond) = edge_helper edge clk
97+
98+
mk_decl (ProcessDecl (Event (mk_expr -> clk) clk_edge)
99+
(Just (Event (mk_expr -> reset) reset_edge, reset_stmt)) stmt)
100+
= [V.AlwaysItem (V.EventControlStmt e (Just s1))]
101+
where
102+
e = V.EventControlExpr (V.EventOr clk_event reset_event)
103+
104+
s1 = V.IfStmt reset_cond (Just (mk_stmt reset_stmt)) (Just s2)
105+
s2 = V.IfStmt clk_cond (Just (mk_stmt stmt)) Nothing
106+
107+
(clk_event, clk_cond) = edge_helper clk_edge clk
108+
(reset_event, reset_cond) = edge_helper reset_edge reset
109+
110+
edge_helper :: Edge -> V.Expression -> (V.EventExpr, V.Expression)
111+
edge_helper PosEdge x = (V.EventPosedge x, x)
112+
edge_helper NegEdge x = (V.EventNegedge x, V.ExprUnary V.UBang x)
98113

99114
mk_range :: Range -> V.Range
100115
mk_range (Range e1 e2)
101116
= V.Range (mk_expr e1) (mk_expr e2)
102117

103-
mk_process_stmt :: [(Event, Stmt)] -> V.Statement
104-
mk_process_stmt []
105-
= error "mk_process_stmt: empty list"
106-
mk_process_stmt [(_, stmt)]
107-
-- if this is the last one, then we don't have to check the event condition
108-
= mk_stmt stmt
109-
mk_process_stmt ((Event e edge, stmt):xs)
110-
= V.IfStmt cond (Just (mk_stmt stmt)) (Just (mk_process_stmt xs))
111-
where
112-
cond = case edge of
113-
PosEdge -> (mk_expr e)
114-
NegEdge -> V.ExprUnary V.UBang (mk_expr e)
115-
116-
-- create a Verilog event expression from a list of triggers.
117-
-- the list must have at least one 'Event' field in it.
118-
mk_trigger :: [Event] -> V.EventExpr
119-
mk_trigger []
120-
= error "mk_trigger: empty event list"
121-
mk_trigger xs0
122-
= foldr1 V.EventOr (f xs0)
123-
where
124-
f [] = []
125-
f (Event x edge : xs) = e : f xs
126-
where
127-
e = case edge of
128-
PosEdge -> V.EventPosedge (mk_expr x)
129-
NegEdge -> V.EventNegedge (mk_expr x)
130-
-- AnyEdge -> V.EventExpr (expr_var x)
131-
-- V.EventOr (V.EventPosedge (expr_var x)) (V.EventNegedge (expr_var x))
132-
-- is this the right thing to do?
133-
134118
mk_stmt :: Stmt -> V.Statement
135119
mk_stmt (Assign x expr)
136120
= V.NonBlockingAssignment (mk_expr x) Nothing (mk_expr expr)

netlist-to-vhdl/Language/Netlist/GenVHDL.hs

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import Language.Netlist.AST
1717

1818
import Text.PrettyPrint
1919
import Data.Maybe(catMaybes)
20-
import Data.List(nub)
2120

2221

2322
-- | Generate a 'Language.Netlist.AST.Module' as a VHDL file . The ['String'] argument
@@ -78,9 +77,6 @@ decl (MemDecl i (Just asize) dsize) = Just $
7877

7978
decl _d = Nothing
8079

81-
82-
83-
8480
insts :: [Decl] -> Doc
8581
insts [] = empty
8682
insts is = case catMaybes $ zipWith inst gensyms is of
@@ -91,13 +87,37 @@ insts is = case catMaybes $ zipWith inst gensyms is of
9187
inst :: String -> Decl -> Maybe Doc
9288
inst _ (NetAssign i e) = Just $ text i <+> text "<=" <+> expr e
9389

94-
inst gensym proc@(ProcessDecl evs) = Just $
90+
inst gensym (ProcessDecl (Event clk edge) Nothing s) = Just $
9591
text gensym <+> colon <+> text "process" <> senlist <+> text "is" $$
9692
text "begin" $$
97-
nest 2 (pstmts evs) $$
93+
nest 2 (text "if" <+> nest 2 event <+> text "then" $$
94+
nest 2 (stmt s) $$
95+
text "end if" <> semi) $$
9896
text "end process" <+> text gensym
99-
where senlist = parens $ cat $ punctuate comma $ map expr $ mkSensitivityList proc
97+
where
98+
senlist = parens $ expr clk
99+
event = case edge of
100+
PosEdge -> text "rising_edge" <> parens (expr clk)
101+
NegEdge -> text "falling_edge" <> parens (expr clk)
100102

103+
inst gensym (ProcessDecl (Event clk clk_edge)
104+
(Just (Event reset reset_edge, reset_stmt)) s) = Just $
105+
text gensym <+> colon <+> text "process" <> senlist <+> text "is" $$
106+
text "begin" $$
107+
nest 2 (text "if" <+> nest 2 reset_event <+> text "then" $$
108+
nest 2 (stmt reset_stmt) $$
109+
text "elsif" <+> nest 2 clk_event <+> text "then" $$
110+
nest 2 (stmt s) $$
111+
text "end if" <> semi) $$
112+
text "end process" <+> text gensym
113+
where
114+
senlist = parens $ cat $ punctuate comma $ map expr [ clk, reset ]
115+
clk_event = case clk_edge of
116+
PosEdge -> text "rising_edge" <> parens (expr clk)
117+
NegEdge -> text "falling_edge" <> parens (expr clk)
118+
reset_event = case reset_edge of
119+
PosEdge -> expr reset <+> text "= '1'"
120+
NegEdge -> expr reset <+> text "= '0'"
101121

102122

103123
inst _ (InstDecl nm inst gens ins outs) = Just $
@@ -130,18 +150,6 @@ inst _ (CommentDecl msg) = Just $
130150

131151
inst _ _d = Nothing
132152

133-
pstmts :: [(Event, Stmt)] -> Doc
134-
pstmts ss = (vcat $ zipWith mkIf is ss) $$ text "end if" <> semi
135-
where is = (text "if"):(repeat (text "elsif"))
136-
mkIf i (p,s) = i <+> nest 2 (event p) <+> text "then" $$
137-
nest 2 (stmt s)
138-
139-
event :: Event -> Doc
140-
event (Event i PosEdge) = text "rising_edge" <> parens (expr i)
141-
event (Event i NegEdge) = text "falling_edge" <> parens (expr i)
142-
event (Event i AsyncHigh) = expr i <+> text "= '1'"
143-
event (Event i AsyncLow) = expr i <+> text "= '0'"
144-
145153
stmt :: Stmt -> Doc
146154
stmt (Assign l r) = expr l <+> text "<=" <+> expr r <> semi
147155
stmt (Seq ss) = vcat (map stmt ss)
@@ -215,18 +223,6 @@ expr (ExprCase e ((p:ps,alt):alts) def) =
215223
expr x = text (show x)
216224

217225

218-
-- | mkSensitivityList takes a process and extracts the appropriate sensitify list
219-
--
220-
221-
mkSensitivityList :: Decl -> [Expr]
222-
mkSensitivityList (ProcessDecl evs) = nub event_names
223-
where event_names =
224-
-- AJG: This is now *only* based on the 'Event' vars, nothing else.
225-
map (\ (e,_) -> case e of
226-
Event (ExprVar name) _ -> ExprVar name
227-
_ -> error $ "strange form for mkSensitivityList " ++ show e
228-
) evs
229-
230226
lookupUnary :: UnaryOp -> Doc -> Doc
231227
lookupUnary op e = text (unOp op) <> parens e
232228

netlist/Language/Netlist/AST.hs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,8 @@ data Decl
8888
-- declare an external module entity
8989
-- TODO: ExternDecl ExternLang
9090

91-
-- | A general process construct, compatible with both VHDL and Verilog
92-
-- processes. It supports positive and negative edge triggers and a body (a
93-
-- statement) for each trigger. Here are loose semantics of a process
94-
-- @[(trigger0, stmt0), (trigger1, stmt1)...]@:
95-
--
96-
-- @
97-
-- if trigger0
98-
-- statement0
99-
-- else if
100-
-- trigger1
101-
-- ...
102-
-- @
103-
104-
| ProcessDecl [(Event, Stmt)]
91+
-- | A sequential process with clock and (optional) asynchronous reset.
92+
| ProcessDecl Event (Maybe (Event, Stmt)) Stmt
10593

10694
-- | A statement that executes once at the beginning of simulation.
10795
-- Equivalent to Verilog \"initial\" statement.
@@ -132,9 +120,6 @@ data Event
132120
data Edge
133121
= PosEdge
134122
| NegEdge
135-
| AsyncHigh
136-
| AsyncLow
137-
-- TODO: AnyEdge?
138123
deriving (Eq, Ord, Show, Data, Typeable)
139124

140125
-- | Expr is a combination of VHDL and Verilog expressions.
@@ -274,8 +259,10 @@ instance Binary Decl where
274259
put x3
275260
put x4
276261
put x5
277-
ProcessDecl x1 -> do putWord8 4
278-
put x1
262+
ProcessDecl x1 x2 x3 -> do putWord8 4
263+
put x1
264+
put x2
265+
put x3
279266
InitProcessDecl x1 -> do putWord8 5
280267
put x1
281268
CommentDecl x1 -> do putWord8 6
@@ -301,7 +288,9 @@ instance Binary Decl where
301288
x5 <- get
302289
return (InstDecl x1 x2 x3 x4 x5)
303290
4 -> do x1 <- get
304-
return (ProcessDecl x1)
291+
x2 <- get
292+
x3 <- get
293+
return (ProcessDecl x1 x2 x3)
305294
5 -> do x1 <- get
306295
return (InitProcessDecl x1)
307296
6 -> do x1 <- get
@@ -334,15 +323,11 @@ instance Binary Edge where
334323
= case x of
335324
PosEdge -> putWord8 0
336325
NegEdge -> putWord8 1
337-
AsyncHigh -> putWord8 2
338-
AsyncLow -> putWord8 3
339326
get
340327
= do i <- getWord8
341328
case i of
342329
0 -> return PosEdge
343330
1 -> return NegEdge
344-
2 -> return AsyncHigh
345-
3 -> return AsyncLow
346331
_ -> error "Corrupted binary data for Edge"
347332

348333

netlist/Language/Netlist/Examples.hs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ ds :: [Decl]
3131
ds = [ NetDecl "a" (makeRange Down 16) (Just (ExprVar "x"))
3232
, NetDecl "b" (makeRange Down 16) (Just (sizedInteger 16 10))
3333
, MemDecl "c" Nothing (makeRange Down 16)
34-
, ProcessDecl
35-
[ (Event (ExprVar "reset") PosEdge, Assign (ExprVar "c") (sizedInteger 16 0))
36-
, (Event (ExprVar "clk") PosEdge, If (ExprVar "enable")
37-
(Assign (ExprVar "c") (ExprVar "x"))
38-
Nothing)
39-
]
34+
, ProcessDecl (Event (ExprVar "clk") PosEdge)
35+
(Just (Event (ExprVar "reset") PosEdge, (Assign (ExprVar "c") (sizedInteger 16 0))))
36+
(If (ExprVar "enable")
37+
(Assign (ExprVar "c") (ExprVar "x"))
38+
Nothing)
4039
]
4140

4241
var_exprs :: [Expr]

netlist/Language/Netlist/Util.hs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,11 @@ statements xs = Seq xs
8989
generateReg :: Expr -> Expr -> Maybe (Expr, Expr) -> Maybe (Expr, Expr) ->
9090
Maybe Expr -> Expr -> Decl
9191
generateReg x clk mb_reset mb_restart mb_enable expr
92-
= ProcessDecl as
92+
= ProcessDecl (Event clk PosEdge) mb_reset' stmt2
9393
where
94-
as = case mb_reset of
95-
Just (reset, initial)
96-
-> [ (Event reset PosEdge, Assign x initial), a0]
97-
Nothing
98-
-> [a0]
99-
100-
a0 = (Event clk PosEdge, stmt2)
94+
mb_reset' = case mb_reset of
95+
Just (reset, initial) -> Just (Event reset PosEdge, Assign x initial)
96+
Nothing -> Nothing
10197

10298
stmt2 = case mb_restart of
10399
Just (restart, initial)

0 commit comments

Comments
 (0)