2014年6月1日 星期日

Verilog DataTypes資料型態

  1. DataTypes  源自於 http://www.see.ed.ac.uk/~gerard/Teach/Verilog/manual/
    1. Nets
    2. Registers
    3. Vectors
    4. Numbers
    5. Arrays
    6. Tri-state

Nets

Keywords: wire, supply0, supply1
default value: z
default size: 1 bit
Nets represent the continuous updating of outputs with respect to their changing inputs. For example in the figure below, c is connected to a by a not gate. if c is declared and initialised as shown, it will continuously be driven by the changing value of a, its new value will not have to be explicitly assigned to it.

If the drivers of a wire have the same value, the wire assumes this value. If the drivers have different values it chooses the strongest, if the strengths are the same the wire assumes the value of unknown, x.
The most frequently used net is the wire, two others which may be useful are supply0, and supply1, these model power supplies in a circuit.



Registers

Keywords: reg
default value: x
default size: 1 bit
The fundamental difference between nets and registers is that registers have to be assigned values explicitly. That value is held until a new assignment is made. This property can, for example, be used to model a E-type flip flop as shown in figure below, with corresponding Verilog code given below.



        module E_ff(q, data, enable, reset, clock);
            output q;
            input data, enable, reset, clock;
            reg q;

            always @(posedge clock)  // whenever the clock makes a transition to 1
                if (reset == 0)
                 q = 1'b0;
                else if (enable==1)
                 q = data;
                // implicitly : else q = q:

        endmodule

Register q holds the same value until it us changed by an explicit assignment.

As a contrast, if we go into a higher level module, for example the stimulus shown below, the output from the E_ff would have to be assigned as a net so that the E_ff module can drive its value. So now q is a wire.
        module stimulus;
          reg data, enable, clock, reset;
          wire q;

        initial begin
          clock = 1'b0;
          forever #5 clock = ~clock;
        end

        E_ff eff0(q, data, enable, reset, clock);
        // as with 'c' in the previous section, the wire 'q' will now have its
        // value driven into it by the E_ff module.

        initial begin
          reset = 1'b0;
          #10 reset = 1'b1;
              data = 1'b1;
          #20 enable = 1;
          #10 data = 1'b0;
          #10 data = 1'b1;
          #10 enable = 0;
          #10 data = 1'b0;
          #10 data = 1'b1;
          #10 enable = 1;
          #10 reset = 1'b0;
          #30 $finish;
        end

        initial
          $monitor($time, " q = %d", q);

        endmodule

EXERCISE
Consider the stimulus above and predict the output for q. Then stimulus and check your answer.



Vectors

Both the register and net data types can be any number of bits wide if declared as vectors. Vectors can be accessed either in whole or in part, the left hand number is always the most significant number in the vector. See below for examples of vector declarations.
        reg [3:0] output; // output is a 4-bit register
        wire [31:0] data; // data is a 32-bit wire
        reg [7:0] a;

        data[3:0] = output; // partial assignment
        output = 4'b0101;   // assignment to the whole register


It is important to be consistant in the ordering of the vector width declaration. Normally the most significant figure is written first.
        reg [3:0] a;  // it is important to adopt one convention for
        reg [0:3] b;  // the declaration of vector width.

EXERCISE
a) Declare an 8 bit wire with variable name address.
b) Assign 4'b1010 to its 4 most signficant bits.



Numbers

Integers

Keywords: integer
default value: x
default size: dependant on the host machine, but at least 32 bits
Integers are similar to registers but can store signed (i.e. negative as well as positive numbers) whereas registers can only store positive numbers.

Real numbers

Keywords: real
default value: x
default size: again host machine dependant, but at least 64 bits
Real numbers can be in decimal or scientific format as shown in the example below. When written with a decimal point, there must be at least one number on either side of the point. A real number is converted to an integer by rounding to the nearest integer.
        // 1.3    a real number in decimal format
        // 1.3e27 a real number in scientific format

        real pedantic_pi;
        integer relaxed_pi;

        initial begin
           pedantic_pi = 3.141596259;
           relaxed_pi = pedantic_pi; // relaxed_pi is set to 3
        end

A warning about using registers vs. integers for signed values
An arithmetic operation is treated differently depending on the data type of the operand. A register operand is treated as an unsigned value and an integer value is treated as a signed value. Therefore if a negative value, such as -4'd12, is assigned to a register, it will stored as a positive integer which is its 2's complement value. So when used as an operand the 2's complement value will be used causing unintentional behaviour. If stored in an integer, the behaviour would be as expected, using signed arithmetic.



Arrays

Registers, integers and time data types can be declared as arrays, as shown in the example below. Note the size of the array comes after the variable name in the declaration and after the variable name but before the bit reference in an assignment. So :-
declaration: <data_type_spec> {size} <variable_name> {array_size}
reference: <variable_name> {array_reference} {bit_reference}
        reg data [7:0]; // 8 1-bit data elements
        integer [3:0] out [31:0]; // 32 4-bit output elements

        data[5]; // referencing the 5th data element



Memories

Memories are simply an array of registers. The syntax is the same as above, we will discuss modelling RAM and ROM using memories in a later section.
        reg [15:0] mem16_1024 [1023:0]; // memory mem16_1024 is 1K of 16 bit elements
        mem16_1024[489]; // referencing element 489 of mem16_1024

It is always good practice to use informative names like mem16_1024 to help keep track of memories.
EXERCISE
Instantiated a 2k memory of 8 bit elements.
Answers




Tri-state

A tri-state driver is one which will output either HIGH, LOW or "nothing".
In some architectures, many different modules need to be able to put data onto (to drive) the same bus, at different times. Thus they all connect to the one common bus - but a set of control signals seek to ensure that only one of them is driving a signal at any one time.
In Verilog, this is modelled using different signal "strengths". There is a signal value: z, which is called "high-impedance". This basically means that a node is isolated, that is not driven. It is possible to assign this value to a net.
Normally if two values are simultaneously written to a net, the result is unknown: x; however, if a driven value is also assigned to the same net as a high-impedance value, the driven value will over-ride the z. This is the basis for the following tri-state driver:
        module triDriver(bus, drive, value);
           inout [3:0] bus;
           input       drive;
           input [3:0] value;

           assign #2 bus = (drive == 1) ? value : 4'bz;

        endmodule // triDriver

When the drive signal is high, the bus is driven to the data value, otherwise, this driver outputs only a high-impedance and hence can be over-ridden by any other driven value.

NOTE: the bus is a wire and is designated as an inout variable on the port declarations.
The following example shows the effect of several control combinations on three tri-state buffers:
        module myTest;
           wire [3:0] bus;
           reg          drive0, drive1, drive2;

           integer    i;

           triDriver mod1 (bus, drive0, i[3:0]);
           triDriver mod2 (bus, drive1, 4'hf);
           triDriver mod3 (bus, drive2, 4'h0);

           initial begin
              for (i = 0; i < 12; i = i + 1) begin
                 #5 {drive2, drive1, drive0} = i;
                 #5 $display ($time,"  %b %b %d", i[2:0], bus, bus);
              end
              $finish;
           end // initial begin

        endmodule // myTest

giving output:
                   10  000 zzzz  z
                   20  001 0001  1
                   30  010 1111 15
                   40  011 xx11  X
                   50  100 0000  0
                   60  101 0x0x  X
                   70  110 xxxx  x
                   80  111 xxxx  x
                   90  000 zzzz  z
                  100  001 1001  9
                  110  010 1111 15
                  120  011 1x11  X

沒有留言:

張貼留言