/// Notes and demos for LSU EE 4702-1 Spring 2001
// Material from Ciletti Chapter 4 (Ci 4), Verilog LRM Chapter 2 and 3.
/// Contents
// Identifiers
// Variables (Incomplete)
// Data Types (Incomplete)
// Constants (Incomplete)
/// Identifiers
// Ci 2.10, LRM 2.7
// Identifiers are used for module names, module instance names, and
// variable names.
// Identifiers:
// First character must be alphabetic or an underscore (_);
// Following characters may be alphabetic, digit, underscore, or dollar sign.
// Case is significant. (myvar and Myvar are different identifiers)
// Maximum length 1024. That's a limit, not a goal.
// Identifier Examples (in wire declarations).
module i_am_an_identifier();
wire this_is_an_identifier;
wire a, A; // Two different variables.
wire a1;
wire icantreadthis;
wire his$is$hard$to$read$too;
wire but_this_I_can_read;
wire _this_works_too;
wire this_is_valid_identifier_but_unless_you_were_skilled_with_a_text_editor_it_would_be_really_difficult_to_use_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
ModuleName ModuleInstanceName(connection1,connection2);
I_m_also_an_idenfifier me_too(And,us,too);
endmodule
/// Variables
// Ci 4.3; LRM 3.2
// Two Kinds of Variables: Net and Register
// Net (as in wire): used to connect modules and gates.
// Register: holds values.
// It's IMPORTANT to understand the differences between these:
// Register types are like variables in conventional languages...
// ... net types are like wires, they are NOT like conventional variables.
/// Register Variable Types
// Ci 4.3.5 Ci 4.3.6 LRM 3.9
// Similar to variables in conventional languages.
// Despite the name, they DO NOT specify anything about how, where,
// or even whether registers should be synthesized.
// Can only be assigned in procedural code ...
// ... which means they CAN NOT connect to output ports of modules ...
// ... nor can they be continuously assigned (covered later).
// Some types of register types: (Types covered soon.)
// reg: Holds logic values. By default, 1 bit.
// integer: Holds integers.
// real: Holds FP values.
// time: Holds a simulation time value. (64-bit integer)
// realtime:Time as a real number.
// Declaration Syntax:
// Within a module:
// reg <identifier1>[,<identifier2>]...;
module reg_demo1(i_am_a_register_type,a);
input a;
output i_am_a_register_type;
reg i_am_a_register_type;
reg me_too;
integer i_am_an_integer_a_kind_of_register_variable;
integer a_change_count;
initial begin
// This is procedural code, the only places registers can be
// assigned.
i_am_a_register_type = 1;
me_too = !i_am_a_register_type;
i_am_an_integer_a_kind_of_register_variable = 12;
a_change_count = 0;
end
always @( a ) begin
// This is also procedural code.
a_change_count = a_change_count + 1;
// Assign bit 3 (LSB = 0) of a_change_count;
i_am_a_register_type = a_change_count[3];
end
endmodule
module reg_demo2(output_x,input_a);
input input_a;
output output_x;
wire input_a;
// (Below) NOT ALLOWED, registers can only be assigned in procedural code.
// reg input_a;
reg reg_b;
reg output_x; // This is perfectly okay.
// (Below) Syntax error because can only assign registers in procedural code.
// reg output_x = reg_b;
initial begin
output_x = !input_a;
end
always @( input_a ) begin
output_x = ! input_a;
end
endmodule
/// Net Variable Types
// Ci 4.3.1 Ci 4.3.3 (wired logic) LRM 3.7
// Used to interconnect devices.
// Do not store values.
// Can NOT ordinarily be assigned in procedural code.
// Net types are assigned by:
// Connecting them to the output of a module (in an instantiation).
// Using an assignment statement (to be covered).
// Assigning in the declaration.
// Some net types:
// wire: for ordinary connections.
// tri: for tri-state logic. (E.g., for busses.)
// wand: for wired and connections
// wor: for wired or connections.
module net_demo(x,a,b);
input a,b;
output x;
wire a, b;
wire wire_1;
wire wire_2;
reg r1;
// Example of a continuous assignment.
assign wire_1 = a | b;
and a1(wire_2,a,b);
// This is a continuous assignment, NOT an initialization.
wire wire_3 = wire_1 ^ r1;
// Wired and example. wire_5 = (a | b ) & !wire_2
wand wire_5;
assign wire_5 = a | b;
assign wire_5 = !wire_2;
wire wire_4;
always @( a or b ) begin
r1 = a;
// wire_4 = b; // Not allowed.
end
endmodule
// Complete List of Net Types (LRM 3.7)
// Covered above: wire, wand, wor, tri,
// Tristate wired logic: triand, trior. (Equivalent to wand and wor.)
// Wire with capacitance (not covered): trireg.
// Wire with pull-down and pull-up resistors (not covered): tri0, tr1
// Fixed logic levels: supply0, supply1;
// These will not be covered in detail.
// An example using tri appears further below.
/// Vectors
// LRM 3.3
// By default variables declared reg and wire are 1 bit.
// A vector is a multiple bit reg or wire.
// To declare a vector include a range specification:
// A vector can have 65536 bits
// reg [MSB:LSB] IDENTIFIER;
// wire [MSB:LSB] IDENTIFIER;
// Vectors are unsigned integers.
// Overflows are silently ignored.
module vector_examples();
// Range specification examples.
reg [0:31] a; // Bit zero is most significant.
reg [31:0] b; // Bit 31 is most significant.
reg [32:1] c; // Some people have a problem with zero.
wire a_is_odd = a[31];
wire b_is_odd = a[0];
wire c_is_odd = a[1];
// OVERFLOWS ARE SILENTLY IGNORED.
reg [3:0] i; // An innocent looking four-bit register.
integer j;
initial begin
for(i=0; i<16; i=i+1) begin
j = j + 1;
end
$display("This line will never be executed. Why?");
end
endmodule // vector_examples
/// Vectored and Scalared Declaration Modifiers
// LRM 3.3 (At end of section.)
// The *vectored* keyword modifies a net declaration, informing
// the compiler that one cannot look at individual bits of a
// net.
module vector_examples2();
// Range specification examples.
wire [0:31] a; // Can examine bits.
wire scalared [0:31] b; // Equivalent to above, can examine bits.
wire vectored [0:31] c; // Should examine bits.
wire a_is_odd = a[31]; // Works
wire b_is_odd = a[31]; // Works
wire c_is_odd = a[31]; // Error on some compilers, not Modelsim.
endmodule // vector_examples
/// Data Types
// Ci 4.3.5, 4.3.11-4.3.14
// Available types: logic, integer, real, time, realtime
// integer (LRM 3.9)
// Two's complement signed.
// Size (number of bits) is system dependent, at least 32 bits.
// Integer Constants
//
// Can specify radix (base) and size.
// Logic: (Ci 4.2, LRM 3.1)
// Value Set, Four values, 0, 1, x, z
// x: Undefined. (Usually does NOT mean don't care or wildcard.)
// z: High Impedance
// time, realtime (LRM 3.9)
// Hold simulator time values.
// Unsigned integer, at least 64 bits.
module mux_3_to_1(out, select, in_0, in_1, in_2);
output out;
input select, in_0, in_1, in_2;
tri [7:0] out;
wire [7:0] in_0, in_1, in_2;
wire [1:0] select;
assign out = select == 0 ? in_0 : 8'bz;
assign out = select == 1 ? in_1 : 8'bz;
assign out = select == 2 ? in_2 : 8'bz;
endmodule // mux_3_to_1
module demo_mux();
integer i;
wire [1:0] s = i[1:0];
reg [7:0] i0, i1, i2;
wire [7:0] o;
mux_3_to_1 my_multipexor(o, s, i0, i1, i2);
initial begin
i0 = 100;
i1 = 111;
i2 = 122;
#10;
for(i=0; i<4; i=i+1) begin
// Don't print anything, we'll eyeball the output.
#10;
end
$stop;
end
endmodule
/// Constants
// Ci 2.11, Ci 4.4 (strings) LRM 2.5
// Strings