/// 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