建立一个C的范围为0~255,内容是(C)2/4的查表
占用256个存储空间,但可以计算出+-127的两个数之积。传统算法需要至少127×127个存储空间。
查找表模块的建立:
module lut_module ( input CLK, input RSTn, input [7:0]Addr, output [15:0]Q ); /*****************************/ reg [15:0]rQ; always @ ( posedge CLK or negedge RSTn ) if( !RSTn ) rQ <= 16'd0; else case( Addr ) 0,1 : rQ <= 16'd0; 2 : rQ <= 16'd1; 3 : rQ <= 16'd2; 4 : rQ <= 16'd4; 5 : rQ <= 16'd6; 6 : rQ <= 16'd9; 7 : rQ <= 16'd12; 8 : rQ <= 16'd16; 9 : rQ <= 16'd20; 10 : rQ <= 16'd25; 11 : rQ <= 16'd30; 12 : rQ <= 16'd36; 13 : rQ <= 16'd42; 14 : rQ <= 16'd49; 15 : rQ <= 16'd56; 16 : rQ <= 16'd64; 17 : rQ <= 16'd72; 18 : rQ <= 16'd81; 19 : rQ <= 16'd90; 20 : rQ <= 16'd100; 21 : rQ <= 16'd110; 22 : rQ <= 16'd121; 23 : rQ <= 16'd132; 24 : rQ <= 16'd144; 25 : rQ <= 16'd156; 26 : rQ <= 16'd169; 27 : rQ <= 16'd182; 28 : rQ <= 16'd196; 29 : rQ <= 16'd210; 30 : rQ <= 16'd225; 31 : rQ <= 16'd240; 32 : rQ <= 16'd256; 33 : rQ <= 16'd272; 34 : rQ <= 16'd289; 35 : rQ <= 16'd306; 36 : rQ <= 16'd324; 37 : rQ <= 16'd342; 38 : rQ <= 16'd361; 39 : rQ <= 16'd380; 40 : rQ <= 16'd400; 41 : rQ <= 16'd420; 42 : rQ <= 16'd441; 43 : rQ <= 16'd462; 44 : rQ <= 16'd484; 45 : rQ <= 16'd506; 46 : rQ <= 16'd529; 47 : rQ <= 16'd552; 48 : rQ <= 16'd576; 49 : rQ <= 16'd600; 50 : rQ <= 16'd625; 51 : rQ <= 16'd650; 52 : rQ <= 16'd676; 53 : rQ <= 16'd702; 54 : rQ <= 16'd729; 55 : rQ <= 16'd756; 56 : rQ <= 16'd784; 57 : rQ <= 16'd812; 58 : rQ <= 16'd841; 59 : rQ <= 16'd870; 60 : rQ <= 16'd900; 61 : rQ <= 16'd930; 62 : rQ <= 16'd961; 63 : rQ <= 16'd992; 64 : rQ <= 16'd1024; 65 : rQ <= 16'd1056; 66 : rQ <= 16'd1089; 67 : rQ <= 16'd1122; 68 : rQ <= 16'd1156; 69 : rQ <= 16'd1190; 70 : rQ <= 16'd1225; 71 : rQ <= 16'd1260; 72 : rQ <= 16'd1296; 73 : rQ <= 16'd1332; 74 : rQ <= 16'd1369; 75 : rQ <= 16'd1406; 76 : rQ <= 16'd1444; 77 : rQ <= 16'd1482; 78 : rQ <= 16'd1521; 79 : rQ <= 16'd1560; 80 : rQ <= 16'd1600; 81 : rQ <= 16'd1640; 82 : rQ <= 16'd1681; 83 : rQ <= 16'd1722; 84 : rQ <= 16'd1764; 85 : rQ <= 16'd1806; 86 : rQ <= 16'd1849; 87 : rQ <= 16'd1892; 88 : rQ <= 16'd1936; 89 : rQ <= 16'd1980; 90 : rQ <= 16'd2025; 91 : rQ <= 16'd2070; 92 : rQ <= 16'd2116; 93 : rQ <= 16'd2162; 94 : rQ <= 16'd2209; 95 : rQ <= 16'd2256; 96 : rQ <= 16'd2304; 97 : rQ <= 16'd2352; 98 : rQ <= 16'd2401; 99 : rQ <= 16'd2450; 100 : rQ <= 16'd2500; 101 : rQ <= 16'd2550; 102 : rQ <= 16'd2601; 103 : rQ <= 16'd2652; 104 : rQ <= 16'd2704; 105 : rQ <= 16'd2756; 106 : rQ <= 16'd2809; 107 : rQ <= 16'd2862; 108 : rQ <= 16'd2916; 109 : rQ <= 16'd2970; 110 : rQ <= 16'd3025; 111 : rQ <= 16'd3080; 112 : rQ <= 16'd3136; 113 : rQ <= 16'd3192; 114 : rQ <= 16'd3249; 115 : rQ <= 16'd3306; 116 : rQ <= 16'd3364; 117 : rQ <= 16'd3422; 118 : rQ <= 16'd3481; 119 : rQ <= 16'd3540; 120 : rQ <= 16'd3600; 121 : rQ <= 16'd3660; 122 : rQ <= 16'd3721; 123 : rQ <= 16'd3782; 124 : rQ <= 16'd3844; 125 : rQ <= 16'd3906; 126 : rQ <= 16'd3969; 127 : rQ <= 16'd4032; 128 : rQ <= 16'd4096; 129 : rQ <= 16'd4160; 130 : rQ <= 16'd4225; 131 : rQ <= 16'd4290; 132 : rQ <= 16'd4356; 133 : rQ <= 16'd4422; 134 : rQ <= 16'd4489; 135 : rQ <= 16'd4556; 136 : rQ <= 16'd4624; 137 : rQ <= 16'd4692; 138 : rQ <= 16'd4761; 139 : rQ <= 16'd4830; 140 : rQ <= 16'd4900; 141 : rQ <= 16'd4970; 142 : rQ <= 16'd5041; 143 : rQ <= 16'd5112; 144 : rQ <= 16'd5184; 145 : rQ <= 16'd5256; 146 : rQ <= 16'd5329; 147 : rQ <= 16'd5402; 148 : rQ <= 16'd5476; 149 : rQ <= 16'd5550; 150 : rQ <= 16'd5625; 151 : rQ <= 16'd5700; 152 : rQ <= 16'd5776; 153 : rQ <= 16'd5852; 154 : rQ <= 16'd5929; 155 : rQ <= 16'd6006; 156 : rQ <= 16'd6084; 157 : rQ <= 16'd6162; 158 : rQ <= 16'd6241; 159 : rQ <= 16'd6320; 160 : rQ <= 16'd6400; 161 : rQ <= 16'd6480; 162 : rQ <= 16'd6561; 163 : rQ <= 16'd6642; 164 : rQ <= 16'd6724; 165 : rQ <= 16'd6806; 166 : rQ <= 16'd6889; 167 : rQ <= 16'd6972; 168 : rQ <= 16'd7056; 169 : rQ <= 16'd7140; 170 : rQ <= 16'd7225; 171 : rQ <= 16'd7310; 172 : rQ <= 16'd7396; 173 : rQ <= 16'd7482; 174 : rQ <= 16'd7569; 175 : rQ <= 16'd7656; 176 : rQ <= 16'd7744; 177 : rQ <= 16'd7832; 178 : rQ <= 16'd7921; 179 : rQ <= 16'd8010; 180 : rQ <= 16'd8100; 181 : rQ <= 16'd8190; 182 : rQ <= 16'd8281; 183 : rQ <= 16'd8372; 184 : rQ <= 16'd8464; 185 : rQ <= 16'd8556; 186 : rQ <= 16'd8649; 187 : rQ <= 16'd8742; 188 : rQ <= 16'd8836; 189 : rQ <= 16'd8930; 190 : rQ <= 16'd9025; 191 : rQ <= 16'd9120; 192 : rQ <= 16'd9216; 193 : rQ <= 16'd9312; 194 : rQ <= 16'd9409; 195 : rQ <= 16'd9506; 196 : rQ <= 16'd9604; 197 : rQ <= 16'd9702; 198 : rQ <= 16'd9801; 199 : rQ <= 16'd9900; 200 : rQ <= 16'd10000; 201 : rQ <= 16'd10100; 202 : rQ <= 16'd10201; 203 : rQ <= 16'd10302; 204 : rQ <= 16'd10404; 205 : rQ <= 16'd10506; 206 : rQ <= 16'd10609; 207 : rQ <= 16'd10712; 208 : rQ <= 16'd10816; 209 : rQ <= 16'd10920; 210 : rQ <= 16'd11025; 211 : rQ <= 16'd11130; 212 : rQ <= 16'd11236; 213 : rQ <= 16'd11342; 214 : rQ <= 16'd11449; 215 : rQ <= 16'd11556; 216 : rQ <= 16'd11664; 217 : rQ <= 16'd11772; 218 : rQ <= 16'd11881; 219 : rQ <= 16'd11990; 220 : rQ <= 16'd12100; 221 : rQ <= 16'd12210; 222 : rQ <= 16'd12321; 223 : rQ <= 16'd12432; 224 : rQ <= 16'd12544; 225 : rQ <= 16'd12656; 226 : rQ <= 16'd12769; 227 : rQ <= 16'd12882; 228 : rQ <= 16'd12996; 229 : rQ <= 16'd13100; 230 : rQ <= 16'd13225; 231 : rQ <= 16'd13340; 232 : rQ <= 16'd13456; 233 : rQ <= 16'd13572; 234 : rQ <= 16'd13689; 235 : rQ <= 16'd13806; 236 : rQ <= 16'd13924; 237 : rQ <= 16'd14042; 238 : rQ <= 16'd14161; 239 : rQ <= 16'd14280; 240 : rQ <= 16'd14400; 241 : rQ <= 16'd14520; 242 : rQ <= 16'd14641; 243 : rQ <= 16'd14762; 244 : rQ <= 16'd14884; 245 : rQ <= 16'd15006; 246 : rQ <= 16'd15129; 247 : rQ <= 16'd15252; 248 : rQ <= 16'd15376; 249 : rQ <= 16'd15500; 250 : rQ <= 16'd15625; 251 : rQ <= 16'd15750; 252 : rQ <= 16'd15876; 253 : rQ <= 16'd16002; 254 : rQ <= 16'd16129; 255 : rQ <= 16'd16256; endcase /*****************************/ assign Q = rQ; /*****************************/ endmodule
根据ab=( a + b ) 2 /4 - ( a - b ) 2 /4,取I1=a+b,I2=a-b,然后I1,I2取正数,调用rom模块求出(C)2/4; 然后相减(加补码)
module lut_multiplier_module ( input CLK, input RSTn, input Start_Sig, input [7:0]A, input [7:0]B, output Done_Sig, output [15:0]Product, /***************************/ output [8:0]SQ_I1_Sig, output [8:0]SQ_I2_Sig, output [15:0]SQ_Q1_Sig, output [15:0]SQ_Q2_Sig /***************************/ ); /***************************/ wire [15:0]Q1_Sig; wire [15:0]Q2_Sig; /***************************/ reg [3:0]i; reg [8:0]I1; reg [8:0]I2; reg [15:0]Data; reg isDone; always @ ( posedge CLK or negedge RSTn ) if( !RSTn ) begin i <= 4'd0; I1 <= 9'd0; I2 <= 9'd0; Data <= 16'd0; isDone <= 1'b0; end else if( Start_Sig ) case( i ) 0: begin I1 <= { A[7], A } + { B[7], B }; I2 <= { A[7], A } + { ~B[7], ( ~B + 1'b1 ) }; i <= i + 1'b1; end 1: begin I1 <= I1[8] ? ( ~I1 + 1'b1 ) : I1; I2 <= I2[8] ? ( ~I2 + 1'b1 ) : I2; i <= i + 1'b1; end 2: begin i <= i + 1'b1; end 3: begin Data <= Q1_Sig + ( ~Q2_Sig + 1'b1 ); i <= i + 1'b1; end 4: begin isDone <= 1'b1; i <= i + 1'b1; end 5: begin isDone <= 1'b0; i <= 4'd0; end endcase /***************************/ lut_module U1 ( .CLK ( CLK ), .RSTn( RSTn ), .Addr ( I1[7:0] ), .Q ( Q1_Sig ) ); /***************************/ lut_module U2 ( .CLK ( CLK ), .RSTn( RSTn ), .Addr ( I2[7:0] ), .Q ( Q2_Sig ) ); /***************************/ assign Done_Sig = isDone; assign Product = Data; /***************************/ assign SQ_I1_Sig = I1; assign SQ_I2_Sig = I2; assign SQ_Q1_Sig = Q1_Sig; assign SQ_Q2_Sig = Q2_Sig; /***************************/ endmodule
还可通过quartus直接建立rom宏模块,.mif文件由file-new-other files-Memory Initialization File建立,填入上述地址、数据。
测试激励文本lut_multiplier_module.vt
`timescale 1 ps/ 1 ps module lut_multiplier_module_simulation(); reg CLK; reg RSTn; reg Start_Sig; reg [7:0]A; reg [7:0]B; wire Done_Sig; wire [15:0]Product; /*************************/ wire [8:0]SQ_I1_Sig; wire [8:0]SQ_I2_Sig; wire [15:0]SQ_Q1_Sig; wire [15:0]SQ_Q2_Sig; /*************************/ lut_multiplier_module U1 ( .CLK(CLK), .RSTn(RSTn), .Start_Sig(Start_Sig), .A(A), .B(B), .Done_Sig(Done_Sig), .Product(Product), .SQ_I1_Sig(SQ_I1_Sig), .SQ_I2_Sig(SQ_I2_Sig), .SQ_Q1_Sig(SQ_Q1_Sig), .SQ_Q2_Sig(SQ_Q2_Sig) ); /******************************/ initial begin RSTn = 0; #10; RSTn = 1; CLK = 0; forever #10 CLK = ~CLK; end /******************************/ reg [3:0]i; always @ ( posedge CLK or negedge RSTn ) if( !RSTn ) begin i <= 4'd0; Start_Sig <= 1'b0; A <= 8'd0; B <= 8'd0; end else case( i ) 0: // A = -127 , B = 127 if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end else begin A <= 8'b10000001; B <= 8'd127; Start_Sig <= 1'b1; end 1: // A = 2 , B = - 4 if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end else begin A <= 8'd2; B <= 8'b11111100; Start_Sig <= 1'b1; end 2: // A = 10 , B = 100 if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end else begin A <= 8'd10; B <= 8'd100; Start_Sig <= 1'b1; end 3: // A = -127 , B = -127 if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end else begin A <= 8'b10000001; B <= 8'b10000001; Start_Sig <= 1'b1; end 4: i <= 4'd4; endcase endmodule