Verilog, help with an ALU for a newbie

Thread Starter

toffee_pie

Joined Oct 31, 2009
235
hi all,

I am trying to implement a 16 bit ALU, and thus far have this much written.

I want to get some of the basic arithmitic compiling successfully before I move onto more difficuklt taskks.

I am having problems getting my head around how I deal with the 2s compliment signed output, 16 bits wide.

I need to have an extra bit in the output? do I need extra regs for the bit ?

this is what I have done so far.



.

/ VERILOG CODE


// 'timescale 10ns

module ALU (c,resetb,clk,a,b,op, ov);


output signed [s + 15:0] c; // 2's compliment signed 16 bit output word

output ov; // The result of addition or subtraction is
// supposed to fit
// within the significant bits used to represent the numbers.
// If ‘n’ bits are used to represent signed numbers
// in 2’s complement
// scheme, then the result must be in the range
// –2n-1 to 2n-1-1.
// If the result does not fit in this range, then an arithmetic
// overflow has occurred, this used for signed operations.


input clk,resetb; // system clock @ 100Mhz , synchronous
// system reset active low
input [2:0] op; // assigns ALU one of its 8 operand Instruction
input [15:0] a,b; // unsigned 16 bit input operands to ALU

// internal nodes

wire [15:0] a,b;
reg signed [15:0] c; // output reg
reg signed overflow;


parameter WIDTH = 'd16;

parameter ADD_AB = 3'b000; // addition -> c = a + b
parameter SUB_AB = 3'b001; // subtraction -> c = a - b
parameter MUL_AB = 3'b010; // multiplication -> c = a * b
parameter AND_AB = 3'b011; // and -> c = a & b
parameter OR_AB = 3'b100; // or -> c = a | b
parameter XOR_AB = 3'b101; // xor -> c = a ^ b
parameter SHIFT_LEFT_A = 3'b110; // shift left -> c = a >> 1
parameter SHIFT_RIGHT_A = 3'b111; // shift right -> c = b >> 1



always @ (a or b or op) begin

// Lets do Arithmetic operations

begin

if (op[2:1] == 2'b00) begin

case (op[2:0])

3'b000:c = a + b ; // addition
3'b001:c = a - b ; // subtraction
//3'b010:c = a * b ; //
default:c = 16'bx;

endcase

//overflow = c[15]^c[14];

end


// Lets do Logical operations

else if (op[2:1] == 2'b01) begin

case (op[2:0])

3'b011:c = a & b ; // logical and
3'b100:c = a | b ; // logical or
3'b111:c = a ^ b; // logical exor
default:c = 16'bx;


endcase

endmodule
 

Ursa Major

Joined Jul 8, 2010
1
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
module tb_alu_v;
// Inputs
reg rstb;
reg clk;
reg [15:0] a;
reg [15:0] b;
reg [7:0] op;
// Outputs
wire [15:0] c;
wire ov;

parameter ADD_AB = 8'b00000001; // addition -> c = a + b
parameter SUB_AB = 8'b00000010; // subtraction -> c = a - b
parameter MUL_AB = 8'b00000100; // multiplication -> c = a * b
parameter AND_AB = 8'b00001000; // and -> c = a & b
parameter OR_AB = 8'b00010000; // or -> c = a | b
parameter XOR_AB = 8'b00100000; // xor -> c = a ^ b
parameter SHIFT_LEFT_A = 8'b01000000; // shift left -> c = a >> 1
parameter SHIFT_RIGHT_A = 8'b10000000; // shift right -> c = b >> 1
// Instantiate the Unit Under Test (UUT)
alu uut (
.c(c),
.rstb(rstb),
.clk(clk),
.a(a),
.b(b),
.op(op),
.ov(ov)
);
initial begin
// Initialize Inputs
rstb = 0;
clk = 0;
a = 0;
b = 0;
op = 0;
// Wait 100 ns for global reset to finish
#100;

// Add stimulus here
#5
a = 8;
b = 3;
op = ADD_AB;
#5
a = 8;
b = 3;
op = SUB_AB;
#5
a = 8;
b = 3;
op = MUL_AB;
#5
a = 8;
op = SHIFT_LEFT_A;
#5
a = 8;
op = SHIFT_RIGHT_A;
#5
a = 8;
b = 3;
op = XOR_AB;
#5
a = 8;
b = 3;
op = AND_AB;
#5
a = 8;
b = 3;
op = OR_AB;

end

always
#2 clk = ~clk;

endmodule

/////////////////////////////////////////////////
`timescale 1ns / 1ps
//****************************************************
// 16 bit arithmetic logic unit
//
// parameter:
// CLK.......system clock
// RESET.....System Reset
// A.........A input
// B.........B input
// OP........operation to perform
// Y.........8 bit result output
// C.........carry status
// OV.........overflow status
// N.........sign status
// Z.........zero status
//
//****************************************************
module alu(c,rstb,clk,a,b,op,ov);
parameter s = 0; // dummy variable
output signed[s+15:0] c;
input rstb,clk; // system clock @ 100Mhz , synchronous
// system reset active low
input [15:0]a,b; // unsigned 16 bit input operands to ALU
//input [2:0]op;
input [7:0]op;

output ov; // The result of addition or subtraction is supposed to fit
// within the significant bits used to represent the numbers.
// If ‘n’ bits are used to represent signed numbers
// in 2’s complement
// scheme, then the result must be in the range
// –2n-1 to 2n-1-1.
// If the result does not fit in this range, then an arithmetic
// overflow has occurred, this used for signed operations.

//input clk, resetb; input [2:0] op; // assigns ALU one of its 8 operand Instruction
// internal nodes
wire [15:0] a,b;
reg signed [15:0] c; // output reg
reg signed overflow;

parameter WIDTH = 'd16;
/*
parameter ADD_AB = 3'b000; // addition -> c = a + b
parameter SUB_AB = 3'b001; // subtraction -> c = a - b
parameter MUL_AB = 3'b010; // multiplication -> c = a * b
parameter AND_AB = 3'b011; // and -> c = a & b
parameter OR_AB = 3'b100; // or -> c = a | b
parameter XOR_AB = 3'b101; // xor -> c = a ^ b
parameter SHIFT_LEFT_A = 3'b110; // shift left -> c = a >> 1
parameter SHIFT_RIGHT_A = 3'b111; // shift right -> c = b >> 1
*/
parameter ADD_AB = 8'b00000001; // addition -> c = a + b
parameter SUB_AB = 8'b00000010; // subtraction -> c = a - b
parameter MUL_AB = 8'b00000100; // multiplication -> c = a * b
parameter AND_AB = 8'b00001000; // and -> c = a & b
parameter OR_AB = 8'b00010000; // or -> c = a | b
parameter XOR_AB = 8'b00100000; // xor -> c = a ^ b
parameter SHIFT_LEFT_A = 8'b01000000; // shift left -> c = a >> 1
parameter SHIFT_RIGHT_A = 8'b10000000; // shift right -> c = b >> 1
/*
always @ (a or b or op)
// Lets do Arithmetic operations
begin
if (op[2:1] == 2'b00)
begin
case (op[2:0])
3'b000:c = a + b ; // addition
3'b001:c = a - b ; // subtraction
3'b010:c = a * b ; //
default:c = 16'bx;
endcase
//overflow = c[15]^c[14];
end
// Lets do Logical operations
else if (op[2:1] == 2'b01)
begin
case (op[2:0])
3'b011:c = a & b ; // logical and
3'b100:c = a | b ; // logical or
3'b111:c = a ^ b; // logical exor
default:c = 16'bx;
endcase
end
end
*/
always @ (a or b or op)
// Lets do Arithmetic operations
begin
case (op)
ADD_AB :
begin
$display("ADD");
c = a + b ; // addition
end
SUB_AB :
begin
$display("SUBTRACT");
c = a - b ; // subtraction
end
MUL_AB :
begin
$display("MUL");
c = a * b ; //
end
AND_AB :
begin
$display("AND");
c = a & b ; // logical and
end
OR_AB :c = a | b; // logical or
XOR_AB :c = a ^ b; // logical exor
SHIFT_LEFT_A :
begin
$display("SHL");
c = a >> 1; // shift left -> c = a >> 1
end
SHIFT_RIGHT_A :
begin
$display("SHR");
c = a << 1 ;
end
default:c = 16'bx;
endcase
end

endmodule
 
Top