Documente Academic
Documente Profesional
Documente Cultură
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
27/12/12
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
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")
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
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 ) ;
27/12/12
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