# Creating a verilog code for 4-bit multiplier using lookup table

I am having trouble creating a verilog code for a 4-bit multipler using a lookup table. I am still trying to grasp the concept of a lookup table. If anyone could help me it would be greatly appreciated.I am just lost.

• Can you show us what you've tried or where you are so far? – Greg d'Eon Apr 9 '15 at 16:02
• module TBM(a,b,p); input [1:0]a,b; output [3:0]p; assign p[3] = a[1] & a[0]& b[1] & b[0]; assign p[2] = (a[1] & ~a[0] & b[1]) | (a[0]& b[1] & ~b[0]); assign p[1] = (a[1] & ~b[1] & b[0]) | (a[1] & ~a[0] & b[0]) | (~a[1] & a[0] & b[1]) | (a[0]& b[1] & ~b[0]); assign p[0] = a[0] & b[0]; endmodule – supasport13 Apr 9 '15 at 21:28
• I was only able to come up with a two bit multiplier but I don't feel like it satisfies using a lookup table. I am stuck transitioning to a 4 bit multiplier. – supasport13 Apr 9 '15 at 21:31
• for the four bit I am stuck at the very beginning – supasport13 Apr 9 '15 at 21:32
• module TBM(a,b,p); input[3:0]a,b; output[7,0]p; – supasport13 Apr 9 '15 at 21:32

## 3 Answers

There are two different ways the term "lookup table" are used in FPGA design that might be confusing you.

First, the main building block of combinatorial logic in an FPGA is called a lookup table, but usually abbreviated as LUT. This is just a small RAM element that takes 4 or 5 or 6 inputs (depending on which type of FPGA you have) and uses that to select a bit from memory to be output.

Second, more generally a lookup table is just logic that takes inputs and has a defined output for every combination of those inputs, just like a logic table you'd use for paper-and-pencil design. Since a hardware LUT in an FPGA isn't big enough to implement a 4-bit adder, this is probably the kind of lookup table that's meant in your problem.

In Verilog, a lookup table is usually implemented with a case statement. For example, to implement a 2-input XOR gate with a lookup table you might write,

reg out;
wire [1:0] in;
always @(in)
case(in)
2'b00 : out = 0;
2'b01 : out = 1;
2'b10 : out = 1;
2'b11 : out = 0;
endcase


For your 4-input multiplier, you will probably want to use bit concatenation to form the input bits:

wire [3:0] A;
wire [3:0] B;
...
case ({A, B})
...
endcase


And your case statement will have 256 lines in it.

In addition to The Photon's answer, here is the complete RTL of a 4-bit multiplier using LUTs.

module Multiplier(a, b, z);
input [3:0] a;
input [3:0] b;
output reg [7:0] z;

always @(a, b) begin
case ({a, b})
8'b00000000: z <= 8'b00000000; // 0 * 0 = 0
8'b00000001: z <= 8'b00000000; // 0 * 1 = 0
8'b00000010: z <= 8'b00000000; // 0 * 2 = 0
8'b00000011: z <= 8'b00000000; // 0 * 3 = 0
8'b00000100: z <= 8'b00000000; // 0 * 4 = 0
8'b00000101: z <= 8'b00000000; // 0 * 5 = 0
8'b00000110: z <= 8'b00000000; // 0 * 6 = 0
8'b00000111: z <= 8'b00000000; // 0 * 7 = 0
8'b00001000: z <= 8'b00000000; // 0 * 8 = 0
8'b00001001: z <= 8'b00000000; // 0 * 9 = 0
8'b00001010: z <= 8'b00000000; // 0 * 10 = 0
8'b00001011: z <= 8'b00000000; // 0 * 11 = 0
8'b00001100: z <= 8'b00000000; // 0 * 12 = 0
8'b00001101: z <= 8'b00000000; // 0 * 13 = 0
8'b00001110: z <= 8'b00000000; // 0 * 14 = 0
8'b00001111: z <= 8'b00000000; // 0 * 15 = 0
8'b00010000: z <= 8'b00000000; // 1 * 0 = 0
8'b00010001: z <= 8'b00000001; // 1 * 1 = 1
8'b00010010: z <= 8'b00000010; // 1 * 2 = 2
8'b00010011: z <= 8'b00000011; // 1 * 3 = 3
8'b00010100: z <= 8'b00000100; // 1 * 4 = 4
8'b00010101: z <= 8'b00000101; // 1 * 5 = 5
8'b00010110: z <= 8'b00000110; // 1 * 6 = 6
8'b00010111: z <= 8'b00000111; // 1 * 7 = 7
8'b00011000: z <= 8'b00001000; // 1 * 8 = 8
8'b00011001: z <= 8'b00001001; // 1 * 9 = 9
8'b00011010: z <= 8'b00001010; // 1 * 10 = 10
8'b00011011: z <= 8'b00001011; // 1 * 11 = 11
8'b00011100: z <= 8'b00001100; // 1 * 12 = 12
8'b00011101: z <= 8'b00001101; // 1 * 13 = 13
8'b00011110: z <= 8'b00001110; // 1 * 14 = 14
8'b00011111: z <= 8'b00001111; // 1 * 15 = 15
8'b00100000: z <= 8'b00000000; // 2 * 0 = 0
8'b00100001: z <= 8'b00000010; // 2 * 1 = 2
8'b00100010: z <= 8'b00000100; // 2 * 2 = 4
8'b00100011: z <= 8'b00000110; // 2 * 3 = 6
8'b00100100: z <= 8'b00001000; // 2 * 4 = 8
8'b00100101: z <= 8'b00001010; // 2 * 5 = 10
8'b00100110: z <= 8'b00001100; // 2 * 6 = 12
8'b00100111: z <= 8'b00001110; // 2 * 7 = 14
8'b00101000: z <= 8'b00010000; // 2 * 8 = 16
8'b00101001: z <= 8'b00010010; // 2 * 9 = 18
8'b00101010: z <= 8'b00010100; // 2 * 10 = 20
8'b00101011: z <= 8'b00010110; // 2 * 11 = 22
8'b00101100: z <= 8'b00011000; // 2 * 12 = 24
8'b00101101: z <= 8'b00011010; // 2 * 13 = 26
8'b00101110: z <= 8'b00011100; // 2 * 14 = 28
8'b00101111: z <= 8'b00011110; // 2 * 15 = 30
8'b00110000: z <= 8'b00000000; // 3 * 0 = 0
8'b00110001: z <= 8'b00000011; // 3 * 1 = 3
8'b00110010: z <= 8'b00000110; // 3 * 2 = 6
8'b00110011: z <= 8'b00001001; // 3 * 3 = 9
8'b00110100: z <= 8'b00001100; // 3 * 4 = 12
8'b00110101: z <= 8'b00001111; // 3 * 5 = 15
8'b00110110: z <= 8'b00010010; // 3 * 6 = 18
8'b00110111: z <= 8'b00010101; // 3 * 7 = 21
8'b00111000: z <= 8'b00011000; // 3 * 8 = 24
8'b00111001: z <= 8'b00011011; // 3 * 9 = 27
8'b00111010: z <= 8'b00011110; // 3 * 10 = 30
8'b00111011: z <= 8'b00100001; // 3 * 11 = 33
8'b00111100: z <= 8'b00100100; // 3 * 12 = 36
8'b00111101: z <= 8'b00100111; // 3 * 13 = 39
8'b00111110: z <= 8'b00101010; // 3 * 14 = 42
8'b00111111: z <= 8'b00101101; // 3 * 15 = 45
8'b01000000: z <= 8'b00000000; // 4 * 0 = 0
8'b01000001: z <= 8'b00000100; // 4 * 1 = 4
8'b01000010: z <= 8'b00001000; // 4 * 2 = 8
8'b01000011: z <= 8'b00001100; // 4 * 3 = 12
8'b01000100: z <= 8'b00010000; // 4 * 4 = 16
8'b01000101: z <= 8'b00010100; // 4 * 5 = 20
8'b01000110: z <= 8'b00011000; // 4 * 6 = 24
8'b01000111: z <= 8'b00011100; // 4 * 7 = 28
8'b01001000: z <= 8'b00100000; // 4 * 8 = 32
8'b01001001: z <= 8'b00100100; // 4 * 9 = 36
8'b01001010: z <= 8'b00101000; // 4 * 10 = 40
8'b01001011: z <= 8'b00101100; // 4 * 11 = 44
8'b01001100: z <= 8'b00110000; // 4 * 12 = 48
8'b01001101: z <= 8'b00110100; // 4 * 13 = 52
8'b01001110: z <= 8'b00111000; // 4 * 14 = 56
8'b01001111: z <= 8'b00111100; // 4 * 15 = 60
8'b01010000: z <= 8'b00000000; // 5 * 0 = 0
8'b01010001: z <= 8'b00000101; // 5 * 1 = 5
8'b01010010: z <= 8'b00001010; // 5 * 2 = 10
8'b01010011: z <= 8'b00001111; // 5 * 3 = 15
8'b01010100: z <= 8'b00010100; // 5 * 4 = 20
8'b01010101: z <= 8'b00011001; // 5 * 5 = 25
8'b01010110: z <= 8'b00011110; // 5 * 6 = 30
8'b01010111: z <= 8'b00100011; // 5 * 7 = 35
8'b01011000: z <= 8'b00101000; // 5 * 8 = 40
8'b01011001: z <= 8'b00101101; // 5 * 9 = 45
8'b01011010: z <= 8'b00110010; // 5 * 10 = 50
8'b01011011: z <= 8'b00110111; // 5 * 11 = 55
8'b01011100: z <= 8'b00111100; // 5 * 12 = 60
8'b01011101: z <= 8'b01000001; // 5 * 13 = 65
8'b01011110: z <= 8'b01000110; // 5 * 14 = 70
8'b01011111: z <= 8'b01001011; // 5 * 15 = 75
8'b01100000: z <= 8'b00000000; // 6 * 0 = 0
8'b01100001: z <= 8'b00000110; // 6 * 1 = 6
8'b01100010: z <= 8'b00001100; // 6 * 2 = 12
8'b01100011: z <= 8'b00010010; // 6 * 3 = 18
8'b01100100: z <= 8'b00011000; // 6 * 4 = 24
8'b01100101: z <= 8'b00011110; // 6 * 5 = 30
8'b01100110: z <= 8'b00100100; // 6 * 6 = 36
8'b01100111: z <= 8'b00101010; // 6 * 7 = 42
8'b01101000: z <= 8'b00110000; // 6 * 8 = 48
8'b01101001: z <= 8'b00110110; // 6 * 9 = 54
8'b01101010: z <= 8'b00111100; // 6 * 10 = 60
8'b01101011: z <= 8'b01000010; // 6 * 11 = 66
8'b01101100: z <= 8'b01001000; // 6 * 12 = 72
8'b01101101: z <= 8'b01001110; // 6 * 13 = 78
8'b01101110: z <= 8'b01010100; // 6 * 14 = 84
8'b01101111: z <= 8'b01011010; // 6 * 15 = 90
8'b01110000: z <= 8'b00000000; // 7 * 0 = 0
8'b01110001: z <= 8'b00000111; // 7 * 1 = 7
8'b01110010: z <= 8'b00001110; // 7 * 2 = 14
8'b01110011: z <= 8'b00010101; // 7 * 3 = 21
8'b01110100: z <= 8'b00011100; // 7 * 4 = 28
8'b01110101: z <= 8'b00100011; // 7 * 5 = 35
8'b01110110: z <= 8'b00101010; // 7 * 6 = 42
8'b01110111: z <= 8'b00110001; // 7 * 7 = 49
8'b01111000: z <= 8'b00111000; // 7 * 8 = 56
8'b01111001: z <= 8'b00111111; // 7 * 9 = 63
8'b01111010: z <= 8'b01000110; // 7 * 10 = 70
8'b01111011: z <= 8'b01001101; // 7 * 11 = 77
8'b01111100: z <= 8'b01010100; // 7 * 12 = 84
8'b01111101: z <= 8'b01011011; // 7 * 13 = 91
8'b01111110: z <= 8'b01100010; // 7 * 14 = 98
8'b01111111: z <= 8'b01101001; // 7 * 15 = 105
8'b10000000: z <= 8'b00000000; // 8 * 0 = 0
8'b10000001: z <= 8'b00001000; // 8 * 1 = 8
8'b10000010: z <= 8'b00010000; // 8 * 2 = 16
8'b10000011: z <= 8'b00011000; // 8 * 3 = 24
8'b10000100: z <= 8'b00100000; // 8 * 4 = 32
8'b10000101: z <= 8'b00101000; // 8 * 5 = 40
8'b10000110: z <= 8'b00110000; // 8 * 6 = 48
8'b10000111: z <= 8'b00111000; // 8 * 7 = 56
8'b10001000: z <= 8'b01000000; // 8 * 8 = 64
8'b10001001: z <= 8'b01001000; // 8 * 9 = 72
8'b10001010: z <= 8'b01010000; // 8 * 10 = 80
8'b10001011: z <= 8'b01011000; // 8 * 11 = 88
8'b10001100: z <= 8'b01100000; // 8 * 12 = 96
8'b10001101: z <= 8'b01101000; // 8 * 13 = 104
8'b10001110: z <= 8'b01110000; // 8 * 14 = 112
8'b10001111: z <= 8'b01111000; // 8 * 15 = 120
8'b10010000: z <= 8'b00000000; // 9 * 0 = 0
8'b10010001: z <= 8'b00001001; // 9 * 1 = 9
8'b10010010: z <= 8'b00010010; // 9 * 2 = 18
8'b10010011: z <= 8'b00011011; // 9 * 3 = 27
8'b10010100: z <= 8'b00100100; // 9 * 4 = 36
8'b10010101: z <= 8'b00101101; // 9 * 5 = 45
8'b10010110: z <= 8'b00110110; // 9 * 6 = 54
8'b10010111: z <= 8'b00111111; // 9 * 7 = 63
8'b10011000: z <= 8'b01001000; // 9 * 8 = 72
8'b10011001: z <= 8'b01010001; // 9 * 9 = 81
8'b10011010: z <= 8'b01011010; // 9 * 10 = 90
8'b10011011: z <= 8'b01100011; // 9 * 11 = 99
8'b10011100: z <= 8'b01101100; // 9 * 12 = 108
8'b10011101: z <= 8'b01110101; // 9 * 13 = 117
8'b10011110: z <= 8'b01111110; // 9 * 14 = 126
8'b10011111: z <= 8'b10000111; // 9 * 15 = 135
8'b10100000: z <= 8'b00000000; // 10 * 0 = 0
8'b10100001: z <= 8'b00001010; // 10 * 1 = 10
8'b10100010: z <= 8'b00010100; // 10 * 2 = 20
8'b10100011: z <= 8'b00011110; // 10 * 3 = 30
8'b10100100: z <= 8'b00101000; // 10 * 4 = 40
8'b10100101: z <= 8'b00110010; // 10 * 5 = 50
8'b10100110: z <= 8'b00111100; // 10 * 6 = 60
8'b10100111: z <= 8'b01000110; // 10 * 7 = 70
8'b10101000: z <= 8'b01010000; // 10 * 8 = 80
8'b10101001: z <= 8'b01011010; // 10 * 9 = 90
8'b10101010: z <= 8'b01100100; // 10 * 10 = 100
8'b10101011: z <= 8'b01101110; // 10 * 11 = 110
8'b10101100: z <= 8'b01111000; // 10 * 12 = 120
8'b10101101: z <= 8'b10000010; // 10 * 13 = 130
8'b10101110: z <= 8'b10001100; // 10 * 14 = 140
8'b10101111: z <= 8'b10010110; // 10 * 15 = 150
8'b10110000: z <= 8'b00000000; // 11 * 0 = 0
8'b10110001: z <= 8'b00001011; // 11 * 1 = 11
8'b10110010: z <= 8'b00010110; // 11 * 2 = 22
8'b10110011: z <= 8'b00100001; // 11 * 3 = 33
8'b10110100: z <= 8'b00101100; // 11 * 4 = 44
8'b10110101: z <= 8'b00110111; // 11 * 5 = 55
8'b10110110: z <= 8'b01000010; // 11 * 6 = 66
8'b10110111: z <= 8'b01001101; // 11 * 7 = 77
8'b10111000: z <= 8'b01011000; // 11 * 8 = 88
8'b10111001: z <= 8'b01100011; // 11 * 9 = 99
8'b10111010: z <= 8'b01101110; // 11 * 10 = 110
8'b10111011: z <= 8'b01111001; // 11 * 11 = 121
8'b10111100: z <= 8'b10000100; // 11 * 12 = 132
8'b10111101: z <= 8'b10001111; // 11 * 13 = 143
8'b10111110: z <= 8'b10011010; // 11 * 14 = 154
8'b10111111: z <= 8'b10100101; // 11 * 15 = 165
8'b11000000: z <= 8'b00000000; // 12 * 0 = 0
8'b11000001: z <= 8'b00001100; // 12 * 1 = 12
8'b11000010: z <= 8'b00011000; // 12 * 2 = 24
8'b11000011: z <= 8'b00100100; // 12 * 3 = 36
8'b11000100: z <= 8'b00110000; // 12 * 4 = 48
8'b11000101: z <= 8'b00111100; // 12 * 5 = 60
8'b11000110: z <= 8'b01001000; // 12 * 6 = 72
8'b11000111: z <= 8'b01010100; // 12 * 7 = 84
8'b11001000: z <= 8'b01100000; // 12 * 8 = 96
8'b11001001: z <= 8'b01101100; // 12 * 9 = 108
8'b11001010: z <= 8'b01111000; // 12 * 10 = 120
8'b11001011: z <= 8'b10000100; // 12 * 11 = 132
8'b11001100: z <= 8'b10010000; // 12 * 12 = 144
8'b11001101: z <= 8'b10011100; // 12 * 13 = 156
8'b11001110: z <= 8'b10101000; // 12 * 14 = 168
8'b11001111: z <= 8'b10110100; // 12 * 15 = 180
8'b11010000: z <= 8'b00000000; // 13 * 0 = 0
8'b11010001: z <= 8'b00001101; // 13 * 1 = 13
8'b11010010: z <= 8'b00011010; // 13 * 2 = 26
8'b11010011: z <= 8'b00100111; // 13 * 3 = 39
8'b11010100: z <= 8'b00110100; // 13 * 4 = 52
8'b11010101: z <= 8'b01000001; // 13 * 5 = 65
8'b11010110: z <= 8'b01001110; // 13 * 6 = 78
8'b11010111: z <= 8'b01011011; // 13 * 7 = 91
8'b11011000: z <= 8'b01101000; // 13 * 8 = 104
8'b11011001: z <= 8'b01110101; // 13 * 9 = 117
8'b11011010: z <= 8'b10000010; // 13 * 10 = 130
8'b11011011: z <= 8'b10001111; // 13 * 11 = 143
8'b11011100: z <= 8'b10011100; // 13 * 12 = 156
8'b11011101: z <= 8'b10101001; // 13 * 13 = 169
8'b11011110: z <= 8'b10110110; // 13 * 14 = 182
8'b11011111: z <= 8'b11000011; // 13 * 15 = 195
8'b11100000: z <= 8'b00000000; // 14 * 0 = 0
8'b11100001: z <= 8'b00001110; // 14 * 1 = 14
8'b11100010: z <= 8'b00011100; // 14 * 2 = 28
8'b11100011: z <= 8'b00101010; // 14 * 3 = 42
8'b11100100: z <= 8'b00111000; // 14 * 4 = 56
8'b11100101: z <= 8'b01000110; // 14 * 5 = 70
8'b11100110: z <= 8'b01010100; // 14 * 6 = 84
8'b11100111: z <= 8'b01100010; // 14 * 7 = 98
8'b11101000: z <= 8'b01110000; // 14 * 8 = 112
8'b11101001: z <= 8'b01111110; // 14 * 9 = 126
8'b11101010: z <= 8'b10001100; // 14 * 10 = 140
8'b11101011: z <= 8'b10011010; // 14 * 11 = 154
8'b11101100: z <= 8'b10101000; // 14 * 12 = 168
8'b11101101: z <= 8'b10110110; // 14 * 13 = 182
8'b11101110: z <= 8'b11000100; // 14 * 14 = 196
8'b11101111: z <= 8'b11010010; // 14 * 15 = 210
8'b11110000: z <= 8'b00000000; // 15 * 0 = 0
8'b11110001: z <= 8'b00001111; // 15 * 1 = 15
8'b11110010: z <= 8'b00011110; // 15 * 2 = 30
8'b11110011: z <= 8'b00101101; // 15 * 3 = 45
8'b11110100: z <= 8'b00111100; // 15 * 4 = 60
8'b11110101: z <= 8'b01001011; // 15 * 5 = 75
8'b11110110: z <= 8'b01011010; // 15 * 6 = 90
8'b11110111: z <= 8'b01101001; // 15 * 7 = 105
8'b11111000: z <= 8'b01111000; // 15 * 8 = 120
8'b11111001: z <= 8'b10000111; // 15 * 9 = 135
8'b11111010: z <= 8'b10010110; // 15 * 10 = 150
8'b11111011: z <= 8'b10100101; // 15 * 11 = 165
8'b11111100: z <= 8'b10110100; // 15 * 12 = 180
8'b11111101: z <= 8'b11000011; // 15 * 13 = 195
8'b11111110: z <= 8'b11010010; // 15 * 14 = 210
8'b11111111: z <= 8'b11100001; // 15 * 15 = 225
default: z <= 0;
endcase
end
endmodule


And here is the Python script used to generate the RTL

#!/usr/bin/env python3
import itertools

width = 4
a_width = width
b_width = width
z_width = a_width + b_width

print("module Multiplier(a, b, z);")
print("    input [{}:0] a;".format(a_width - 1))
print("    input [{}:0] b;".format(b_width - 1))
print("    output reg [{}:0] z;".format(z_width - 1))
print()
print("    always @(a, b) begin")
print("        case ({a, b})")

fmt = "            {{4}}'b{{3:0{0}b}}: z <= {{4}}'b{{2:0{0}b}}; // {{0}} * {{1}} = {{2}}".format(z_width)
for a, b in itertools.product(range(2 ** a_width), range(2 ** b_width)):
sel = (a << b_width) + b
z = a * b
print(fmt.format(a, b, z, sel, z_width))

print("            default: z <= 0;")
print("        endcase")
print("    end")
print("endmodule")


Usage :

$python3 gen_mult.py > MultiplierLUT.v  Use this Modified and Working code and the testbench to evaluate the module. module MBA_module(p,a,b,clock); output [15:0] p; input [7:0] a, b; input clock; reg [15:0] p,ans; integer i, lookup_tbl; integer operate; initial begin p=16'b0; ans=16'b0; end always @(negedge clock) begin p=16'b0; for(i=1;i<=7;i=i+2) begin if(i==1) lookup_tbl = 0; else lookup_tbl = b[i-2]; lookup_tbl = lookup_tbl + 4*b[i] + 2*b[i-1]; if(lookup_tbl == 0 || lookup_tbl == 7) operate = 0; else if(lookup_tbl == 3 || lookup_tbl == 4) operate = 2; else operate = 1; if(b[i] == 1) operate = -1*operate; case(operate) 1: begin ans=a; ans=ans<<(i-1); p=p+ans; end 2: begin ans=a<<1; ans=ans<<(i-1); p=p+ans; end -1: begin ans=~a+1; ans=ans<<(i-1); p=p+ans; end -2: begin ans=a<<1; ans=~ans+1; ans=ans<<(i-1); p=p+ans; end endcase end end endmodule  Below is the testbench module MBA_mod_tb; // Inputs reg [7:0] a; reg [7:0] b; reg clock; // Outputs wire [15:0] p; // Variables integer j,k; // Instantiate the Unit Under Test (UUT) MBA_module uut ( .p(p), .a(a), .b(b), .clock(clock) ); initial clock = 0; always #5 clock = ~clock; initial begin a=0; b=0; for (j=1; j<10; j=j+1) for (k=1; k<11; k=k+1) begin a=j; b=k; #20$display("%d * %d = %d", a, b, p);
end
end
endmodule

• The question is two years old. There is no point resurrecting it with an answer that doesn't actually answer the question. – Tom Carpenter Apr 4 '17 at 19:55