To understand RTL description for an arithmetic logic unit using arithmetic and logical operators.

RTL

// ALU RTL

 

module alu(a_in,b_in,command,en,d_out);

        

         input [7:0]a_in,b_in;

         input [3:0]command;

         input en;

         output [15:0]d_out;

 

   parameter       ADD  = 4'b0000, // Add two 8 bit numbers a and b.

                         INC  = 4'b0001, // Increment a by 1.

                         SUB  = 4'b0010, // Subtracts b from a.

                         DEC  = 4'b0011, // Decrement a by 1.

                         MUL  = 4'b0100, // Multiply 4 bit numbers a and b.

                         DIV  = 4'b0101, // Divide a by b.

                         SHL  = 4'b0110, // Shift a to left side by 1 bit.

                         SHR  = 4'b0111, // Shift a to right by 1 bit.

                       AND  = 4'b1000, // Logical AND operation.

                         OR   = 4'b1001, // Logical OR operation.

                         INV  = 4'b1010, // Logical Negation.

                         NAND = 4'b1011, // Bitwise NAND.

                         NOR  = 4'b1100, // Bitwise NOR.

                         XOR  = 4'b1101, // Bitwise XOR.

                         XNOR = 4'b1110, // Bitwise XNOR.

                         BUF  = 4'b1111; // BUF.

 

 

   reg  [15:0]out;

 

 

   always@(command)

      begin

       case(command)

            ADD : out=a_in + b_in;

                  INC : out=a_in + 1'b1;

                  SUB : out=a_in - b_in;

                  DEC : out=a_in - 1'b1;

                  MUL : out=a_in * b_in;

                  DIV : out=a_in / b_in;

                  SHL : out=a_in << b_in;

                  SHR : out=a_in >> b_in;

                  AND : out=a_in & b_in;

                  OR  : out=a_in | b_in;

                  INV : out=~(a_in);

                  NAND: out=~(a_in & b_in);

                  NOR : out=~(a_in | b_in);

                  XOR : out=a_in ^ b_in;

                  XNOR: out=a_in ~^ b_in;

                  BUF : out=a_in;

           

                  default out=1'b0;

       endcase

           

      end

           

   //Understand the tri-state logic for actual output

   assign d_out = (en) ? out : 16'hzzzz;

           

endmodule

 

 

Test Bench

//Alu test bench

 

module alu_tb();

   

 

   reg [7:0]a,b;

   reg [3:0]command;

   reg enable;

   wire [15:0]out;

           

  

   integer i,m,n;

 

 

   parameter ADD  = 4'b0000, // Add two 8 bit numbers a and b.

           INC  = 4'b0001, // Increment a by 1.

           SUB  = 4'b0010, // Subtracts b from a.

           DEC  = 4'b0011, // Decrement a by 1.

           MUL  = 4'b0100, // Multiply 4 bit numbers a and b.

           DIV  = 4'b0101, // Divide a by b.

           SHL  = 4'b0110, // Shift a to left side by 1 bit.

           SHR  = 4'b0111, // Shift a to right by 1 bit.

           AND  = 4'b1000, // Logical AND operation

           OR   = 4'b1001, // Logical OR operation

           INV  = 4'b1010, // Logical Negation

           NAND = 4'b1011, // Bitwise NAND

           NOR  = 4'b1100, // Bitwise NOR

           XOR  = 4'b1101, // Bitwise XOR

           XNOR = 4'b1110, // Bitwise XNOR

           BUF  = 4'b1111; // BUF

                                         

 

   reg [4*8:0]string_cmd;

 

  

   alu A (a,b,command,enable,out);

 

 

   task initialize;

      begin

       {a,b,command,enable} = 0;

      end

   endtask

 

 

   task en(input e);

      begin

       enable=e;

      end

   endtask

 

   task data(input [7:0]a_in,b_in);

      begin

       a=a_in;

       b=b_in;

      end

   endtask

 

   task comm (input [3:0]comm1);

      begin

       command=comm1;

      end

   endtask

 

   task delay();

      begin

       #10;

      end

   endtask

           

 

   always@(command)

      begin

         case(command)

          ADD   :  string_cmd = "ADD";

          INC   :  string_cmd = "INC";

          SUB   :  string_cmd = "SUB";

          DEC   :  string_cmd = "DEC";

          MUL   :  string_cmd = "MUL";

          DIV   :  string_cmd = "DIV";

          SHL   :  string_cmd = "SHL";

          SHR   :  string_cmd = "SHR";

          INV   :  string_cmd = "INV";

          AND   :  string_cmd = "AND";

          OR    :  string_cmd = "OR";

          NAND  :  string_cmd = "NAND";

          NOR   :  string_cmd = "NOR";

          XOR   :  string_cmd = "XOR";

          XNOR  :  string_cmd = "XNOR";

          BUF   :  string_cmd = "BUF";

       endcase

      end

                 

 

   initial

      begin

         initialize;

       en(1'b1);

       for (i=0;i<16;i=i+1)

          begin

             for (m=0;m<16;m=m+1)

                begin

                 data(i,m);

                      for (n=0;n<16;n=n+1)

                       begin

                            command=n;

                            delay;

                       end

                end

          end 

         en(0);

         data(8'd20,8'd10);

         comm(ADD);

         delay;

         en(1);

         data(8'd25,8'd17);

         comm(ADD);

         delay; 

         $finish;

      end

                 

  

   initial

      $monitor("Input enable=%b, a=%b, b=%b, command=%s, Output out=%b",enable,a,b,string_cmd,out);

                                               

  

endmodule


Post Your doubt in mail.👇👇👇

  E-Mail:-denilvaghasiya17@gmail.com