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.
-
3Can you show us what you've tried or where you are so far? – Greg d'Eon Apr 09 '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 09 '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 09 '15 at 21:31
-
for the four bit I am stuck at the very beginning – supasport13 Apr 09 '15 at 21:32
-
module TBM(a,b,p); input[3:0]a,b; output[7,0]p; – supasport13 Apr 09 '15 at 21:32
-
@Gregd'Eon this is what I have so far – supasport13 Apr 10 '15 at 06:04
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.

- 126,425
- 3
- 159
- 304
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

- 63
- 1
- 4
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 04 '17 at 19:55