|
This
page gives FREE synthesizable verilog code examples, block diagrams and
timing diagrams of typical digital circuit building blocks.
|
Topics:
The following topics are currently covered. (Finished topics have links).
A good template for your verilog files
is shown below with an example given afterwards.
This is not taken from the Language
reference manual.
// timescale directive tells the simulator
the base units and precision of the simulation
`timescale 1 ns / 10 ps
module <name> (<input and outputs>);
// parameter declarations
parameter <parameter_name> = <parameter
value>;
// Input output declarations
input <in1>;
input <in2>;
// single bit inputs
input [<msb>:<lsb>] <in3>;
// a bus input
// internal signal register type declaration
- register types (only assigned within always statements).
reg <register variable 1>;
reg [<msb>:<lsb>] <register
variable 2>;
// internal signal. net type declaration
- (only assigned outside always statements)
wire <net variable 1>;
// hierarchy - instantiating another
module
<reference name> <instance name>
(
.pin1
(net1),
.pin2
(net2),
.
.
.
.pinn
(netn)
);
// synchronous procedures
always @ (posedge <clock>)
begin
.
.
.
end
// combinatinal procedures
always @ (signal1 or signal2 or signal3)
begin
.
.
.
end
assign <net variable> = <combinational logic>;
endmodule
Two things to note about inferring flip flops:
| D-type
flip flop
reg q; always @ (posedge clk)
![]() |
![]() |
| D
type flip flop with asynchronous reset
reg q; always @ (posedge clk or posedge reset)
![]() |
![]() |
| D
type flip flop with synchronous reset
reg q; always @ (posedge clk)
![]() |
![]() |
| D
type flip flop with gated clock
reg q;
always @ (posedge gtd_clk)
![]() |
![]() |
| Data
enbled D type flip flop
reg q; always @ (posedge clk)
![]() |
![]() |
| Negative
edge triggered D type flip flop
reg q; always @ (negedge clk)
|
![]() |
| Latch
reg q; always @ (q or enable)
![]() |
![]() |
| Two
input multiplexer (using if else)
reg y; always @ (a or b or select)
|
![]() |
| Two
input multiplexer (using ternary operator ?:)
wire t = (select ? a : b);
|
![]() |
| Two
input multiplexer (using case statement)
reg w; // mux version 3
![]() |
![]() |
| Two
input multiplexer (using default assignment and if)
reg p; // mux version 4
![]() |
![]() |
| Three
input priority encoded mux multiplexer (using if else)
reg q; always @ (a or b or c or select2)
![]() |
![]() |
| Three
input multiplexer with no priority (using case)
reg s; always @ (a or b or c or select2)
![]() |
![]() |
| Comparator
(using assign)
module comparator1 (a,b,c);
|
| Comparator
(using always)
module comparator2 (a,b,c);
|
Finite
State Machines
A full example of a state machine
and associated test bench
The state machine
The state machine
test bench
The following is a simple four state
finite state machine.
The methodology for writing finite
state machines is as follows:
1. Draw a state diagram. Label
all conditions, label all output values. Label the state encoding.
2. Use parameter to encode the
states as in the example.
3. Use two processes or always
statements- one sequential and one combinational. See the example.
4. The state machine is normally
resettable _ choose synchronous or asynchronous.
5. The combinational process normally
has one big case statement in it. Put default values at the beginning.
There are a couple of neat things
about the example.
We are using parameters is the
test bench and passing them to the state machine using parameter passing
We are using tasks to control the
flow of the testbench
We are using hierarchical naming
to access the state variable in the state machine from the test bench.
Finally we are using test bench
messages which allow us to monitor the current state from the simulation
waveform viewer (assuming we change the bus radix of the 'message' to ascii.
//
--------------------------------------------
//
// S T A T E
M A C H I N E
//
// --------------------------------------------
module state_machine(sm_in,sm_clock,reset,sm_out);
parameter idle
= 2'b00;
parameter read
= 2'b01;
parameter write = 2'b11;
parameter wait
= 2'b10;
input sm_clock;
input reset;
input sm_in;
output sm_out;
reg [1:0] current_state,
next_state;
always @ (posedge sm_clock)
begin
if (reset
== 1'b1)
current_state
<= 2'b00;
else
current_state
<= next_state;
end
always @ (current_state
or sm_in)
begin
// default values
sm_out = 1'b1;
next_state = current_state;
case (current_state)
idle:
sm_out = 1'b0;
if (sm_in)
next_state = 2'b11;
write:
sm_out = 1'b0;
if (sm_in == 1'b0)
next_state = 2'b10;
read:
if (sm_in == 1'b1)
next_state = 2'b01;
wait:
if (sm_in == 1'b1)
next_state = 2'b00;
endcase
end
endmodule
//
--------------------------------------------
//
// T E S T
B E N C H
//
// --------------------------------------------
module testbench;
// parameter declaration
section
// ...
parameter idle_state
= 2'b00;
parameter read_state
= 2'b01;
parameter write_state
= 2'b11;
parameter wait_state
= 2'b10;
// testbench declaration
section
reg [500:1] message;
reg [500:1] state_message;
reg in1;
reg clk;
reg reset;
wire data_mux;
// instantiations
state_machine #(idle_state,
read_state,
write_state,
wait_state) st_mac (
.sm_in
(in1),
.sm_clock
(clk),
.reset
(reset),
.sm_out
(data_mux)
);
// monitor section
always @ (st_mac.current_state)
case (st_mac.current_state)
idle_state : state_message = "idle";
read_state : state_message = "read";
write_state: state_message = "write";
wait_state : state_message = "wait";
endcase
// clock declaration
initial clk = 1'b0;
always #50 clk = ~clk;
// tasks
task reset_cct;
begin
@(posedge
clk);
message
= " reset";
@(posedge
clk);
reset =
1'b1;
@(posedge
clk);
reset =
1'b0;
@(posedge
clk);
@(posedge
clk);
end
endtask
task change_in1_to;
input a;
begin
message = "change in1
task";
@ (posedge clk);
in1 = a;
end
endtask
// main task calling
section
initial
begin
message = "start";
reset_cct;
change_in1_to(1'b1);
change_in1_to(1'b0);
change_in1_to(1'b1);
change_in1_to(1'b0);
change_in1_to(1'b1);
@ (posedge clk);
@ (posedge clk);
@ (posedge clk);
$stop;
end
endmodule
Please mail any comments or coding queries to finbarr.oregan@ee.ucd.ie
Last updated: August 23, 2000