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