Sunteți pe pagina 1din 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:

modulecontAss_A(out,cnt,a,b); outputout; input cnt,a,b;

reg

out;

always@(cntoraorb)

out=cnt?a:b;

endmodule//contAss

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:

modulecontAss_B(out,cnt,a,b); outputout; input cnt,a,b;

reg

out;

always@(cntoraorb)

if(cnt==1)out=a;

elseif(cnt==0)out=b;

else$display("unexpectedvalueforcnt(%b)",cnt);

endmodule

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

modulecontAss_C(out,cnt,a,b); outputout; input cnt,a,b;

assignout=cnt?a:b;

endmodule

Notice: no reg declaration.

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:

moduledtype(out,clk,d); outputout; input clk,d;

reg

out;

always@(posedgeclk)

out=d;

endmodule

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:

moduledtype_r(out,clk,reset,d); outputout; input clk,reset,d;

reg

out;

always@(posedgeclk)

if(reset==1)

out=0;

else

out=d;

endmodule

or perhaps a set and an enable signal (which updates the output only if the enable control signal is high):

moduleEtype_s(out,clk,enable,set,d); outputout; input clk,enable,set,d;

reg

out;

always@(posedgeclk)

if(set==1)

out=1;

elseif(enable==1)

out=d;

endmodule

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:

27/12/12

Sy nchronous design with Verilog

moduledtype_A_r(out,clk,reset,d); outputout; input clk,reset,d;

reg

out;

always@(posedgeclkorposedgereset)

if(reset==1)

out=0;

else

out=d;

endmodule

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 registerbe as simple as these examples. For instance. they could be: counter which is incremented on

counter which is incremented on each clock edgeexamples. For instance. they could be: an n-bit register state machine (usually implemented by a case

state machine (usually implemented by a case statement indexed by the current value of the "state") case statement indexed by the current value of the "state")

a

a

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:

regclk;

initialbegin

clk=0;

forever#50clk=~clk;

end

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:

initialbegin

a=0;

#100a=1;

#800a=0;

#100a=1;

#200$finish;

end

Note: the delays are accumulative rather than absolute - this means that in the above example the changes occur at time:

time

incr

a =

0

#0

0

100 #100

1

27/12/12

Sy nchronous design with Verilog

900 #800

0

1000

#100

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:

initial#40forever#100$display("output=%d",out);

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

always@(posedgeclk)

out=d;

always@(posedgeclk)

$display("output=%d",out);

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:

always@(posedgeclk)

#1$display("output=%d",out);

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

moduletestsync;

reg[3:0]a,b;

reg

clk;

initialbegin

clk=0;

forever#50clk=~clk;

end

initialbegin

a=0;

#100a=1;

#800a=2;

#100a=3;

#200$finish;

end

initial

#40forever

#100$display($time,"input=%doutput=%d",a,b);

always@(posedgeclk)b=a;

27/12/12

Sy nchronous design with Verilog

endmodule//testsync