Looking for a reliable Verilog implementation for an 8-bit multiplier? Whether you are working on an FPGA project or solving a Hardware Description Language (HDL) assignment, there are two main ways to approach this: the "Hacker" way (behavioral) and the "Engineer" way (structural).
Below is the code for both approaches and a testbench to verify them.
Takes two inputs ($A, B$) and outputs a Sum and a Carry.
/////////////////////////////////////////////////////////////////////////////// // 8-bit Unsigned Multiplier // Implementation: Combinational (Array Multiplier) // Inputs: a[7:0], b[7:0] - 8-bit unsigned numbers // Output: product[15:0] - 16-bit product ///////////////////////////////////////////////////////////////////////////////module eight_bit_multiplier ( input wire [7:0] a, // Multiplicand input wire [7:0] b, // Multiplier output wire [15:0] product // Product output );
// Internal wires for partial products wire [7:0] pp [0:7]; // 8 partial products (each 8 bits) wire [15:0] sum_stage1, sum_stage2, sum_stage3; // Generate partial products using AND gates genvar i, j; generate for (i = 0; i < 8; i = i + 1) begin for (j = 0; j < 8; j = j + 1) begin assign pp[i][j] = a[j] & b[i]; end end endgenerate // Adder tree for summing partial products wire [7:0] carry [0:6]; wire [7:0] sum [0:6]; // Stage 1: Add first two partial products ripple_carry_adder #(.WIDTH(8)) adder01 ( .a(pp[0]), .b(pp[1] << 1), .cin(1'b0), .sum(sum[0]), .cout(carry[0][0]) ); // Stage 2: Add with third partial product ripple_carry_adder #(.WIDTH(9)) adder02 ( .a(carry[0][0], sum[0]), .b(pp[2] << 2), .cin(1'b0), .sum(sum[1][7:0], product[0]), .cout(carry[1][0]) ); // Stage 3: Add with fourth partial product ripple_carry_adder #(.WIDTH(10)) adder03 ( .a(carry[1][0], sum[1][7:0]), .b(pp[3] << 3), .cin(1'b0), .sum(sum[2][7:0], product[1:0]), .cout(carry[2][0]) ); // Stage 4: Add with fifth partial product ripple_carry_adder #(.WIDTH(11)) adder04 ( .a(carry[2][0], sum[2][7:0]), .b(pp[4] << 4), .cin(1'b0), .sum(sum[3][7:0], product[3:0]), .cout(carry[3][0]) ); // Stage 5: Add with sixth partial product ripple_carry_adder #(.WIDTH(12)) adder05 ( .a(carry[3][0], sum[3][7:0]), .b(pp[5] << 5), .cin(1'b0), .sum(sum[4][7:0], product[7:4]), .cout(carry[4][0]) ); // Stage 6: Add with seventh partial product ripple_carry_adder #(.WIDTH(13)) adder06 ( .a(carry[4][0], sum[4][7:0]), .b(pp[6] << 6), .cin(1'b0), .sum(sum[5][7:0], product[11:8]), .cout(carry[5][0]) ); // Stage 7: Add with eighth partial product ripple_carry_adder #(.WIDTH(14)) adder07 ( .a(carry[5][0], sum[5][7:0]), .b(pp[7] << 7), .cin(1'b0), .sum(product[15:8], product[7:0]) );endmodule
/////////////////////////////////////////////////////////////////////////////// // Parameterized Ripple Carry Adder ///////////////////////////////////////////////////////////////////////////////
module ripple_carry_adder #( parameter WIDTH = 8 )( input wire [WIDTH-1:0] a, input wire [WIDTH-1:0] b, input wire cin, output wire [WIDTH-1:0] sum, output wire cout );
wire [WIDTH:0] carry; assign carry[0] = cin; genvar i; generate for (i = 0; i < WIDTH; i = i + 1) begin full_adder fa_inst ( .a(a[i]), .b(b[i]), .cin(carry[i]), .sum(sum[i]), .cout(carry[i+1]) ); end endgenerate assign cout = carry[WIDTH];endmodule
/////////////////////////////////////////////////////////////////////////////// // Full Adder /////////////////////////////////////////////////////////////////////////////// 8bit multiplier verilog code github
module full_adder ( input wire a, input wire b, input wire cin, output wire sum, output wire cout );
assign sum = a ^ b ^ cin; assign cout = (a & b) | (b & cin) | (a & cin);
endmodule
To write clean, "GitHub-worthy" Verilog, we should use a Structural Modeling approach. This means we build small sub-modules and connect them together, much like connecting chips on a breadboard. 📝 Post Title: 🖥️ How to Implement an
We need two basic building blocks:
Here is a synthesizable sequential 8-bit multiplier that you can directly copy into your project. It consumes minimal logic and is perfect for FPGA boards like the Basys 3 or ICEstick.
// Filename: mul8_sequential.v // Description: 8-bit sequential multiplier using shift-add algorithm module mul8_sequential ( input clk, input rst_n, input start, input [7:0] multiplicand, input [7:0] multiplier, output reg [15:0] product, output reg done );reg [7:0] A, Q; // Multiplicand, Multiplier reg [15:0] P; // Product register (16 bits) reg [3:0] bit_count; // Counter for 8 iterations always @(posedge clk or negedge rst_n) begin if (!rst_n) begin P <= 0; product <= 0; done <= 0; bit_count <= 0; end else if (start) begin A <= multiplicand; Q <= multiplier; P <= 16'b0; bit_count <= 0; done <= 0; end else if (bit_count < 8) begin if (Q[0] == 1) begin P <= P + 8'b0, A; // Add multiplicand to upper bits end // Shift right arithmetic (P, Q) as one combined register P, Q <= 1'b0, P[15:1], Q[7:1]; bit_count <= bit_count + 1; end else begin product <= P; done <= 1'b1; end end
endmodule
#delay inside RTL may simulate fine but fail synthesis. Keep delays only in testbenches.# 8-bit Multiplier in Verilog