* Note the the IEEE Std 1364-2005 is "Verilog", not "System Verilog" In System Verilog, int is a 32-bit 2-state type, whereas integer is a 32-bit 4-state type longint is a new 64-bit 2-state type. byte --> 8-bit, 2-state, signed shortint --> 16-bit, 2-state, signed int --> 32-bit, 2-state, signed longint --> 64-bit, 2-state, signed integer --> 32-bit, 4-state, signed According to System Verlilog, 2-state variables are initialized to 0 by default According to original verilog, 4-state (integer) is initialized to x by default According to original Verilog, real and realtime are initialized to 0.0 by default You can override the default initial value when you declare a variable, which is good practice anyway for clarity. (From IEEE Std 1364-2005 : 4.2.2 Variable declarations A variable is an abstraction of a data storage element. A variable shall store a value from one assignment to the next. An assignment statement in a procedure acts as a trigger that changes the value in the data storage element. The initialization value for reg, time, and integer data types shall be the unknown value, x. The default initialization value for real and realtime variable data types shall be 0.0. If a variable declaration assignment is used (see 6.2.1), the variable shall take this value as if the assignment occurred in a blocking assignment in an initial construct. It is illegal to redeclare a name already declared by a net, parameter, or variable declaration. ) * IEEE Std 1364-2005 : 4.8.2 Important note. When reals are converted to integer, they are "rounded". This is different than any language I know of. **************************************************************************************** * Signed Objects (p. 33 of vlogref) **************************************************************************************** The following rules determine the resulting type of an expression (from p. 34 of vlogref) * The expression type depends only on the operands. It does not depend on the left-hand side (LHS) (if any). * Decimal numbers are signed. * If any operand is real, the result is real. * If all operands are signed, the result is signed, regardless of operator. * The following list shows objects that are unsigned regardless of the operands: o The result of any expression where any operand is unsigned o Based numbers o Comparison results (1, 0) o Bit select results o Part select results o Concatenate results * If a signed operand is to be resized to a larger signed width and the value of the sign bit is X or Z, the resulting value will be a bit filled with an X value. * If any nonlogical operation has a bit with a signed value of X or Z, then the result is X for the entire value of the expression. Nets as signed objects only have significance in an expression, in which case the entire expression is considered a signed value. Expressions on ports are typed, sized, evaluated, and assigned to the object on the other side of the port using the same rules as expressions in assignments. Verilog-XL uses the following steps for evaluating an expression: 1. Determine the right-hand side (RHS) type, then coerce all RHS operands to this type. 2. Determine the largest operand size, including the LHS (if any), then resize all RHS operands to this size. 3. Evaluate the RHS expression, producing a result of the type found in step 1 and the size found in step 2. 4. If there is a LHS, o Resize the result to the LHS size. o Coerce the result to the LHS type. **************************************************************************************** ~ * ---------------------------------------------------- https://www.verilogpro.com/verilog-reg-verilog-wire-systemverilog-logic/ * ---------------------------------------------------- // Random Number Generator from (works with 32-bit integers) // https://pdfs.semanticscholar.org/8284/542deb19d556c8818e0456cce771a50ed0ff.pdf // Tables of Linear Congruential Generators of Different Sizes and Good // Lattice Structure - Pierre L'Ecuyer // m = (2^16 - 15) = 65521 // a = 17364 // x_n+1 = (x_n * a) mod m // notice a 16 bit 2's comp number x is // -2^15 <= x < 2^15 // -32768 <= x <= 32767 // The biggest (x * a) would thus be 65521 * 17364 = 1137706644 // A 32-bit integer has a range -2^31 <= n < 2^31 = 2147483648 // We can thus to all the math below which will generate // positive numbers from 1 to 65520 (never hits 0 or 65521) // We can thus convert this to an analog value between 0.0 and 1.0 by // y = (x - 0.5) / 65520.0 // For example if I had 5 random numbers (1, 2, 3, 4, 5), I could divide // up the range 0 to 1.0 into subranges 1.0/5 = 0.2 wide // the ranges would be // A --> (0.0 - 0.2) // B --> (0.2 - 0.4) // C --> (0.4 - 0.6) // D --> (0.6 - 0.8) // E --> (0.8 - 1.0) // Using y = (x - 0.5) / 5 // 1 --> 0.1 (Bin A) // 2 --> 0.3 (Bin B) // 3 --> 0.5 (Bin C) // 4 --> 0.7 (Bin D) // 5 --> 0.9 (Bin E) * 10/1/2019 Ok, not I'm wrapping up my studies on the ztm_lib For this library I learned a lot of stuff The $random system task does seem to have a global seed, so it could be used to break symmetry. This did not seem to be the case in VHDL where I had to use the instance name to break symmetry. It seems like the way I'm running iverilog, every module I define gets called at least once, and thus runs in initial blocks in every module This is different than with other verilog simulators, where you need to specify which modules are run, including which module is top The best way to check sytax or anything is just to put the code you are trying to study into a verilog initial module and run it, and print out stuff. For this release of the models, I will now create : fixed delays of 20ps per gate (specified thru a "tp" parameter) fixed offset delay with a spread of +- 2ps (specified thru a "tpo" parameter) jitter delay with a spread of +- 20fs (specified thru a "tpj" parameter) All gates are forced to a random value Gates are release after 1ns + range of (0 to 200ps) Flip Flops and Latches are released after 2ns + range of (0 to 200ps) (these are specified with parameters tfrc trel) * integer and time time is an unsigned 64-bit register integer is a signed 32-bit registor it seems that sometimes people force an integer to be treated as unsigned value by using the concat {} operator as in the random number example below * strings reg [8*10:1] s1, s2; s1 = "Hello"; s2 = " world!"; s1 --> s1 = 000000000048656c6c6f s2 --> s2 = 00000020776f726c6421 ------------------------------------------ module string_test; reg [8*14:1] stringvar; initial begin stringvar = "Hello world"; $display("%s is stored as %h", stringvar,stringvar); stringvar = {stringvar,"!!!"}; $display("%s is stored as %h",stringvar,stringvar); end endmodule The result of running Verilog on the previous description is: Hello world is stored as 00000048656c6c6f20776f726c64 Hello world!!! is stored as 48656c6c6f20776f726c64212121 ------------------------------------------ * verilog $random function (see vlogref - System Tasks and Functions, and Apendix D - Stochastic Analysis) It returns a 32-bit random number each time it is called usage : $random; $random(seed); seed must be an integer or register type and must be defined before calling (it is a variable, and holds the state of the random number generator) shan = ($random % b) gives a number in the range of [-b < shan < b] where b is positive example : reg [23:0] jack; jack = ($random % 60); --> jack will be uniformly distributed in domain (-59 <= jack <= 59) reg [23:0] greg; greg = ({$random} % 60); --> greg will be uniformly distributed in the domain (0 <= greg <= 59) * blocking vs. non-blocking (I found this) >> Blocking Assignments >> Blocking assignments are the most basic of the assignment operations, and >> simply copy the value of the expression at the right hand side of the = >> operator to the variable on the left hand side. However, if two assignments >> that depend on each other are scheduled at the same time, e.g. an attempt to >> swap two variables, such as : >> always @(posedge clk) a = b; >> always @(posedge clk) b = a; >> then a race condition occurs, and both a and b will end up with one of the >> values. The value that they are both left with will depend on which of the >> assignments was scheduled first. >> Non-blocking Assignments >> Non-blocking assignments eliminate the possibility of race conditions in >> situations like this, as at the time that the assignment operation is >> executed the expression on the right hand side of the <= operator is copied >> to an internal temporary variable, which is then copied to the variable on >> the left hand side. All of the `reads' for a particular timestep are carried >> out before any of the `writes', and so values can be safely swapped as below >> always @(posedge clk) a <= b; >> always @(posedge clk) b <= a; >> This time, the code has the intended effect. I think this is better always @(posedge clk) begin a <= b; b <= a; end * One of the most important things in verilog has to do with transport delay and inertial delay (from the verilog user manual) >> Pulse Handling in Verilog-XL 2.0 and Earlier Versions >> In Verilog-XL 2.0 and earlier versions, the simulator >> functions only as an inertial delay simulator. This means >> that during the period of a module path delay, only one >> transition passes through the path\u2019s module input >> and propagates from the module output. Inertial delay is >> the default behavior of the simulator in version 2.1, but >> you can enable transport delay functionality with the >> following plus options: >> >> >> * +transport_path_delays >> >> Enables transport delay functionality and pulse control >> for module path delays. >> >> >> * +transport_int_delays >> >> Enables transport delay functionality and pulse control >> for interconnect delays. (I would recommend sticking with the defaults) You must be careful in feedback loops like latches. A latch is intended to have positive feedback to hold it's value. If the positive feedback look has two gates, then the delay will be TA+TB. Let TH = (TA+TB)/2. A 50% duty cycle signal of peroid 2*TH = (TA+TB) could oscillate, but will be killed by the smaller of TA or TB, unless TA==TB==TH We can thus avoid oscillation by never letting two gates with idential delays form a latch. With one non-inverting gate latched to itself, you cannot oscillate Inertial delay will kill any closed loop oscillation in a two gate loop