0% found this document useful (0 votes)
52 views15 pages

Kogge Stone

The document describes a 16-bit Kogge-Stone adder and a Booth multiplier implemented in Verilog, along with their respective test benches. It also outlines a 4-bit RISC processor that utilizes these components for arithmetic operations, including addition, subtraction, multiplication, and logical operations. The test benches demonstrate the functionality of the adder and multiplier with various test cases.

Uploaded by

Saketh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views15 pages

Kogge Stone

The document describes a 16-bit Kogge-Stone adder and a Booth multiplier implemented in Verilog, along with their respective test benches. It also outlines a 4-bit RISC processor that utilizes these components for arithmetic operations, including addition, subtraction, multiplication, and logical operations. The test benches demonstrate the functionality of the adder and multiplier with various test cases.

Uploaded by

Saketh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

KOGGE STONE :-

`timescale 1ns / 1ps

module kogge_stone_adder_16bit (
input [15:0] A,
input [15:0] B,
output [15:0] Sum,
output Cout
);
wire [15:0] G, P;
wire [15:0] G1, P1;
wire [15:0] G2, P2;
wire [15:0] G3, P3;
wire [15:0] G4, P4;
wire [15:0] C;

// Initial generate and propagate


assign G = A & B;
assign P = A ^ B;

genvar i;

// Stage 1
generate
for (i = 0; i < 16; i = i + 1) begin
if (i == 0) begin
assign G1[i] = G[i];
assign P1[i] = P[i];
end else begin
assign G1[i] = G[i] | (P[i] & G[i-1]);
assign P1[i] = P[i] & P[i-1];
end
end
endgenerate

// Stage 2
generate
for (i = 0; i < 16; i = i + 1) begin
if (i < 2) begin
assign G2[i] = G1[i];
assign P2[i] = P1[i];
end else begin
assign G2[i] = G1[i] | (P1[i] & G1[i-2]);
assign P2[i] = P1[i] & P1[i-2];
end
end
endgenerate

// Stage 3
generate
for (i = 0; i < 16; i = i + 1) begin
if (i < 4) begin
assign G3[i] = G2[i];
assign P3[i] = P2[i];
end else begin
assign G3[i] = G2[i] | (P2[i] & G2[i-4]);
assign P3[i] = P2[i] & P2[i-4];
end
end
endgenerate
// Stage 4
generate
for (i = 0; i < 16; i = i + 1) begin
if (i < 8) begin
assign G4[i] = G3[i];
assign P4[i] = P3[i];
end else begin
assign G4[i] = G3[i] | (P3[i] & G3[i-8]);
assign P4[i] = P3[i] & P3[i-8];
end
end
endgenerate

// Carry
assign C[0] = 1'b0;
generate
for (i = 1; i < 16; i = i + 1) begin
assign C[i] = G4[i-1];
end
endgenerate

assign Sum = P ^ C;
assign Cout = G4[15];
endmodule

TEST BENCH :-
module
kogge_stone_adder_tb;

reg [15:0] A, B;
wire [15:0] Sum;
wire Cout;

// Instantiate adder
kogge_stone_adder_16bit uut (
.A(A),
.B(B),
.Sum(Sum),
.Cout(Cout)
);

initial begin
// Test values
A = 16'h1234; // 4660
B = 16'h0F0F; // 3855

#10; // Wait 10 ns

$display("A = %h", A);


$display("B = %h", B);
$display("Sum = %h", Sum);
$display("Cout = %b", Cout);
$display("Expected Sum = %h", A + B);

$finish;
end

endmodule
BOOTH MULTIPLIER :-

`timescale 1ns / 1ps

module booth_multiplier_16bit (
input [15:0] multiplicand,
input [15:0] multiplier,
output [31:0] product
);
reg [31:0] prod_reg;
reg [15:0] mcand;
reg [16:0] mplier;
integer i;

always @* begin
prod_reg = 32'b0;
mcand = multiplicand;
mplier = {multiplier, 1'b0}; // Append 0 for LSB

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


case (mplier[1:0])
2'b01: prod_reg = prod_reg + (mcand << i);
2'b10: prod_reg = prod_reg - (mcand << i);
default: ; // Do nothing for 00 or 11
endcase
mplier = mplier >> 1;
end
end

assign product = prod_reg;


endmodule

TEST BENCH :-
module booth_multiplier_tb;
reg [15:0] A, B;
wire [31:0] P;

// Instantiate multiplier
booth_multiplier_16bit uut (
.multiplicand(A),
.multiplier(B),
.product(P)
);

initial begin
// Test case 1: Positive numbers
A = 16'h1234; // 4660
B = 16'h0F0F; // 3855
#10;
$display("Test Case 1:");
$display("A = %h (%0d)", A, A);
$display("B = %h (%0d)", B, B);
$display("Product = %h (%0d)", P, P);
$display("Expected= %h (%0d)", A * B, A * B);

// Test case 2: Negative multiplicand


A = 16'hFEDC; // -292 (two's complement)
B = 16'h0012; // 18
#10;
$display("\nTest Case 2:");
$display("A = %h (%0d)", A, $signed(A));
$display("B = %h (%0d)", B, $signed(B));
$display("Product = %h (%0d)", P, $signed(P));
$display("Expected= %h (%0d)", $signed(A) * $signed(B), $signed(A) * $signed(B));

// Test case 3: Negative multiplier


A = 16'h0012; // 18
B = 16'hFEDC; // -292
#10;
$display("\nTest Case 3:");
$display("A = %h (%0d)", A, $signed(A));
$display("B = %h (%0d)", B, $signed(B));
$display("Product = %h (%0d)", P, $signed(P));
$display("Expected= %h (%0d)", $signed(A) * $signed(B), $signed(A) * $signed(B));

// Test case 4: Both negative


A = 16'hFFFE; // -2
B = 16'hFFFF; // -1
#10;
$display("\nTest Case 4:");
$display("A = %h (%0d)", A, $signed(A));
$display("B = %h (%0d)", B, $signed(B));
$display("Product = %h (%0d)", P, $signed(P));
$display("Expected= %h (%0d)", $signed(A) * $signed(B), $signed(A) * $signed(B));

// Test case 5: Large numbers


A = 16'h7FFF; // 32767 (max positive)
B = 16'h7FFF; // 32767
#10;
$display("\nTest Case 5:");

$display("A = %h (%0d)", A, $signed(A));


$display("B = %h (%0d)", B, $signed(B));
$display("Product = %h (%0d)", P, $signed(P));
$display("Expected= %h (%0d)", $signed(A) * $signed(B), $signed(A) * $signed(B));

$finish;
end
endmodule

4 BIT RISC PROCESSOR :-


`timescale 1ns / 1ps

//===================
// Booth Multiplier //
//===================
module booth_multiplier_16bit (
input [15:0] multiplicand,
input [15:0] multiplier,
output [31:0] product
);
reg [31:0] prod_reg;
reg [15:0] mcand;
reg [16:0] mplier;
integer i;

always @* begin
prod_reg = 32'b0;
mcand = multiplicand;
mplier = {multiplier, 1'b0}; // Append 0 for LSB

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


case (mplier[1:0])
2'b01: prod_reg = prod_reg + (mcand << i);
2'b10: prod_reg = prod_reg - (mcand << i);
default: ; // Do nothing for 00 or 11
endcase
mplier = mplier >> 1;
end

end
assign product = prod_reg;
endmodule

//===================
// Kogge-Stone Adder //
//===================
module kogge_stone_adder_16bit (
input [15:0] A,
input [15:0] B,
output [15:0] Sum,
output Cout
);
wire [15:0] G, P;
wire [15:0] G1, P1;
wire [15:0] G2, P2;
wire [15:0] G3, P3;
wire [15:0] G4, P4;
wire [15:0] C;

// Initial generate and propagate


assign G = A & B;
assign P = A ^ B;

genvar i;

// Stage 1
generate
for (i = 0; i < 16; i = i + 1) begin
if (i == 0) begin
assign G1[i] = G[i];
assign P1[i] = P[i];
end else begin
assign G1[i] = G[i] | (P[i] & G[i-1]);
assign P1[i] = P[i] & P[i-1];
end
end
endgenerate

// Stage 2
generate
for (i = 0; i < 16; i = i + 1) begin
if (i < 2) begin
assign G2[i] = G1[i];
assign P2[i] = P1[i];
end else begin
assign G2[i] = G1[i] | (P1[i] & G1[i-2]);
assign P2[i] = P1[i] & P1[i-2];
end
end
endgenerate

// Stage 3
generate
for (i = 0; i < 16; i = i + 1) begin
if (i < 4) begin
assign G3[i] = G2[i];
assign P3[i] = P2[i];
end else begin
assign G3[i] = G2[i] | (P2[i] & G2[i-4]);
assign P3[i] = P2[i] & P2[i-4];
end
end
endgenerate

// Stage 4
generate
for (i = 0; i < 16; i = i + 1) begin
if (i < 8) begin
assign G4[i] = G3[i];
assign P4[i] = P3[i];
end else begin
assign G4[i] = G3[i] | (P3[i] & G3[i-8]);
assign P4[i] = P3[i] & P3[i-8];
end
end
endgenerate

// Carry
assign C[0] = 1'b0;
generate
for (i = 1; i < 16; i = i + 1) begin
assign C[i] = G4[i-1];
end
endgenerate

assign Sum = P ^ C;
assign Cout = G4[15];
endmodule

//===================
// 4-bit RISC Processor
//===================
module risc_processor_4bit (
input clk,
input reset,
input [7:0] instruction,
output reg [3:0] reg_a,
output reg [3:0] reg_b,
output reg [7:0] result
);

// Instruction format: [7:6] = opcode, [5:4] = dest, [3:0] = src/imm


localparam OP_ADD = 2'b00;
localparam OP_SUB = 2'b01;
localparam OP_MUL = 2'b10;
localparam OP_AND = 2'b11;
localparam OP_MOV = 2'b11; // Same as AND but differentiated by other bits

// Registers
reg [3:0] registers [0:3];

// ALU components
wire [7:0] mul_result;
wire [3:0] add_result, sub_result;
wire add_cout, sub_cout;

// Instantiate Booth multiplier


booth_multiplier_16bit multiplier (
.multiplicand({12'b0, registers[instruction[5:4]]}),
.multiplier({12'b0, registers[instruction[3:0]]}),
.product(mul_result)
);

// Instantiate Kogge-Stone adder for addition


kogge_stone_adder_16bit adder (
.A({12'b0, registers[instruction[5:4]]}),
.B({12'b0, registers[instruction[3:0]]}),
.Sum(add_result),
.Cout(add_cout)
);

// Instantiate Kogge-Stone adder for subtraction (A + ~B + 1)


kogge_stone_adder_16bit subtractor (
.A({12'b0, registers[instruction[5:4]]}),
.B({12'b0, ~registers[instruction[3:0]]}),
.Sum(sub_result),
.Cout(sub_cout)
);

// Main execution
always @(posedge clk or posedge reset) begin
if (reset) begin
// Reset all registers
registers[0] <= 4'b0;
registers[1] <= 4'b0;
registers[2] <= 4'b0;
registers[3] <= 4'b0;
reg_a <= 4'b0;
reg_b <= 4'b0;
result <= 8'b0;
end else begin
// Decode and execute instruction
case (instruction[7:6])
OP_ADD: begin
registers[instruction[5:4]] <= add_result;
result <= {4'b0, add_result};
end
OP_SUB: begin
registers[instruction[5:4]] <= sub_result;
result <= {4'b0, sub_result};
end
OP_MUL: begin
// Store lower 4 bits in destination register
registers[instruction[5:4]] <= mul_result[3:0];
result <= mul_result;
end
OP_AND: begin
if (instruction[5]) begin // MOV operation
// Move immediate value to register
registers[instruction[4]] <= instruction[3:0];
result <= {4'b0, instruction[3:0]};
end else begin // AND operation

registers[instruction[5:4]] <= registers[instruction[5:4]] & registers[instruction[3:0]];


result <= {4'b0, registers[instruction[5:4]] & registers[instruction[3:0]]};
end
end
endcase

// Update output registers


reg_a <= registers[0];
reg_b <= registers[1];
end
end
endmodule

TEST BENCH :-
module risc_processor_tb;

// Inputs
reg clk;
reg reset;
reg [7:0] instruction;

// Outputs
wire [3:0] reg_a;
wire [3:0] reg_b;
wire [7:0] result;

// Instantiate the Unit Under Test (UUT)


risc_processor_4bit uut (
.clk(clk),
.reset(reset),
.instruction(instruction),
.reg_a(reg_a),
.reg_b(reg_b),
.result(result)
);

// Clock generation
initial begin
clk = 0;
forever #5 clk = ~clk;
end

initial begin
// Initialize Inputs
reset = 1;
instruction = 0;

// Wait 10 ns for global reset to finish


#10;
reset = 0;

// Test sequence
$display("=== 4-bit RISC Processor Test ===");

// 1. MOV R0, 5 (Move 5 to register 0)


instruction = 8'b11_10_0101; // OP_MOV, R0, 5
#10;
$display("MOV R0, 5: R0 = %d, Result = %d", reg_a, result);
// 2. MOV R1, 3 (Move 3 to register 1)
instruction = 8'b11_11_0011; // OP_MOV, R1, 3
#10;
$display("MOV R1, 3: R1 = %d, Result = %d", reg_b, result);

// 3. ADD R2, R0, R1 (R2 = R0 + R1)


instruction = 8'b00_10_0001; // OP_ADD, R2, R0+R1
#10;
$display("ADD R2, R0, R1: R2 = %d, Result = %d", result[3:0], result);

// 4. SUB R3, R0, R1 (R3 = R0 - R1)


instruction = 8'b01_11_0001; // OP_SUB, R3, R0-R1
#10;
$display("SUB R3, R0, R1: R3 = %d, Result = %d", result[3:0], result);

// 5. MUL R0, R0, R1 (R0 = R0 * R1)


instruction = 8'b10_00_0001; // OP_MUL, R0, R0*R1
#10;
$display("MUL R0, R0, R1: R0 = %d, Result = %d", reg_a, result);

// 6. AND R1, R0, R1 (R1 = R0 & R1)


instruction = 8'b11_01_0000; // OP_AND, R1, R0&R1
#10;
$display("AND R1, R0, R1: R1 = %d, Result = %d", reg_b, result);

// End simulation
$finish;
end
endmodule
16 BIT RISC PROCESSOR :-

`timescale 1ns / 1ps

module booth_multiplier_16bit (
input signed [15:0] multiplicand,
input signed [15:0] multiplier,
output signed [31:0] product
);
reg [31:0] prod_reg;
reg [15:0] mcand;
reg [16:0] mplier;
integer i;

always @* begin
prod_reg = 0;
mcand = multiplicand;
mplier = {multiplier, 1'b0};
for (i = 0; i < 16; i = i + 1) begin
case (mplier[1:0])
2'b01: prod_reg = prod_reg + (mcand << i);
2'b10: prod_reg = prod_reg - (mcand << i);
default: ;
endcase
mplier = mplier >> 1;
end
end
assign product = prod_reg;
endmodule

module kogge_stone_16bit (
input [15:0] A,
input [15:0] B,
input op, // 0=ADD, 1=SUB
output [15:0] Sum,
output Cout
);
wire [15:0] B_adj = op ? ~B : B;
wire [15:0] G = A & B_adj;
wire [15:0] P = A ^ B_adj;

// Carry computation (4-stage)


wire [15:0] G1, P1, G2, P2, G3, P3, G4, P4;

// Stage 1
assign G1[0] = G[0];
assign P1[0] = P[0];
genvar i;
generate
for (i = 1; i < 16; i = i + 1) begin
assign G1[i] = G[i] | (P[i] & G[i-1]);
assign P1[i] = P[i] & P[i-1];
end
endgenerate

// Stage 2
assign G2[1:0] = G1[1:0];
assign P2[1:0] = P1[1:0];
generate
for (i = 2; i < 16; i = i + 1) begin
assign G2[i] = G1[i] | (P1[i] & G1[i-2]);
assign P2[i] = P1[i] & P1[i-2];
end
endgenerate

// Stage 3
assign G3[3:0] = G2[3:0];
assign P3[3:0] = P2[3:0];
generate
for (i = 4; i < 16; i = i + 1) begin
assign G3[i] = G2[i] | (P2[i] & G2[i-4]);
assign P3[i] = P2[i] & P2[i-4];
end
endgenerate

// Stage 4
assign G4[7:0] = G3[7:0];
assign P4[7:0] = P3[7:0];
generate
for (i = 8; i < 16; i = i + 1) begin
assign G4[i] = G3[i] | (P3[i] & G3[i-8]);
assign P4[i] = P3[i] & P3[i-8];
end
endgenerate

// Final carry
wire [15:0] C = {G4[14:0], op};
assign Sum = P ^ C;
assign Cout = G4[15] | (P4[15] & G3[7]);
endmodule

module risc_processor_16bit (
input clk,
input reset,
input [31:0] instruction,
output [15:0] reg_a,
output [15:0] reg_b,
output [31:0] result
);
// Instruction format
localparam OP_ADD = 2'b00;
localparam OP_SUB = 2'b01;
localparam OP_MUL = 2'b10;
localparam OP_AND = 2'b11;
localparam OP_MOV = 2'b11;

reg [15:0] registers [0:15];

// ALU connections
wire [31:0] mul_result;
wire [15:0] alu_result;
wire cout;

booth_multiplier_16bit mul_unit (
.multiplicand(registers[instruction[25:21]]),
.multiplier(registers[instruction[20:16]]),
.product(mul_result)
);

kogge_stone_16bit alu_unit (
.A(registers[instruction[25:21]]),
.B(registers[instruction[20:16]]),
.op(instruction[26]),
.Sum(alu_result),
.Cout(cout)
);

// Register update
always @(posedge clk or posedge reset) begin
if (reset) begin
for (integer i = 0; i < 16; i = i + 1)
registers[i] <= 0;
end else begin
case (instruction[31:30])
OP_ADD, OP_SUB: registers[instruction[29:25]] <= alu_result;
OP_MUL: registers[instruction[29:25]] <= mul_result[15:0];
OP_AND: registers[instruction[29:25]] <= registers[instruction[25:21]] & registers[instruction[20:16]];
OP_MOV: if (instruction[16]) registers[instruction[15:11]] <= instruction[10:0];
endcase
end
end

assign reg_a = registers[0];


assign reg_b = registers[1];
assign result = (instruction[31:30] == OP_MUL) ? mul_result : {16'b0, alu_result};
endmodule

TEST BENCH :-

`timescale 1ns / 1ps

module risc_processor_16bit_tb;
reg clk;
reg reset;
reg [31:0] instruction;
wire [15:0] reg_a;
wire [15:0] reg_b;
wire [31:0] result;

risc_processor_16bit uut (
.clk(clk),
.reset(reset),
.instruction(instruction),
.reg_a(reg_a),
.reg_b(reg_b),
.result(result)
);

// Clock generation (100MHz)


initial begin
clk = 0;
forever #5 clk = ~clk;
end

initial begin
// Initialize and reset
reset = 1;
instruction = 0;
#100 reset = 0;
#10;

$display("\n=== 16-bit RISC Processor Test ===");


$display("Time\tInstruction\t\tR0\t\tR1\t\tResult");
$display("----------------------------------------------------------");

// Test case 1: MOV R0, 500 (0x01F4)


instruction = 32'b11_1_00000_00000_000000111110100;
#100;
$display("%0tns\tMOV R0,500\t\t%h\t%h\t%h", $time, reg_a, reg_b, result);

// Test case 2: MOV R1, 300 (0x012C)


instruction = 32'b11_1_00001_00000_000000100101100;
#100;
$display("%0tns\tMOV R1,300\t\t%h\t%h\t%h", $time, reg_a, reg_b, result);

// Test case 3: ADD R2, R0, R1 (500 + 300 = 800)


instruction = 32'b00_0_00010_00000_00001_00000000000;
#100;
$display("%0tns\tADD R2,0+1\t\t%h\t%h\t%h", $time, reg_a, reg_b, result);

// Test case 4: SUB R3, R0, R1 (500 - 300 = 200)


instruction = 32'b01_1_00011_00000_00001_00000000000;
#100;
$display("%0tns\tSUB R3,0-1\t\t%h\t%h\t%h", $time, reg_a, reg_b, result);

// Test case 5: MUL R4, R0, R1 (500 * 300 = 150000)


instruction = 32'b10_0_00100_00000_00001_00000000000;
#100;
$display("%0tns\tMUL R4,0*1\t\t%h\t%h\t%h", $time, reg_a, reg_b, result);

$finish;
end

// Monitor all register changes


initial begin
$monitor("At %t: R0=%h R1=%h R2=%h R3=%h R4=%h",
$time, [Link][0], [Link][1],
[Link][2], [Link][3], [Link][4]);
end
endmodule

You might also like