Visualize
the Hardware:
|
Describe the
Hardware:
|
Comments:
|
D flip-flop, positive-edge triggered
|
module D_FF
(D,Clock,Q);
/* Port modes */
input D,Clock;
output Q;
// Registered identifiers
reg Q;
// Functionality
always @ (posedge Clock)
����� Q <= D;
endmodule
|
The input list only contains the signal
that is responsible for triggering the flip-flop, i.e., the �Clock� signal;
other inputs such as �D� may be used inside the �always� block, but they must
not appear in the parenthesized list.
|
T flip-flop, negative-edge triggered
|
module
T_FF (T,Clock,Q);
/* Port modes */
input T,Clock;
output Q,;
// Registered identifiers
reg Q;
// Functionality
always @ (negedge Clock)
����� if (T == 1)
����������� Q <= ~Q;
endmodule
|
T (�toggle�) flip-flop behavior is such that applying a 1
to the T input causes the output to change state on the clock edge, and
applying a 0 maintains the state.
�negedge� for negative-edge trigger.
NOTE: The behavior when T is zero is not
explicitly described here. The inferred behavior is that the state of Q
should remain unchanged if the �if� test evaluates false (when T is zero).
|
T flip-flop, negative-edge triggered, with inverted and
noninverted outputs
|
module
T_FF (T,Clock,Q,_Q);
/* Port modes */
input T,Clock;
output Q,_Q;
// Registered identifiers
reg Q;
// Functionality
always @ (negedge Clock)
����� if (T == 1)
����������� Q <= ~Q;
assign
_Q = ~Q;
endmodule
|
In this example the �assign� technique is put to good use.
The �always� block implements most of the desired behavior, namely, a single-bit
storage device with appropriate behavior and clocking.
The �assign� statement simply copies the Q signal to an additional output
while performing the necessary inversion along the way.
|
D flip-flop, negative-edge triggered, with inverted and
noninverted outputs, and asynchronous reset (active high)
|
module
D_FF (D,Clock,Q,_Q,Reset);
/* Port modes */
input D,Clock,Reset;
output Q,_Q;
// Registered identifiers
reg Q;
// Functionality
always
@ (negedge Clock or
�� posedge
Reset)
����� if (Reset == 1)
����������� Q <= 0;
����� else
����������� Q <= D;
assign _Q = ~Q;
endmodule
|
�Asynchronous reset� means that asserting the reset will
instantly set the Q output to zero, regardless of the activity of D or Clock.
Q will remain zero as long as Reset is asserted. This behavior matches
standard flip-flop circuits.
The �always� block needs to be �triggered� either by the Clock or the Reset, so the Reset signal is
added to the parenthesized list.
Once inside the �always� block, a test is made to determine whether the clock
or reset was responsible for the trigger, hence the �if� test.
NOTE: Do not try to invent shortcuts
here! You will only cause yourself grief!!
|
D flip-flop, positive-edge triggered, and asynchronous preset
(active low)
|
module
D_FF (D,Clock,Q,_Preset);
/* Port modes */
input D,Clock,_Preset;
output Q;
// Registered identifiers
reg Q;
// Functionality
always @ (posedge Clock or
�� negedge _Preset)
����� if (_Preset == 0)
����������� Q <= 1;
����� else
����������� Q <= D;
endmodule
|
�Asynchronous preset� behaves similarly to �reset�, except
that the Q output is set to 1 instead of zero.
Technique for making active-low asynchronous control input.
|
D flip-flop, positive-edge triggered, with synchronous reset (active high)
|
module
D_FF (D,Clock,Q,Reset);
/* Port modes */
input D,Clock,Reset;
output Q;
// Registered identifiers
reg Q;
// Functionality
always @ (posedge Clock)
����� Q <= (Reset)? 0 : D;
endmodule
|
�Synchronous reset� means that the reset action does not occur
until the next clock edge.
�Reset� does not appear in the
input list now, but it appears inside the �always� block.
|
|
|
NOTE: Avoid the temptation to design arbitrary flip-flop behavior,
e.g., ability to trigger on both edges of the clock, ability to trigger on
multiple clock signals, etc. The hardware synthesis tool does not �magically�
create new hardware from thin air! You have to write circuit descriptions
that are realizable, that is, can be mapped onto existing (known)
hardware elements such as standard D flip-flops.
Bottom line: Use the constructs listed above exactly as
shown... don�t invent your own!!
|
16-bit data register
|
module
Reg16 (D,Clock,Q,Reset);
/* Port modes */
input [15:0] D;
input Clock,Reset;
output [15:0] Q;
// Registered identifiers
reg [15:0] Q;
// Functionality
always @ (posedge Clock or
�� posedge
Reset)
����� if (Reset == 1)
����������� Q <= 0;
����� else
����������� Q <= D;
endmodule
|
A register is
typically composed of an array of D flip-flops.
|
N-bit data
register
|
module
RegN (D,Clock,Q,Reset);
// Constants
parameter
NumBits = 34;
// Port modes
input [Numbits-1:0] D;
input Clock,Reset;
output [Numbits-1:0] Q;
// Registered identifiers
reg [Numbits-1:0] Q;
// Functionality
always @ (posedge Clock or
�� posedge
Reset)
����� if (Reset == 1)
����������� Q <= 0;
����� else
����������� Q <= D;
endmodule
|
The �parameter� keyword is used to declare a global
constant for register width. This is a simple example of parameterized description. Changing only a single number can
update the entire design.
�NumBits� parameter can be used to do mathematical calculations that evaluate
to a constant value, such as register width.
|
8-bit up counter with asynchronous reset
|
module
CountUp (Clock,Reset,Q);
// Port modes
�input Clock,Reset;
output [7:0] Q;
// Registered identifiers
reg [7:0] Q;
// Functionality
always @ (posedge Clock or
�� posedge
Reset)
����� if (Reset == 1)
����������� Q <= 0;
����� else
����������� Q <= Q + 1;
endmodule
|
Free-running up counter
Increments by one in this example. Can easily increment by a different
constant. Use �-� to make a down counter.
|
8-bit up counter with count enable, and asynchronous reset
|
module
CountUp (Clock,Reset,Enable,Q);
// Port modes
�input Clock,Reset,Enable;
output [7:0] Q;
// Registered identifiers
reg [7:0] Q;
// Functionality
always @ (posedge Clock or
�� posedge
Reset)
����� if (Reset == 1)
����������� Q <= 0;
����� else
����������� Q <= (Enable) ? Q + 1 ����������������� :
Q;
endmodule
|
Counter only increments when ENABLE signal is asserted.
Use ternary operator to add a condition to the count operation.
|
8-bit down counter with count enable and initialize
control inputs, asynchronous reset
|
module
CountDown (Clock,Reset,Enable,Init,Q);
// Port modes
input Clock,Reset,Enable,Init;
output [7:0] Q;
// Registered identifiers
reg [7:0] Q;
// Functionality
always @ (posedge Clock or
�� posedge
Reset)
����� if (Reset == 1)
����� ��
Q <= 0;
����� else
����� �� if (Init)
����������� Q <= 8�hFF;
����� ��
else if (Enable)
����������� Q <= Q � 1;
endmodule
|
Counter is similar to previous example, except it counts
down. An additional control input initializes the counter to 8�hFF.
In this example, asserting �Init� has priority over �Enable� if they are both
asserted simultaneously. If neither is asserted, then �Q� remains unchanged.
|
8-bit loadable shift register
|
module
Shifter (Clock,Reset,Load,D,Q);
// Port modes
input Clock,Reset,Load;
input [7:0] D;
output [7:0] Q;
// Registered identifiers
reg [7:0] Q;
// Functionality
always @ (posedge Clock or
�� posedge
Reset)
����� if (Reset == 1)
����� ��
Q <= 0;
����� else
����� ��
Q <= (Load) ? D :
����������� {1�b0,Q[7:1]};
endmodule
|
Right-shifts the data, filling the MSB with zero.
|
Clock divider (produces a pulse every N clock cycles)
|
parameter MaxCount = 12;
always @ (posedge Clock or posedge Reset)
�� if
(Reset) begin
�����
ClockDiv <= 0;
�����
SlowClock <= 0;
�� end
�� else
if (ClockDiv == MaxCount)
�����
begin
��������
SlowClock <= 1;
��������
ClockDiv <= 0;
�����
end
����� else
begin
����� �� SlowClock <= 0;
����� �� ClockDiv <= ClockDiv+1;
����� end
|
|