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 2s 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
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 2s 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