You are on page 1of 5

27/12/12

Sy nchronous design with Verilog

Synchronous design with Verilog


Purely synchronous design is based upon the principle that all state elements (dtypes) can only be changed on a single event trigger (for instance, a positive clock edge). One of the key benefits of this is that glitches on a control line do not lead to unexpected changes since when they take effect (on the trigger event) the glitch will have gone away.

Verilog coding practice


In some styles of Verilog, an output is continuously updated by enclosing it in an always block and putting all of its inputs on the event list. Thus a s-1 multiplexor could be:
m o d u l ec o n t A s s _ A ( o u t ,c n t ,a ,b ) ; o u t p u to u t ; i n p u t c n t ,a ,b ; r e g o u t ; a l w a y s@ ( c n to rao rb ) o u t=c n t?a :b ; e n d m o d u l e/ /c o n t A s s

Notice that out must be declared as a register to allow it to be the target of an assignment within an always block. In some cases this permits clarity as in:
m o d u l ec o n t A s s _ B ( o u t ,c n t ,a ,b ) ; o u t p u to u t ; i n p u t c n t ,a ,b ; r e g o u t ; a l w a y s@ ( c n to rao rb ) i f( c n t= =1 )o u t=a ; e l s ei f( c n t= =0 )o u t=b ; e l s e$ d i s p l a y ( " u n e x p e c t e dv a l u ef o rc n t( % b ) " ,c n t ) ; e n d m o d u l e

However, in other cases a simple continuous assignment statement will suffice:


m o d u l ec o n t A s s _ C ( o u t ,c n t ,a ,b ) ; o u t p u to u t ; i n p u t c n t ,a ,b ; a s s i g no u t=c n t?a :b ; e n d m o d u l e

Notice: no reg declaration.


www.ee.ed.ac.uk/~gerard/Teach/Verilog/DesignTips/Sy ncVer.html 1/5

27/12/12

Sy nchronous design with Verilog

In the first two examples, the reg declaration was simply made to allow the assignment within an always block: there was NO intended correspondence with a "register" which would hold the value of out (since the code states that this changes whenever the input changes). However, when we DO want a software equivalent of a state element there should be ONLY ONE ENTRY ON THE EVENT list. Thus the basic, bog-standard Dtype is:
m o d u l ed t y p e ( o u t ,c l k ,d ) ; o u t p u to u t ; i n p u t c l k ,d ; r e g o u t ; a l w a y s@ ( p o s e d g ec l k ) o u t=d ; e n d m o d u l e

and, of course, here the reg actually does hold its value in between changes positive clock edges. It is simple to enhance this module with additional functionality. Thus, for instance, we can add a synchronous reset:
m o d u l ed t y p e _ r ( o u t ,c l k ,r e s e t ,d ) ; o u t p u to u t ; i n p u t c l k ,r e s e t ,d ; r e g o u t ; a l w a y s@ ( p o s e d g ec l k ) i f( r e s e t= =1 ) o u t=0 ; e l s e o u t=d ; e n d m o d u l e

or perhaps a set and an enable signal (which updates the output only if the enable control signal is high):
m o d u l eE t y p e _ s ( o u t ,c l k ,e n a b l e ,s e t ,d ) ; o u t p u to u t ; i n p u t c l k ,e n a b l e ,s e t ,d ; r e g o u t ; a l w a y s@ ( p o s e d g ec l k ) i f( s e t= =1 ) o u t=1 ; e l s ei f( e n a b l e= =1 ) o u t=d ; e n d m o d u l e

To repeat: in synchronous design, there should only be one (edge-triggered) event guarding the always statements which implement state elements. Thus the following is NOT recommended:
www.ee.ed.ac.uk/~gerard/Teach/Verilog/DesignTips/Sy ncVer.html 2/5

27/12/12

Sy nchronous design with Verilog

m o d u l ed t y p e _ A _ r ( o u t ,c l k ,r e s e t ,d ) ; o u t p u to u t ; i n p u t c l k ,r e s e t ,d ; r e g o u t ; a l w a y s@ ( p o s e d g ec l ko rp o s e d g er e s e t ) i f( r e s e t= =1 ) o u t=0 ; e l s e o u t=d ; e n d m o d u l e

since any positive transition (even a brief "hazard") on the reset signal will cause the dtype to be reset. Of course, the state elements do not need to be as simple as these examples. For instance. they could be: an n-bit register a counter which is incremented on each clock edge a state machine (usually implemented by a case statement indexed by the current value of the "state")

Test vector strategy


Synchronous design assumes that all signals settled down when the next active clock edge arrives. Thus any inputs which we provide as test vectors should also be "settled down" on the active clock edge. In general, we provide a clock signal: clk with code such as:
r e gc l k ; i n i t i a lb e g i n c l k=0 ; f o r e v e r# 5 0c l k=~ c l k ; e n d

which means that there will be a rising clock edge at 50, 150, 250. Thus we can change our input signals on multiples of 100:
i n i t i a lb e g i n a=0 ; # 1 0 0a=1 ; # 8 0 0a=0 ; # 1 0 0a=1 ; # 2 0 0$ f i n i s h ; e n d

Note: the delays are accumulative rather than absolute - this means that in the above example the changes occur at time: time incr 0
www.ee.ed.ac.uk/~gerard/Teach/Verilog/DesignTips/Sy ncVer.html

a= 0 1
3/5

#0

100 #100

27/12/12

Sy nchronous design with Verilog

900 #800 1000 #100

0 1

1200 #200 STOP By the same token, we can set up a $display command to catch the outputs of our circuit at some time after the active clock edge (giving enough time for the signals to all settle down. Thus:
i n i t i a l# 4 0f o r e v e r# 1 0 0$ d i s p l a y ( " o u t p u t=% d " ,o u t ) ;

NOTE: because there is a delay (possibly of zero time, but a delay never the less) between a trigger event and an output change, you cannot sample the output of a gate at the same time as its change occurs and expect to see the new value. Thus
a l w a y s@ ( p o s e d g ec l k ) o u t=d ; a l w a y s@ ( p o s e d g ec l k ) $ d i s p l a y ( " o u t p u t=% d " ,o u t ) ;

will (may?) not give you the new value of out. Instead you should delay the event by some time. In general, (when we have non-zero gate delays for our gates) this sampling will need to be after all the signals and gates have settled down - thus in the example above we delay the sampling by #40 units. In cases where we are dealing with only #0 delays, then a pause of #1 (or indeed of an explicit #0 ) is sufficient. An alternative to the forever loop above might thus be:
a l w a y s@ ( p o s e d g ec l k ) # 1$ d i s p l a y ( " o u t p u t=% d " ,o u t ) ;

Putting these ideas together gives us a test module such as:


m o d u l et e s t s y n c ; r e g[ 3 : 0 ]a , b ; r e g c l k ; i n i t i a lb e g i n c l k=0 ; f o r e v e r# 5 0c l k=~ c l k ; e n d i n i t i a lb e g i n a=0 ; # 1 0 0a=1 ; # 8 0 0a=2 ; # 1 0 0a=3 ; # 2 0 0$ f i n i s h ; e n d i n i t i a l # 4 0f o r e v e r # 1 0 0$ d i s p l a y ( $ t i m e ,"i n p u t=% do u t p u t=% d " ,a ,b ) ; a l w a y s@ ( p o s e d g ec l k )b=a ;
www.ee.ed.ac.uk/~gerard/Teach/Verilog/DesignTips/Sy ncVer.html 4/5

27/12/12

Sy nchronous design with Verilog

e n d m o d u l e/ /t e s t s y n c

www.ee.ed.ac.uk/~gerard/Teach/Verilog/DesignTips/Sy ncVer.html

5/5