/// LSU EE 4755 -- Fall 2019 -- Digital Design / HDL /// /// Descriptive Styles /// Contents /// References // :SV12: IEEE 1800-2017 -- The SystemVerilog Standard // https://ieeexplore.ieee.org/document/8299595/ // This is for those already familiar with Verilog. // // :BV3: Brown & Vranesic, Fundamentals of Digital Logic with Verilog, 3rd Ed. // The text used in LSU EE 2740. // This is for those who need to review basic Verilog. //////////////////////////////////////////////////////////////////////////////// /// Descriptive Styles // :Def: Descriptive Style // // A set of rules for writing Verilog code. // // The descriptive styles here are informally defined. /// Four Major Styles // // Explicit Structural: Most restrictive. // Implicit Structural: Still restrictive. // Synthesizable Behavioral: Less restrictive, depends on synth prog. // Non-synthesizable Behavioral: No restrictions. No synthesis either. //////////////////////////////////////////////////////////////////////////////// /// Explicit Structural Form // :Def: Explicit Structural Form // // A descriptive style in which a module can not use continuous // assignment statements (assign) or procedural statements (code // within (initial and always). The module can instantiate primitives // and other modules. // // This style is easiest for synthesis programs to work with but // extremely tedious to write. // /// Rules: // No operators ( +, &, ~, >>, etc.) // No continuous assignments. (No use of assign.) // No structured procedures. (No use of initial, always*, final.) // Can instantiate primitives and modules. // :Example: // // The pie module in explicit structural form. This is a good example // of where the explicit structural form should *not* be used, that's // because pie can be much more clearly expressed in implicit // structural form. // module pie( output uwire x, y, input uwire a, b, c ); uwire t1, t2; xor x1(t1,a,b); not n1(x,t1); and a1(t2,x,c); or o1(y,t2,b); /// Don't forget: don't use primitives unless you are forced to. endmodule // :Example: // // The two_pie module below is also in explicit structural form. This // is a good use of the form. // module two_pie( output uwire o1, o2, input uwire f, g, h, a ); uwire i1, i2; pie apple (i1, i2, f, g, h ); pie cherry(o1, o2, i1, i2, a ); endmodule //////////////////////////////////////////////////////////////////////////////// /// Implicit Structural Form // :Def: Implicit Structural Form // // A descriptive style in which a module can not use procedural // statements (code within (initial and always). The module can // instantiate primitives and other modules, and can use continuous // assignments. // // This style is also easy for synthesis programs to work with // but can be tedious to write. /// Rules: // No structured procedures. (No use of initial, always*, final.) // Can use continuous assignments. (assign's are okay) // Can instantiate primitives and modules. // :Example: // // The module below is equivalent to the pie module, except that // it is in implicit structural form. // module pie_implicit_structural ( output uwire x, y, input uwire a, b, c ); assign x = !( a ^ b ); assign y = x && c || b; endmodule //////////////////////////////////////////////////////////////////////////////// /// Behavioral Form // Easiest to write. // Cannot always be synthesized. // (More restrictive behavioral styles can be synthesized, these // will be covered later.) /// Rules: // // :Example: // // The module below is behavioral and is neither explicit nor // implicit structural. // // Because of the $display system task, the module below is not in // synthesizable behavioral form, nor in any other descriptive style // defined above. Obviously, that's easy to fix in this case. // module pie_procedural ( output logic x, y, input uwire a, b, c ); initial begin $display("Hello, from the pie_procedural module!\n"); end always_comb begin // Live in objects: a, b, c // Note: x is not live in. x = !( a ^ b ); y = x && c || b; end endmodule // :Example: Unnecessarily Complicated Behavioral Shifter Description // // This description is correct but unnecessarily complicated and so // should not be used. It is also not synthesizable for reasons to be // covered later. (If you must know: it's because the number of // iterations in the loops depends upon a non-constant value, the // module amt input.) // module shift_right_behavioral ( output logic [15:0] shifted, input uwire [15:0] unshifted, input uwire [3:0] amt ); localparam int width = 16; always_comb begin for ( int i=0; i<width-amt; i++ ) shifted[i] = unshifted[i+amt]; for ( int i=width-amt; i<width; i++ ) shifted[i] = 0; end endmodule //////////////////////////////////////////////////////////////////////////////// /// Synthesizable Behavioral Form // :Def: Synthesizable Behavioral Form // // A descriptive style in which a module can use procedural code, but // following some set of rules for synthesizability. // // Synthesizability rules are determined by the particular synthesis // program being used. Examples of these rules will be covered // throughout the semester. /// Typical Rules // No code reading and writing files or console messages. // No use of delays, limited use of event controls. // The number of iterations in a loop must be an elaboration-time constant. // No floating point types. // // More details in later lectures. // // The rules forbid Verilog code usages for which there is no // reasonable hardware equivalent, or for which the synthesis program // is not capable of generating hardware. // // For example, there is no reasonable hardware equivalent for the use // of $display in pie_procedural. An unreasonable hardware equivalent // would be a little LCD display showing the "Hello" message, which of // course would be a silly thing to add to a simple piece of // combinational logic. // // Verilog code using floating-point numbers is an example of code for // which a particular synthesis program is not capable of inferring // hardware. This is simply a design decision on the part of those // directing the development of those programs. Perhaps they felt that // FP would not be used as frequently as integer calculations and so // they focused there development resources on other features. (Those // needing FP could instantiate modules from a library.) // :Example: // // The module below is equivalent to the pie module, except that // it is in synthesizable behavioral form. module pie_behavioral ( output logic x, y, input uwire a, b, c ); always_comb begin x = !( a ^ b ); y = x && c || b; end endmodule