Answers

Introduction

Gate Types

a) XNOR

        -------------------
        | in1 | in2 | out |
        -------------------
        |  0  |  0  |  1  |
        |  0  |  1  |  0  |
        |  1  |  0  |  0  |
        |  1  |  1  |  1  |
        -------------------

b) The example can be cut and pasted to a file then compiled, the value of a is 1.

DataTypes

Vectors

a) reg [7:0] address;
b) address[7:4] = 4'b1010;

Arrays and Memories

reg [7:0] mem8_2048 [2047:0];

Operators

Logical

a) 0 (false)
b) 0 (false)
c) 1 (true)
d) 1 (true)
e) 1 (true)

Relational

a) The while loop will execute 5 times.

Equality

a) 1 (true)
b) 1 (true)
c) x (unknown)
d) 1 (true)

Bitwise

a) 10
b) 1000
c) xxx1

Reduction

a) 0 (false)
b) 1 (true)
c) 1 (true)

shift
a) 1
b) 0

concatination and replication
0001111101

Modules

Stimulus

b)

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

           always @(posedge clock)
              if (reset == 1)
              q = 0;
              else if (enable == 1)
              q = data;

        endmodule // e_ff


Ports

Connection Rules

b) Here is the module for a toggle flip-flop, The stimulus is also given. Try running them.

        module d_ff( q, d, reset, clock);
           output q;
           input  d, reset, clock;
           reg      q;

           always @(posedge clock)
              if (reset == 1)
              q = #1 0;
              else
              q = #1 d;

        endmodule // d_ff

        module e_ff(q, d, enable, reset, clock);
           output q;
           input  d, enable, reset, clock;
           wire     inD;

           assign inD = (enable == 1) ? d : q;
           d_ff dff0(q, inD, reset, clock);

        endmodule // e_ff

        module t_ff(q, toggle, reset, clock);
           output q;
           input  toggle, reset, clock;

           e_ff eff0 (q, ~q, toggle, reset, clock);

        endmodule // t_ff

        module stimulus;
           reg    toggle, reset, clock;
           wire   out;

           t_ff tff0 (q, toggle, reset, clock);

           initial begin
              clock = 0;
              forever #5 clock = ~clock;
           end // initial begin

           initial forever #10 $display($time,"  %b", q);

           initial begin
              reset = 0;
              toggle = 0;

              #20 reset = 1;
              #20 reset = 0;
              #20 toggle = 1;
              #50 toggle = 0;
              #20 reset = 1;
              #30 $finish;
           end // initial begin

        endmodule // stimulus

Basic Bocks

Initial

Initial blocks with just one statement do not need the keywords begin and end. Only multiple statements need to be grouped.

Always

        module wave;
          reg clock;
          reg [1:0] alpha;

        initial begin
          $monitor($time, " - %b %d", clock, alpha);
          clock = 1'b0;
          alpha = 2'b00;
        end

        always #10 clock = ~clock;

        always begin
          #10 alpha = 1;
          #5  alpha = 2;
          #10 alpha = 0;
        end

        initial #70 $finish;

        endmodule

Timing

Delay-Based

The answers can be obtained by running the following code along with the module given in the question.

        module stimulusdelay;
           wire [3:0] a, b, c;

           testdelay delay(a, b, c);

           initial begin
              #15 $display ($time," a=%d", a);
              #2 $display ($time," b=%d", b);
              #1 $display ($time," c=%d", c);
              #12 $display ($time," a=%d", a);
           end

        endmodule

Large Worked Example

Counter


        always @(posedge clock)
         ...
          if (updown)       // if updown==1 we want to increment the counter
              q = q + 3;   // else we want to decrement
          else
              q = q - 3;

        endmodule

Branches

If

        module muxstimulus;
          reg in1, in2, in3, in4;
          reg cntrl1, cntrl2;
          wire out;

        multiplexor4_1 mux4_1(out, in1, in2, in3, in4, cntrl1, cntrl2);

        initial begin
          in1 = 1; in2 = 0; in3 = 1; in4 = 0;
          $display("Initial arbirtary values");
          #0 $display($time," input1 = %b, input2 = %b, input3 = %b, input4 = %b",
                                in1, in2, in3, in4);

         cntrl1 = 0; cntrl2 = 0;
         #10 $display($time," cntrl1=%b, cntrl2=%b, output is %b",
                                cntrl1, cntrl2, out);

         cntrl1 = 0; cntrl2 = 1;
         #10 $display($time," cntrl1=%b, cntrl2=%b output is %b",
                                cntrl1, cntrl2, out);

         cntrl1 = 1; cntrl2 = 0;
         #10 $display($time," cntrl1=%b, cntrl2=%b output is %b",
                                cntrl1, cntrl2, out);

         cntrl1 = 1; cntrl2 = 1;
         #10 $display($time," cntrl1=%b, cntrl2=%b output is %b",
                                cntrl1, cntrl2, out);

        end

        endmodule

Case

        zz01x: Matched OK
        xxxzx: Did not match
        010xz: Matched OK
        zzz0z: Matched OK

Conditional Operator

        module multiplexor4_1(out, in1, in2, in3, in4, cntrl1, cntrl2);
          output out;
          input in1, in2, in3, in4, cntrl1, cntrl2;

        assign out = cntrl1 ? (cntrl2 ? in4 : in2) : (cntrl2 ? in3 : in1);

        endmodule

Loops

While

5 times

For

        module initmem;
           reg [15:0] mem16_256 [255:0];
           reg [15:0] address;
           integer    index;

           initial begin
              address = 24;
              for(index = 0; index < 256; index = index + 1) begin
              mem16_256 [index] = address;
              address = address + 1;
              $display("%d", mem16_256[index]);
              end
           end

        endmodule // initmem

Repeat

A for loop would be favoured over a repeat loop in any situation where we are using the loop index in the loop as in the initialisation exercise in the last section. With a repeat loop we loop strictly a preset number of times but this is more flexible in a for loop, for example

        for(i = 0; i < 256; i = i + 1);
          if some_event
              // do something and
              i = i + 10;      // speed up the loop
          else if another_event
                 // do something and
                 i = i - 10;         // slow down the loop
          else if yet_another_event
                 // do someting and
                 i = 256;           // end the loop altogether

Forever

The forever loop given will start executing at time 5 units, it will flip the clock endlessly and with out a break until the end of the simulation not allowing anything else to happen.

Extras

Memories

        module readwriteMem;

        integer handle1, handle2, channelsA, index;
        reg [7:0] memory [7:0];

        initial begin
          handle1 = $fopen("mem.dat");
          $fwrite(handle1, "@00300000011000001000000010100000110");

          handle2 = $fopen("memory.out");
          channelsA = handle2 | 1;
          $fwrite(channelsA,"@0030);

          $readmemb("mem.dat", memory);
          for(index = 0; index < 8; index = index + 1)
            $fdisplayb(channelsA, memory[index]);

          $fclose(handle1);
          $fclose(handle2);
        end
        endmodule