Sep 27, 2016

Verilog Code for 8-bit ALU

/*
 *inst[3:0]  =  4'h0 => reserved
 *inst[3:0]  =  4'h1 => Addition  
 *inst[3:0]  =  4'h2 => Substraction
 *inst[3:0]  =  4'h3 => Multiply  
 *inst[3:0]  =  4'h4 => division  
 *inst[3:0]  =  4'h5 => shift right
 *inst[3:0]  =  4'h6 => shift left
 *inst[3:0]  =  4'h7 => logical AND
 *inst[3:0]  =  4'h8 => logical OR
 *inst[3:0]  =  4'h9 => Bitwise AND
 *inst[3:0]  =  4'hA => Bitwise OR
 *inst[3:0]  =  4'hB => XOR        
 *inst[3:0]  =  4'hC => Reserved  
 *inst[3:0]  =  4'hD => Reserved  
 *inst[3:0]  =  4'hE => Reserved  
 *inst[3:0]  =  4'hF => Reserved  
 *
 *
 */


`timescale 1ns/100ps

module ALU_8bit (
      input [3:0] inst ,
      input [7:0] op_a,
      input [7:0] op_b,
      output [7:0] op_out
   );


reg [8:0] op_out_int;

assign op_out = op_out_int[7:0];

always @(*) begin
 case (inst)
   4'h1 :  //
       op_out_int = op_a + op_b ;  // can instantiate a adder here
   4'h2 :  //
       op_out_int = op_a - op_b ;
   4'h3 :  //
       op_out_int = op_a * op_b ;
   4'h4 :  //
       op_out_int = op_a / op_b ;
   4'h5 :  //
       op_out_int = op_a >> 1  ;
   4'h6 :  //
       op_out_int = op_a << 1 ;
   4'h7 :  //
       op_out_int = op_a && op_b ;
   4'h8 :  //
       op_out_int = op_a || op_b ;
   4'h9 :  //
       op_out_int = op_a & op_b ;
   4'hA :  //
       op_out_int = op_a | op_b ;
   4'hB :  //
       op_out_int = op_a ^ op_b ;
   default : op_out_int = 'b0;
 endcase
end


endmodule

module tb ;

wire [7:0] ct_a;
wire [7:0] ct_b;
reg [3:0] opcode = 0 ;

integer count =0;

reg clk =0;

always #5 clk = ~clk;

always @(posedge clk)
  count = count + 'h2928_4001;

always @(posedge clk)
  opcode = opcode +1;

assign ct_a = count[9:2];

assign ct_b = count[14:7];



wire [7:0] opout;

ALU_8bit u_dut (  .inst(opcode),
                  .op_a(ct_a),
                  .op_b(ct_b),
                  .op_out(opout) );


always @(*) begin
 #1;
 if (opcode == 1)
   if( opout != (ct_a + ct_b))
     $display("ERROR , Addition not working ");
   else
     $display("Addition : %h + %h = %h" , ct_a, ct_b, opout);
 else if (opcode == 2)
   if( opout != (ct_a - ct_b) )
     $display("ERROR , Subs not working ");
   else
     $display("Substraction : %h - %h = %h" , ct_a, ct_b, opout);
 else if (opcode == 3)
   if( opout != (ct_a * ct_b) )
     $display("ERROR , Multiply not working ");
   else
     $display("Multiply : %h * %h = %h" , ct_a, ct_b, opout);

 else if (opcode == 4)
   if( opout != (ct_a / ct_b) )
     $display("ERROR , division not working ");
   else
     $display("Division : %h / %h = %h" , ct_a, ct_b, opout);

 else if (opcode == 5)
   if( opout != (ct_a >> 1 ) )
     $display("ERROR ,  right shift not working ");
   else
     $display("Right Shift : %h >> 1  = %h" , ct_a, opout);

 else if (opcode == 6)
   if( opout != (ct_a <<  1) )
     $display("ERROR , Left shift not working ");
   else
     $display("Left Shift : %h >> 1 = %h" , ct_a, opout);

 else if (opcode == 7)
   if( opout != (ct_a && ct_b))
     $display("ERROR ,Logical AND not working ");
   else
     $display("Logical AND : %h  && %h = %h" , ct_a, ct_b, opout);

 else if (opcode == 8)
   if( opout != (ct_a || ct_b) )
     $display("ERROR , Logical OR not working ");
   else
     $display("Logical OR : %h || %h = %h" , ct_a, ct_b, opout);

 else if (opcode == 9)
   if( opout != (ct_a & ct_b) )
     $display("ERROR , Bit Wise AND not working ");
   else
     $display("Bit Wise AND : %h & %h = %h" , ct_a, ct_b, opout);

 else if (opcode == 10)
   if( opout != (ct_a | ct_b) )
     $display("ERROR , Bit wise OR not working ");
   else
     $display("Bit Wise OR : %h || %h = %h" , ct_a, ct_b, opout);
 else
  $display("Reserved");

end


`ifdef WAVE
 initial begin
   $recordfile("test.trn");
   $recordvars();
   #1000;
   $finish;
 end
`endif
endmodule