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.
-
3\$\begingroup\$ Can you show us what you've tried or where you are so far? \$\endgroup\$– Greg d'EonCommented Apr 9, 2015 at 16:02
-
\$\begingroup\$ 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 \$\endgroup\$– supasport13Commented Apr 9, 2015 at 21:28
-
\$\begingroup\$ 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. \$\endgroup\$– supasport13Commented Apr 9, 2015 at 21:31
-
\$\begingroup\$ for the four bit I am stuck at the very beginning \$\endgroup\$– supasport13Commented Apr 9, 2015 at 21:32
-
\$\begingroup\$ module TBM(a,b,p); input[3:0]a,b; output[7,0]p; \$\endgroup\$– supasport13Commented Apr 9, 2015 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
-
\$\begingroup\$ The question is two years old. There is no point resurrecting it with an answer that doesn't actually answer the question. \$\endgroup\$ Commented Apr 4, 2017 at 19:55