├── LICENSE ├── README.md ├── adder.v ├── adder_tb.v ├── divider.v ├── exponential.v ├── exponential_tb.v ├── multiplier.v ├── multiplier_tb.sv ├── softmax.py ├── softmax.v ├── softmax_tb.v └── waveform ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── Capture.PNG ├── a.png ├── add.png ├── adder_tb.png ├── b.png ├── c.png ├── exp_tb.png ├── graph.PNG ├── mul_tb.png ├── sc1.png ├── schematic.png ├── smax.png └── softmax.png /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Verilog implementation of Softmax function 2 | Softmax is a non-linear logistic function commonly used in neural network circuits. 3 | 4 | Softmax is denoted with the following equation. 5 | 6 | ![Softmax equation](waveform/smax.png) 7 | ### Softmax graph 8 | ![Softmax graph](waveform/graph.PNG) 9 | Taylor series approximation is used to calculate exponential which is donated as follow: 10 | f(x) = e^x = 1 + x/1! + x^2/2! + x^3/3! + .... 11 | 12 | ### Implementation Block: 13 | ![Block Diagram](waveform/Capture.PNG) 14 | 15 | ### Waveforms 16 | ![softmax waveform](waveform/softmax.png) 17 | -------------------------------------------------------------------------------- /adder.v: -------------------------------------------------------------------------------- 1 | //IEEE Floating Point Adder (Single Precision) 2 | //Copyright (C) Jonathan P Dawson 2013 3 | //2013-12-12 4 | `timescale 1ns/1ps 5 | module adder( 6 | input_a, 7 | input_b, 8 | input_a_stb, 9 | input_b_stb, 10 | output_z_ack, 11 | clk, 12 | rst, 13 | output_z, 14 | output_z_stb, 15 | input_a_ack, 16 | input_b_ack); 17 | 18 | input clk; 19 | input rst; 20 | 21 | input [31:0] input_a; 22 | input input_a_stb; 23 | output input_a_ack; 24 | 25 | input [31:0] input_b; 26 | input input_b_stb; 27 | output input_b_ack; 28 | 29 | output reg [31:0] output_z; 30 | output output_z_stb; 31 | input output_z_ack; 32 | 33 | reg s_output_z_stb; 34 | // reg [31:0] output_z; 35 | reg s_input_a_ack; 36 | reg s_input_b_ack; 37 | 38 | reg [3:0] state; 39 | parameter get_a = 4'd0, 40 | get_b = 4'd1, 41 | unpack = 4'd2, 42 | special_cases = 4'd3, 43 | align = 4'd4, 44 | add_0 = 4'd5, 45 | add_1 = 4'd6, 46 | normalise_1 = 4'd7, 47 | normalise_2 = 4'd8, 48 | round = 4'd9, 49 | pack = 4'd10, 50 | put_z = 4'd11; 51 | 52 | reg [31:0] a, b, z; 53 | reg [26:0] a_m, b_m; 54 | reg [23:0] z_m; 55 | reg [9:0] a_e, b_e, z_e; 56 | reg a_s, b_s, z_s; 57 | reg guard, round_bit, sticky; 58 | reg [27:0] sum; 59 | 60 | always @(posedge clk or negedge rst) 61 | begin 62 | if (rst == 1) begin 63 | state <= get_a; 64 | s_input_a_ack <= 0; 65 | s_input_b_ack <= 0; 66 | s_output_z_stb <= 0; 67 | output_z <= 0; 68 | a <= 0; 69 | b <= 0; 70 | z <= 0; 71 | a_m <= 0; 72 | b_m <= 0; 73 | z_m <= 0; 74 | a_e <= 0; 75 | b_e <= 0; 76 | z_m <= 0; 77 | 78 | end 79 | else begin 80 | 81 | case(state) 82 | 83 | get_a: 84 | begin 85 | s_input_a_ack <= 1; 86 | if (s_input_a_ack && input_a_stb) begin 87 | a <= input_a; 88 | s_input_a_ack <= 0; 89 | state <= get_b; 90 | end 91 | end 92 | 93 | get_b: 94 | begin 95 | s_input_b_ack <= 1; 96 | if (s_input_b_ack && input_b_stb) begin 97 | b <= input_b; 98 | s_input_b_ack <= 0; 99 | state <= unpack; 100 | end 101 | end 102 | 103 | unpack: 104 | begin 105 | a_m <= {a[22 : 0], 3'd0}; 106 | b_m <= {b[22 : 0], 3'd0}; 107 | a_e <= a[30 : 23] - 127; 108 | b_e <= b[30 : 23] - 127; 109 | a_s <= a[31]; 110 | b_s <= b[31]; 111 | state <= special_cases; 112 | end 113 | 114 | special_cases: 115 | begin 116 | //if a is NaN or b is NaN return NaN 117 | if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin 118 | z[31] <= 1; 119 | z[30:23] <= 255; 120 | z[22] <= 1; 121 | z[21:0] <= 0; 122 | state <= put_z; 123 | //if a is inf return inf 124 | end else if (a_e == 128) begin 125 | z[31] <= a_s; 126 | z[30:23] <= 255; 127 | z[22:0] <= 0; 128 | //if a is inf and signs don't match return nan 129 | if ((b_e == 128) && (a_s != b_s)) begin 130 | z[31] <= b_s; 131 | z[30:23] <= 255; 132 | z[22] <= 1; 133 | z[21:0] <= 0; 134 | end 135 | state <= put_z; 136 | //if b is inf return inf 137 | end else if (b_e == 128) begin 138 | z[31] <= b_s; 139 | z[30:23] <= 255; 140 | z[22:0] <= 0; 141 | state <= put_z; 142 | //if a is zero return b 143 | end else if ((($signed(a_e) == -127) && (a_m == 0)) && (($signed(b_e) == -127) && (b_m == 0))) begin 144 | z[31] <= a_s & b_s; 145 | z[30:23] <= b_e[7:0] + 127; 146 | z[22:0] <= b_m[26:3]; 147 | state <= put_z; 148 | //if a is zero return b 149 | end else if (($signed(a_e) == -127) && (a_m == 0)) begin 150 | z[31] <= b_s; 151 | z[30:23] <= b_e[7:0] + 127; 152 | z[22:0] <= b_m[26:3]; 153 | state <= put_z; 154 | //if b is zero return a 155 | end else if (($signed(b_e) == -127) && (b_m == 0)) begin 156 | z[31] <= a_s; 157 | z[30:23] <= a_e[7:0] + 127; 158 | z[22:0] <= a_m[26:3]; 159 | state <= put_z; 160 | end else begin 161 | //Denormalised Number 162 | if ($signed(a_e) == -127) begin 163 | a_e <= -126; 164 | end else begin 165 | a_m[26] <= 1; 166 | end 167 | //Denormalised Number 168 | if ($signed(b_e) == -127) begin 169 | b_e <= -126; 170 | end else begin 171 | b_m[26] <= 1; 172 | end 173 | state <= align; 174 | end 175 | end 176 | 177 | align: 178 | begin 179 | if ($signed(a_e) > $signed(b_e)) begin 180 | b_e <= b_e + 1; 181 | b_m <= b_m >> 1; 182 | b_m[0] <= b_m[0] | b_m[1]; 183 | end else if ($signed(a_e) < $signed(b_e)) begin 184 | a_e <= a_e + 1; 185 | a_m <= a_m >> 1; 186 | a_m[0] <= a_m[0] | a_m[1]; 187 | end else begin 188 | state <= add_0; 189 | end 190 | end 191 | 192 | add_0: 193 | begin 194 | z_e <= a_e; 195 | if (a_s == b_s) begin 196 | sum <= a_m + b_m; 197 | z_s <= a_s; 198 | end else begin 199 | if (a_m >= b_m) begin 200 | sum <= a_m - b_m; 201 | z_s <= a_s; 202 | end else begin 203 | sum <= b_m - a_m; 204 | z_s <= b_s; 205 | end 206 | end 207 | state <= add_1; 208 | end 209 | 210 | add_1: 211 | begin 212 | if (sum[27]) begin 213 | z_m <= sum[27:4]; 214 | guard <= sum[3]; 215 | round_bit <= sum[2]; 216 | sticky <= sum[1] | sum[0]; 217 | z_e <= z_e + 1; 218 | end else begin 219 | z_m <= sum[26:3]; 220 | guard <= sum[2]; 221 | round_bit <= sum[1]; 222 | sticky <= sum[0]; 223 | end 224 | state <= normalise_1; 225 | end 226 | 227 | normalise_1: 228 | begin 229 | if (z_m[23] == 0 && $signed(z_e) > -126) begin 230 | z_e <= z_e - 1; 231 | z_m <= z_m << 1; 232 | z_m[0] <= guard; 233 | guard <= round_bit; 234 | round_bit <= 0; 235 | end else begin 236 | state <= normalise_2; 237 | end 238 | end 239 | 240 | normalise_2: 241 | begin 242 | if ($signed(z_e) < -126) begin 243 | z_e <= z_e + 1; 244 | z_m <= z_m >> 1; 245 | guard <= z_m[0]; 246 | round_bit <= guard; 247 | sticky <= sticky | round_bit; 248 | end else begin 249 | state <= round; 250 | end 251 | end 252 | 253 | round: 254 | begin 255 | if (guard && (round_bit | sticky | z_m[0])) begin 256 | z_m <= z_m + 1; 257 | if (z_m == 24'hffffff) begin 258 | z_e <=z_e + 1; 259 | end 260 | end 261 | state <= pack; 262 | end 263 | 264 | pack: 265 | begin 266 | z[22 : 0] <= z_m[22:0]; 267 | z[30 : 23] <= z_e[7:0] + 127; 268 | z[31] <= z_s; 269 | if ($signed(z_e) == -126 && z_m[23] == 0) begin 270 | z[30 : 23] <= 0; 271 | end 272 | //if overflow occurs, return inf 273 | if ($signed(z_e) > 127) begin 274 | z[22 : 0] <= 0; 275 | z[30 : 23] <= 255; 276 | z[31] <= z_s; 277 | end 278 | state <= put_z; 279 | end 280 | 281 | put_z: 282 | begin 283 | s_output_z_stb <= 1; 284 | output_z <= z; 285 | if (s_output_z_stb && output_z_ack) begin 286 | s_output_z_stb <= 0; 287 | state <= get_a; 288 | end 289 | end 290 | 291 | endcase 292 | 293 | end 294 | end 295 | assign input_a_ack = s_input_a_ack; 296 | assign input_b_ack = s_input_b_ack; 297 | assign output_z_stb = s_output_z_stb; 298 | // assign output_z = output_z; 299 | 300 | endmodule 301 | 302 | -------------------------------------------------------------------------------- /adder_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | module adder_tb(); 3 | 4 | reg clk; 5 | reg rst; 6 | reg [31:0] input_a; 7 | reg [31:0] input_b; 8 | reg input_a_stb; 9 | reg input_b_stb; 10 | reg output_z_ack; 11 | wire input_a_ack; 12 | wire input_b_ack; 13 | wire output_z_stb; 14 | wire [31:0] output_z; 15 | initial begin 16 | clk = 1; 17 | rst = 1; 18 | input_a_stb = 0; 19 | input_b_stb = 0; 20 | output_z_ack = 0; 21 | #10 22 | rst = 0; 23 | //////////////////////////// 24 | input_a_stb = 1; 25 | input_b_stb = 1; 26 | output_z_ack = 1; 27 | // #5 28 | input_a = 32'h3f800000; 29 | input_b = 32'h3f800000; 30 | #32 31 | // input_a_stb = 0; 32 | // input_b_stb = 0; 33 | // output_z_ack = 0; 34 | // #10 35 | //////////////////////////// 36 | // input_a_stb = 0; 37 | // input_b_stb = 0; 38 | // output_z_ack = 0; 39 | // //////////////////////////// 40 | // #10 41 | // input_a_stb = 1; 42 | // input_b_stb = 1; 43 | // output_z_ack = 1; 44 | // #5 45 | input_a = 32'h3f000000; 46 | input_b = 32'h3f000000; 47 | #32 48 | input_a = 32'h3f000000; 49 | input_b = 32'hbf000000; 50 | 51 | 52 | end 53 | 54 | adder DUT ( 55 | input_a, 56 | input_b, 57 | input_a_stb, 58 | input_b_stb, 59 | output_z_ack, 60 | clk, 61 | rst, 62 | output_z, 63 | output_z_stb, 64 | input_a_ack, 65 | input_b_ack); 66 | 67 | always 68 | #1 clk = ~clk; 69 | 70 | endmodule // adder_tb -------------------------------------------------------------------------------- /divider.v: -------------------------------------------------------------------------------- 1 | //IEEE Floating Point Divider (Single Precision) 2 | //Copyright (C) Jonathan P Dawson 2013 3 | //2013-12-12 4 | // 5 | module divider( 6 | input_a, 7 | input_b, 8 | input_a_stb, 9 | input_b_stb, 10 | output_z_ack, 11 | clk, 12 | rst, 13 | output_z, 14 | output_z_stb, 15 | input_a_ack, 16 | input_b_ack); 17 | 18 | input clk; 19 | input rst; 20 | 21 | input [31:0] input_a; 22 | input input_a_stb; 23 | output input_a_ack; 24 | 25 | input [31:0] input_b; 26 | input input_b_stb; 27 | output input_b_ack; 28 | 29 | output reg [31:0] output_z; 30 | output output_z_stb; 31 | input output_z_ack; 32 | 33 | reg s_output_z_stb; 34 | // reg [31:0] output_z; 35 | reg s_input_a_ack; 36 | reg s_input_b_ack; 37 | 38 | reg [3:0] state; 39 | parameter get_a = 4'd0, 40 | get_b = 4'd1, 41 | unpack = 4'd2, 42 | special_cases = 4'd3, 43 | normalise_a = 4'd4, 44 | normalise_b = 4'd5, 45 | divide_0 = 4'd6, 46 | divide_1 = 4'd7, 47 | divide_2 = 4'd8, 48 | divide_3 = 4'd9, 49 | normalise_1 = 4'd10, 50 | normalise_2 = 4'd11, 51 | round = 4'd12, 52 | pack = 4'd13, 53 | put_z = 4'd14; 54 | 55 | reg [31:0] a, b, z; 56 | reg [23:0] a_m, b_m, z_m; 57 | reg [9:0] a_e, b_e, z_e; 58 | reg a_s, b_s, z_s; 59 | reg guard, round_bit, sticky; 60 | reg [50:0] quotient, divisor, dividend, remainder; 61 | reg [5:0] count; 62 | 63 | always @(posedge clk) 64 | begin 65 | if (rst == 1) begin 66 | state <= get_a; 67 | s_input_a_ack <= 0; 68 | s_input_b_ack <= 0; 69 | s_output_z_stb <= 0; 70 | output_z <= 0; 71 | a <= 0; 72 | b <= 0; 73 | z <= 0; 74 | a_m <= 0; 75 | b_m <= 0; 76 | z_m <= 0; 77 | a_e <= 0; 78 | b_e <= 0; 79 | z_m <= 0; 80 | 81 | 82 | end 83 | else begin 84 | 85 | case(state) 86 | 87 | get_a: 88 | begin 89 | s_input_a_ack <= 1; 90 | if (s_input_a_ack && input_a_stb) begin 91 | a <= input_a; 92 | s_input_a_ack <= 0; 93 | state <= get_b; 94 | end 95 | end 96 | 97 | get_b: 98 | begin 99 | s_input_b_ack <= 1; 100 | if (s_input_b_ack && input_b_stb) begin 101 | b <= input_b; 102 | s_input_b_ack <= 0; 103 | state <= unpack; 104 | end 105 | end 106 | 107 | unpack: 108 | begin 109 | a_m <= a[22 : 0]; 110 | b_m <= b[22 : 0]; 111 | a_e <= a[30 : 23] - 127; 112 | b_e <= b[30 : 23] - 127; 113 | a_s <= a[31]; 114 | b_s <= b[31]; 115 | state <= special_cases; 116 | end 117 | 118 | special_cases: 119 | begin 120 | //if a is NaN or b is NaN return NaN 121 | if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin 122 | z[31] <= 1; 123 | z[30:23] <= 255; 124 | z[22] <= 1; 125 | z[21:0] <= 0; 126 | state <= put_z; 127 | //if a is inf and b is inf return NaN 128 | end else if ((a_e == 128) && (b_e == 128)) begin 129 | z[31] <= 1; 130 | z[30:23] <= 255; 131 | z[22] <= 1; 132 | z[21:0] <= 0; 133 | state <= put_z; 134 | //if a is inf return inf 135 | end else if (a_e == 128) begin 136 | z[31] <= a_s ^ b_s; 137 | z[30:23] <= 255; 138 | z[22:0] <= 0; 139 | state <= put_z; 140 | //if b is zero return NaN 141 | if ($signed(b_e == -127) && (b_m == 0)) begin 142 | z[31] <= 1; 143 | z[30:23] <= 255; 144 | z[22] <= 1; 145 | z[21:0] <= 0; 146 | state <= put_z; 147 | end 148 | //if b is inf return zero 149 | end else if (b_e == 128) begin 150 | z[31] <= a_s ^ b_s; 151 | z[30:23] <= 0; 152 | z[22:0] <= 0; 153 | state <= put_z; 154 | //if a is zero return zero 155 | end else if (($signed(a_e) == -127) && (a_m == 0)) begin 156 | z[31] <= a_s ^ b_s; 157 | z[30:23] <= 0; 158 | z[22:0] <= 0; 159 | state <= put_z; 160 | //if b is zero return NaN 161 | if (($signed(b_e) == -127) && (b_m == 0)) begin 162 | z[31] <= 1; 163 | z[30:23] <= 255; 164 | z[22] <= 1; 165 | z[21:0] <= 0; 166 | state <= put_z; 167 | end 168 | //if b is zero return inf 169 | end else if (($signed(b_e) == -127) && (b_m == 0)) begin 170 | z[31] <= a_s ^ b_s; 171 | z[30:23] <= 255; 172 | z[22:0] <= 0; 173 | state <= put_z; 174 | end else begin 175 | //Denormalised Number 176 | if ($signed(a_e) == -127) begin 177 | a_e <= -126; 178 | end else begin 179 | a_m[23] <= 1; 180 | end 181 | //Denormalised Number 182 | if ($signed(b_e) == -127) begin 183 | b_e <= -126; 184 | end else begin 185 | b_m[23] <= 1; 186 | end 187 | state <= normalise_a; 188 | end 189 | end 190 | 191 | normalise_a: 192 | begin 193 | if (a_m[23]) begin 194 | state <= normalise_b; 195 | end else begin 196 | a_m <= a_m << 1; 197 | a_e <= a_e - 1; 198 | end 199 | end 200 | 201 | normalise_b: 202 | begin 203 | if (b_m[23]) begin 204 | state <= divide_0; 205 | end else begin 206 | b_m <= b_m << 1; 207 | b_e <= b_e - 1; 208 | end 209 | end 210 | 211 | divide_0: 212 | begin 213 | z_s <= a_s ^ b_s; 214 | z_e <= a_e - b_e; 215 | quotient <= 0; 216 | remainder <= 0; 217 | count <= 0; 218 | dividend <= a_m << 27; 219 | divisor <= b_m; 220 | state <= divide_1; 221 | end 222 | 223 | divide_1: 224 | begin 225 | quotient <= quotient << 1; 226 | remainder <= remainder << 1; 227 | remainder[0] <= dividend[50]; 228 | dividend <= dividend << 1; 229 | state <= divide_2; 230 | end 231 | 232 | divide_2: 233 | begin 234 | if (remainder >= divisor) begin 235 | quotient[0] <= 1; 236 | remainder <= remainder - divisor; 237 | end 238 | if (count == 49) begin 239 | state <= divide_3; 240 | end else begin 241 | count <= count + 1; 242 | state <= divide_1; 243 | end 244 | end 245 | 246 | divide_3: 247 | begin 248 | z_m <= quotient[26:3]; 249 | guard <= quotient[2]; 250 | round_bit <= quotient[1]; 251 | sticky <= quotient[0] | (remainder != 0); 252 | state <= normalise_1; 253 | end 254 | 255 | normalise_1: 256 | begin 257 | if (z_m[23] == 0 && $signed(z_e) > -126) begin 258 | z_e <= z_e - 1; 259 | z_m <= z_m << 1; 260 | z_m[0] <= guard; 261 | guard <= round_bit; 262 | round_bit <= 0; 263 | end else begin 264 | state <= normalise_2; 265 | end 266 | end 267 | 268 | normalise_2: 269 | begin 270 | if ($signed(z_e) < -126) begin 271 | z_e <= z_e + 1; 272 | z_m <= z_m >> 1; 273 | guard <= z_m[0]; 274 | round_bit <= guard; 275 | sticky <= sticky | round_bit; 276 | end else begin 277 | state <= round; 278 | end 279 | end 280 | 281 | round: 282 | begin 283 | if (guard && (round_bit | sticky | z_m[0])) begin 284 | z_m <= z_m + 1; 285 | if (z_m == 24'hffffff) begin 286 | z_e <=z_e + 1; 287 | end 288 | end 289 | state <= pack; 290 | end 291 | 292 | pack: 293 | begin 294 | z[22 : 0] <= z_m[22:0]; 295 | z[30 : 23] <= z_e[7:0] + 127; 296 | z[31] <= z_s; 297 | if ($signed(z_e) == -126 && z_m[23] == 0) begin 298 | z[30 : 23] <= 0; 299 | end 300 | //if overflow occurs, return inf 301 | if ($signed(z_e) > 127) begin 302 | z[22 : 0] <= 0; 303 | z[30 : 23] <= 255; 304 | z[31] <= z_s; 305 | end 306 | state <= put_z; 307 | end 308 | 309 | put_z: 310 | begin 311 | s_output_z_stb <= 1; 312 | output_z <= z; 313 | if (s_output_z_stb && output_z_ack) begin 314 | s_output_z_stb <= 0; 315 | state <= get_a; 316 | end 317 | end 318 | 319 | endcase 320 | 321 | end 322 | end 323 | assign input_a_ack = s_input_a_ack; 324 | assign input_b_ack = s_input_b_ack; 325 | assign output_z_stb = s_output_z_stb; 326 | // assign output_z = output_z; 327 | 328 | endmodule 329 | 330 | -------------------------------------------------------------------------------- /exponential.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define DATALENGTH 32 3 | `define INPUTMAX 5 4 | `define IDLE 2'b00 5 | `define INPUTSTREAM 2'b01 6 | `define OP 2'b10 7 | module exponential ( 8 | input wire Clock, 9 | input wire Reset, 10 | input wire Str, 11 | input wire [`DATALENGTH-1:0] Datain, 12 | output reg Ack, 13 | output reg [`DATALENGTH-1:0] DataOut 14 | 15 | ); 16 | wire [`DATALENGTH-1:0] one, oversix, half; 17 | //reg [`DATALENGTH-1:0] T0R,T1R,T2R,TsR,TdR,TcR, DoR; 18 | reg [`DATALENGTH-1:0] Count; 19 | reg [`DATALENGTH-1:0] T0; 20 | wire [`DATALENGTH-1:0] T1,T2,Ts,Td,Tc,To,Tsh; 21 | wire wa_add_1,wb_add_1,wz_add_1; 22 | wire wa_add_2,wb_add_2,wz_add_2; 23 | wire wa_add_3,wb_add_3,wz_add_3; 24 | wire wa_mul_1,wb_mul_1,wz_mul_1; 25 | wire wa_mul_2,wb_mul_2,wz_mul_2; 26 | wire wa_sh_1,wb_sh_1,wz_sh_1; 27 | wire wa_div_1,wb_div_1,wz_div_1; 28 | 29 | assign one = 32'h3f800000; 30 | assign oversix = 32'h3e2aaaab ; 31 | assign half = 32'h3f000000; 32 | 33 | adder A1 ( 34 | one, 35 | T0, 36 | Str, 37 | Str, 38 | Str, 39 | Clock, 40 | Reset, 41 | T1, 42 | wz_add_1, 43 | wa_add_1, 44 | wb_add_1); 45 | multiplier Ms ( 46 | T0, 47 | T0, 48 | wa_add_1, 49 | wb_add_1, 50 | wz_add_1, 51 | Clock, 52 | Reset, 53 | Ts, 54 | wz_mul_1, 55 | wa_mul_1, 56 | wb_mul_1); 57 | multiplier Msh ( 58 | half, 59 | Ts, 60 | wa_mul_1, 61 | wb_mul_1, 62 | wz_mul_1, 63 | Clock, 64 | Reset, 65 | Tsh, 66 | wz_sh_1, 67 | wa_sh_1, 68 | wb_sh_1); 69 | adder A2 ( 70 | T1, 71 | Tsh, 72 | wa_sh_1, 73 | wb_sh_1, 74 | wz_sh_1, 75 | Clock, 76 | Reset, 77 | T2, 78 | wz_add_2, 79 | wa_add_2, 80 | wb_add_2); 81 | 82 | multiplier Mc ( 83 | Ts, 84 | Ts, 85 | wa_add_2, 86 | wb_add_2, 87 | wz_add_2, 88 | Clock, 89 | Reset, 90 | Tc, 91 | wz_mul_2, 92 | wa_mul_2, 93 | wb_mul_2); 94 | 95 | multiplier Dm ( 96 | Tc, 97 | oversix, 98 | wa_mul_2, 99 | wb_mul_2, 100 | wz_mul_2, 101 | Clock, 102 | Reset, 103 | Td, 104 | wz_div_1, 105 | wa_div_1, 106 | wb_div_1 107 | ); 108 | 109 | adder A3 ( 110 | Td, 111 | T2, 112 | wa_div_1, 113 | wb_div_1, 114 | wz_div_1, 115 | Clock, 116 | Reset, 117 | To, 118 | wz_add_3, 119 | wa_add_3, 120 | wb_add_3); 121 | integer i; 122 | always @(posedge Clock or negedge Reset) begin 123 | if(Reset) begin 124 | T0 <= 0; 125 | DataOut <= 0; 126 | Ack <= 0; 127 | Count <= 0; 128 | // T1 <= 0; 129 | // T2 <= 0; 130 | // Ts <= 0; 131 | // Tc <= 0; 132 | // Td <= 0; 133 | end else begin 134 | if (Str) begin 135 | T0 <= Datain; 136 | DataOut <= To; 137 | if (Count == 140) 138 | Ack <= 1; 139 | Count <= Count +1; 140 | end 141 | else 142 | T0 <= 32'hz; 143 | 144 | // T1R <= T1; 145 | // TsR <= Ts; 146 | // T2R <= T2; 147 | // TcR <= Tc; 148 | // T1 <= T0 + 1 ; 149 | // Ts <= T0 * T0; 150 | // T2 <= T1 + (Ts >> 2); 151 | // Tc <= Ts* T0; 152 | // DataOut <= T2 + (Tc /6); 153 | 154 | end 155 | end 156 | 157 | endmodule 158 | -------------------------------------------------------------------------------- /exponential_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define DATALENGTH 32 3 | `define INPUTMAX 5 4 | `define IDLE 2'b00 5 | `define INPUTSTREAM 2'b01 6 | `define OP 2'b10 7 | module exponential_tb (); 8 | 9 | reg Clock; 10 | reg Reset; 11 | reg Str; 12 | reg [`DATALENGTH-1:0] Datain; 13 | wire [`DATALENGTH-1:0] DataOut; 14 | wire Ack; 15 | 16 | 17 | exponential DUT (Clock, Reset,Str, Datain ,Ack, DataOut); 18 | 19 | initial begin 20 | Clock = 0; 21 | Reset = 1; 22 | Str = 0; 23 | #10 24 | Reset = 0; 25 | Str = 1; 26 | Datain = 32'h3f800000; 27 | #50 28 | $finish; 29 | end 30 | 31 | always 32 | #1 Clock = ~Clock; 33 | 34 | endmodule -------------------------------------------------------------------------------- /multiplier.v: -------------------------------------------------------------------------------- 1 | //IEEE Floating Point Multiplier (Single Precision) 2 | //Copyright (C) Jonathan P Dawson 2013 3 | //2013-12-12 4 | module multiplier( 5 | input_a, 6 | input_b, 7 | input_a_stb, 8 | input_b_stb, 9 | output_z_ack, 10 | clk, 11 | rst, 12 | output_z, 13 | output_z_stb, 14 | input_a_ack, 15 | input_b_ack); 16 | 17 | input clk; 18 | input rst; 19 | 20 | input [31:0] input_a; 21 | input input_a_stb; 22 | output input_a_ack; 23 | 24 | input [31:0] input_b; 25 | input input_b_stb; 26 | output input_b_ack; 27 | 28 | output reg [31:0] output_z; 29 | output output_z_stb; 30 | input output_z_ack; 31 | 32 | reg s_output_z_stb; 33 | // reg [31:0] output_z; 34 | reg s_input_a_ack; 35 | reg s_input_b_ack; 36 | 37 | reg [3:0] state; 38 | parameter get_a = 4'd0, 39 | get_b = 4'd1, 40 | unpack = 4'd2, 41 | special_cases = 4'd3, 42 | normalise_a = 4'd4, 43 | normalise_b = 4'd5, 44 | multiply_0 = 4'd6, 45 | multiply_1 = 4'd7, 46 | normalise_1 = 4'd8, 47 | normalise_2 = 4'd9, 48 | round = 4'd10, 49 | pack = 4'd11, 50 | put_z = 4'd12; 51 | 52 | reg [31:0] a, b, z; 53 | reg [23:0] a_m, b_m, z_m; 54 | reg [9:0] a_e, b_e, z_e; 55 | reg a_s, b_s, z_s; 56 | reg guard, round_bit, sticky; 57 | reg [49:0] product; 58 | 59 | always @(posedge clk) 60 | begin 61 | 62 | case(state) 63 | 64 | get_a: 65 | begin 66 | s_input_a_ack <= 1; 67 | if (s_input_a_ack && input_a_stb) begin 68 | a <= input_a; 69 | s_input_a_ack <= 0; 70 | state <= get_b; 71 | end 72 | end 73 | 74 | get_b: 75 | begin 76 | s_input_b_ack <= 1; 77 | if (s_input_b_ack && input_b_stb) begin 78 | b <= input_b; 79 | s_input_b_ack <= 0; 80 | state <= unpack; 81 | end 82 | end 83 | 84 | unpack: 85 | begin 86 | a_m <= a[22 : 0]; 87 | b_m <= b[22 : 0]; 88 | a_e <= a[30 : 23] - 127; 89 | b_e <= b[30 : 23] - 127; 90 | a_s <= a[31]; 91 | b_s <= b[31]; 92 | state <= special_cases; 93 | end 94 | 95 | special_cases: 96 | begin 97 | //if a is NaN or b is NaN return NaN 98 | if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin 99 | z[31] <= 1; 100 | z[30:23] <= 255; 101 | z[22] <= 1; 102 | z[21:0] <= 0; 103 | state <= put_z; 104 | //if a is inf return inf 105 | end else if (a_e == 128) begin 106 | z[31] <= a_s ^ b_s; 107 | z[30:23] <= 255; 108 | z[22:0] <= 0; 109 | //if b is zero return NaN 110 | if (($signed(b_e) == -127) && (b_m == 0)) begin 111 | z[31] <= 1; 112 | z[30:23] <= 255; 113 | z[22] <= 1; 114 | z[21:0] <= 0; 115 | end 116 | state <= put_z; 117 | //if b is inf return inf 118 | end else if (b_e == 128) begin 119 | z[31] <= a_s ^ b_s; 120 | z[30:23] <= 255; 121 | z[22:0] <= 0; 122 | //if a is zero return NaN 123 | if (($signed(a_e) == -127) && (a_m == 0)) begin 124 | z[31] <= 1; 125 | z[30:23] <= 255; 126 | z[22] <= 1; 127 | z[21:0] <= 0; 128 | end 129 | state <= put_z; 130 | //if a is zero return zero 131 | end else if (($signed(a_e) == -127) && (a_m == 0)) begin 132 | z[31] <= a_s ^ b_s; 133 | z[30:23] <= 0; 134 | z[22:0] <= 0; 135 | state <= put_z; 136 | //if b is zero return zero 137 | end else if (($signed(b_e) == -127) && (b_m == 0)) begin 138 | z[31] <= a_s ^ b_s; 139 | z[30:23] <= 0; 140 | z[22:0] <= 0; 141 | state <= put_z; 142 | end else begin 143 | //Denormalised Number 144 | if ($signed(a_e) == -127) begin 145 | a_e <= -126; 146 | end else begin 147 | a_m[23] <= 1; 148 | end 149 | //Denormalised Number 150 | if ($signed(b_e) == -127) begin 151 | b_e <= -126; 152 | end else begin 153 | b_m[23] <= 1; 154 | end 155 | state <= normalise_a; 156 | end 157 | end 158 | 159 | normalise_a: 160 | begin 161 | if (a_m[23]) begin 162 | state <= normalise_b; 163 | end else begin 164 | a_m <= a_m << 1; 165 | a_e <= a_e - 1; 166 | end 167 | end 168 | 169 | normalise_b: 170 | begin 171 | if (b_m[23]) begin 172 | state <= multiply_0; 173 | end else begin 174 | b_m <= b_m << 1; 175 | b_e <= b_e - 1; 176 | end 177 | end 178 | 179 | multiply_0: 180 | begin 181 | z_s <= a_s ^ b_s; 182 | z_e <= a_e + b_e + 1; 183 | product <= a_m * b_m * 4; 184 | state <= multiply_1; 185 | end 186 | 187 | multiply_1: 188 | begin 189 | z_m <= product[49:26]; 190 | guard <= product[25]; 191 | round_bit <= product[24]; 192 | sticky <= (product[23:0] != 0); 193 | state <= normalise_1; 194 | end 195 | 196 | normalise_1: 197 | begin 198 | if (z_m[23] == 0) begin 199 | z_e <= z_e - 1; 200 | z_m <= z_m << 1; 201 | z_m[0] <= guard; 202 | guard <= round_bit; 203 | round_bit <= 0; 204 | end else begin 205 | state <= normalise_2; 206 | end 207 | end 208 | 209 | normalise_2: 210 | begin 211 | if ($signed(z_e) < -126) begin 212 | z_e <= z_e + 1; 213 | z_m <= z_m >> 1; 214 | guard <= z_m[0]; 215 | round_bit <= guard; 216 | sticky <= sticky | round_bit; 217 | end else begin 218 | state <= round; 219 | end 220 | end 221 | 222 | round: 223 | begin 224 | if (guard && (round_bit | sticky | z_m[0])) begin 225 | z_m <= z_m + 1; 226 | if (z_m == 24'hffffff) begin 227 | z_e <=z_e + 1; 228 | end 229 | end 230 | state <= pack; 231 | end 232 | 233 | pack: 234 | begin 235 | z[22 : 0] <= z_m[22:0]; 236 | z[30 : 23] <= z_e[7:0] + 127; 237 | z[31] <= z_s; 238 | if ($signed(z_e) == -126 && z_m[23] == 0) begin 239 | z[30 : 23] <= 0; 240 | end 241 | //if overflow occurs, return inf 242 | if ($signed(z_e) > 127) begin 243 | z[22 : 0] <= 0; 244 | z[30 : 23] <= 255; 245 | z[31] <= z_s; 246 | end 247 | state <= put_z; 248 | end 249 | 250 | put_z: 251 | begin 252 | s_output_z_stb <= 1; 253 | output_z <= z; 254 | if (s_output_z_stb && output_z_ack) begin 255 | s_output_z_stb <= 0; 256 | state <= get_a; 257 | end 258 | end 259 | 260 | endcase 261 | 262 | if (rst == 1) begin 263 | state <= get_a; 264 | s_input_a_ack <= 0; 265 | s_input_b_ack <= 0; 266 | s_output_z_stb <= 0; 267 | output_z <= 0; 268 | a <= 0; 269 | b <= 0; 270 | z <= 0; 271 | a_m <= 0; 272 | b_m <= 0; 273 | z_m <= 0; 274 | a_e <= 0; 275 | b_e <= 0; 276 | z_m <= 0; 277 | 278 | end 279 | 280 | end 281 | assign input_a_ack = s_input_a_ack; 282 | assign input_b_ack = s_input_b_ack; 283 | assign output_z_stb = s_output_z_stb; 284 | // assign output_z = output_z; 285 | 286 | endmodule 287 | 288 | -------------------------------------------------------------------------------- /multiplier_tb.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | module multiplier_tb(); 3 | 4 | reg clk; 5 | reg rst; 6 | reg [31:0] input_a; 7 | reg [31:0] input_b; 8 | reg input_a_stb; 9 | reg input_b_stb; 10 | reg output_z_ack; 11 | wire input_a_ack; 12 | wire input_b_ack; 13 | wire output_z_stb; 14 | wire [31:0] output_z; 15 | initial begin 16 | clk = 1; 17 | rst = 1; 18 | input_a_stb = 0; 19 | input_b_stb = 0; 20 | output_z_ack = 0; 21 | #10 22 | rst = 0; 23 | //////////////////////////// 24 | input_a_stb = 1; 25 | input_b_stb = 1; 26 | output_z_ack = 1; 27 | // #5 28 | input_a = 32'h3f000000; 29 | input_b = 32'h00000000; 30 | #80 31 | // input_a_stb = 0; 32 | // input_b_stb = 0; 33 | // output_z_ack = 0; 34 | // #10 35 | //////////////////////////// 36 | 37 | // input_a_stb = 1; 38 | // input_b_stb = 1; 39 | // output_z_ack = 1; 40 | // #5 41 | input_a = 32'h3f000000; 42 | input_b = 32'hbf000000; 43 | #80 44 | // input_a_stb = 0; 45 | // input_b_stb = 0; 46 | // output_z_ack = 0; 47 | // //////////////////////////// 48 | // #10 49 | // input_a_stb = 1; 50 | // input_b_stb = 1; 51 | // output_z_ack = 1; 52 | // #5 53 | input_a = 32'h3f000000; 54 | input_b = 32'h3f800000; 55 | end 56 | 57 | multiplier DUT ( 58 | input_a, 59 | input_b, 60 | input_a_stb, 61 | input_b_stb, 62 | output_z_ack, 63 | clk, 64 | rst, 65 | output_z, 66 | output_z_stb, 67 | input_a_ack, 68 | input_b_ack); 69 | 70 | always 71 | #5 clk = ~clk; 72 | 73 | endmodule // multiplier_tb -------------------------------------------------------------------------------- /softmax.py: -------------------------------------------------------------------------------- 1 | 2 | import math 3 | z = [1.0,1 ,1, 1.0] 4 | z_exp = [math.exp(i) for i in z] 5 | print([round(i, 2) for i in z_exp]) 6 | sum_z_exp = sum(z_exp) 7 | print(round(sum_z_exp, 2)) 8 | 9 | softmax = [round(i / sum_z_exp, 3) for i in z_exp] 10 | print(softmax) 11 | -------------------------------------------------------------------------------- /softmax.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define DATALENGTH 32 3 | `define INPUTMAX 2 4 | `define IDLE 3'b000 5 | `define INPUTSTREAM 3'b001 6 | `define EXP 3'b010 7 | `define ADD 3'b011 8 | `define DIV 3'b100 9 | `define OUTPUTSTREAM 3'b101 10 | `define NUMBER 2'b11 11 | 12 | module softmax( 13 | input wire Clock, 14 | input wire Reset, 15 | input wire Start, 16 | input wire [`DATALENGTH-1:0] Datain, 17 | input wire [`INPUTMAX:0] N, 18 | output reg [`DATALENGTH-1:0] Dataout 19 | ); 20 | 21 | integer m; 22 | // reg [`DATALENGTH-1:0] Dataout; 23 | reg [`DATALENGTH-1:0] InputBuffer[2**`INPUTMAX - 1:0]; 24 | reg [`DATALENGTH-1:0] DivBuffer[2**`INPUTMAX - 1:0]; 25 | 26 | reg [`DATALENGTH-1:0] OutputBuffer[2**`INPUTMAX -1 :0]; 27 | reg [`DATALENGTH-1:0] Acc; 28 | reg [`DATALENGTH-1:0] Arg; 29 | 30 | wire [`DATALENGTH-1:0] Acc_w; 31 | 32 | reg [3:0]Str; 33 | 34 | wire [`DATALENGTH-1:0] InputBuffer_w[2**`INPUTMAX -1 :0]; 35 | wire [`DATALENGTH-1:0] OutputBuffer_w[2**`INPUTMAX -1 :0]; 36 | 37 | wire [3:0]Ack; 38 | reg Str_Add_a; 39 | reg Str_Add_b; 40 | reg Str_Add_z; 41 | 42 | 43 | wire Ack_add1; 44 | wire Ack_add2; 45 | wire Ack_add3; 46 | reg Ack_div1; 47 | reg Ack_div2; 48 | reg Ack_div3; 49 | wire [3:0]Ack_div_a; 50 | wire [3:0]Ack_div_b; 51 | wire [3:0]Ack_div_z; 52 | 53 | reg [`INPUTMAX:0] Counter; 54 | reg [`INPUTMAX:0] C,C_add; 55 | 56 | reg [2:0] NextState; 57 | 58 | genvar i; 59 | generate 60 | for (i = 0; i <= 2**`INPUTMAX -1; i = i +1) begin 61 | exponential exp ( 62 | Clock, 63 | Reset, 64 | Str[i], 65 | InputBuffer[i], 66 | Ack[i], 67 | InputBuffer_w[i] 68 | ) ; 69 | end 70 | endgenerate 71 | 72 | // genvar j; 73 | // generate 74 | // for (j = 0; j < `NUMBER; j= j+1) begin 75 | 76 | 77 | adder add ( 78 | Arg, 79 | Acc, 80 | Str_Add_a, 81 | Str_Add_b, 82 | Str_Add_z, 83 | Clock, 84 | Reset, 85 | Acc_w, 86 | Ack_add3, 87 | Ack_add1, 88 | Ack_add2 89 | ) ; 90 | // end 91 | // endgenerate 92 | 93 | 94 | genvar k; 95 | generate 96 | for (k = 0; k <= 2**`INPUTMAX -1; k= k+1) begin 97 | divider div ( 98 | DivBuffer[k], 99 | Acc, 100 | Ack_div1, 101 | Ack_div2, 102 | Ack_div3, 103 | Clock, 104 | Reset, 105 | OutputBuffer_w[k], 106 | Ack_div_z[k], 107 | Ack_div_a[k], 108 | Ack_div_a[k] 109 | ) ; 110 | end 111 | endgenerate 112 | 113 | 114 | always @(posedge Clock or negedge Reset) begin 115 | if (Reset) begin 116 | // reset 117 | for (m = 0; m <= 2**`INPUTMAX -1;m = m+1)begin 118 | InputBuffer[m] <= 0; 119 | OutputBuffer[m] <= 0; 120 | DivBuffer[m] <= 0; 121 | end 122 | Counter <= 0; 123 | C <= 0; 124 | Arg <= 0; 125 | C_add <= 0; 126 | Dataout <= 0; 127 | Acc <= 0; 128 | Str <= 0; 129 | Ack_div1 <=0; 130 | Ack_div2 <=0; 131 | Ack_div3 <=0; 132 | Str_Add_a <= 0; 133 | Str_Add_b <= 0; 134 | Str_Add_z <= 0; 135 | NextState <= `IDLE; 136 | 137 | end 138 | else begin 139 | case(NextState) 140 | 141 | `IDLE: begin 142 | if (Start) 143 | NextState <= `INPUTSTREAM; 144 | else 145 | NextState <= `IDLE; 146 | 147 | end 148 | 149 | `INPUTSTREAM: begin 150 | if (Counter <= N) begin 151 | InputBuffer[Counter] <= Datain; 152 | Counter <= Counter + 1; 153 | NextState <= `INPUTSTREAM; 154 | end 155 | else begin 156 | NextState <= `EXP; 157 | Str <= 4'b1111; 158 | end 159 | end 160 | 161 | `EXP: begin 162 | if(Ack == 4'b1111)begin 163 | for (m = 0; m <= N;m = m+1) 164 | DivBuffer[m] <= InputBuffer_w[m]; 165 | NextState <= `ADD; 166 | Str_Add_a <= 1 ; 167 | Str_Add_b <= 1 ; 168 | Str_Add_z <= 1 ; 169 | end 170 | else begin 171 | NextState <= `EXP; 172 | end 173 | end 174 | 175 | `ADD: begin 176 | if (Ack_add2 || Ack_add1 || Ack_add3) begin 177 | C_add <= C_add + 1; 178 | end 179 | if (C < 2**`INPUTMAX+1 ) begin 180 | Arg <= DivBuffer[C]; 181 | if (C_add == 4) begin 182 | Acc <= Acc_w; 183 | C <= C+1; 184 | C_add <= 0; 185 | end 186 | 187 | NextState <= `ADD; 188 | end 189 | else begin 190 | Str_Add_a <= 1 ; 191 | Str_Add_b <= 1 ; 192 | Str_Add_z <= 1 ; 193 | 194 | NextState <= `DIV; 195 | end 196 | end 197 | 198 | `DIV: begin 199 | Ack_div1 <= 1; 200 | Ack_div2 <= 1; 201 | Ack_div3 <= 1; 202 | if (Ack_div_z == 4'b1111) begin 203 | for (m = 0; m < N;m = m+1)begin 204 | OutputBuffer[m] <= OutputBuffer_w[m]; 205 | end 206 | NextState <= `OUTPUTSTREAM; 207 | end 208 | else 209 | NextState <= `DIV; 210 | 211 | end 212 | 213 | `OUTPUTSTREAM: begin 214 | Counter <= Counter - 1; 215 | if (Counter != 0) begin 216 | Dataout <= OutputBuffer[Counter]; 217 | NextState <= `OUTPUTSTREAM; 218 | end 219 | else begin 220 | NextState <= `IDLE; 221 | end 222 | end 223 | 224 | default: begin 225 | NextState <= `IDLE; 226 | end 227 | 228 | endcase 229 | end 230 | end 231 | 232 | endmodule 233 | -------------------------------------------------------------------------------- /softmax_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define DATALENGTH 32 3 | `define INPUTMAX 5 4 | `define IDLE 2'b00 5 | `define INPUTSTREAM 2'b01 6 | `define OP 2'b10 7 | `define OUTPUTSTREAM 2'b11 8 | `define NUMBER 3'b101 9 | 10 | module softmax_tb( 11 | ); 12 | reg Clock; 13 | reg Reset; 14 | reg Start; 15 | reg [`DATALENGTH-1:0] Datain; 16 | reg [`INPUTMAX-1:0] N; 17 | wire [`DATALENGTH-1:0] Dataout; 18 | 19 | 20 | 21 | softmax DUT (Clock, Reset, Start, Datain,N, Dataout); 22 | 23 | initial begin 24 | Clock = 1; 25 | Reset = 1; 26 | N = 3; 27 | #10 28 | Start = 1; 29 | Reset = 0; 30 | Datain = 32'h3f800000; 31 | #2 32 | Datain = 32'h3f800000; 33 | #2 34 | Datain = 32'h3f800000; 35 | #2 36 | Datain = 32'h3f800000; 37 | 38 | Start = 0; 39 | #2000 40 | $finish; 41 | end 42 | 43 | always 44 | #1 Clock = ~Clock; 45 | 46 | endmodule 47 | -------------------------------------------------------------------------------- /waveform/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/1.png -------------------------------------------------------------------------------- /waveform/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/2.png -------------------------------------------------------------------------------- /waveform/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/3.png -------------------------------------------------------------------------------- /waveform/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/4.png -------------------------------------------------------------------------------- /waveform/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/5.png -------------------------------------------------------------------------------- /waveform/Capture.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/Capture.PNG -------------------------------------------------------------------------------- /waveform/a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/a.png -------------------------------------------------------------------------------- /waveform/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/add.png -------------------------------------------------------------------------------- /waveform/adder_tb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/adder_tb.png -------------------------------------------------------------------------------- /waveform/b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/b.png -------------------------------------------------------------------------------- /waveform/c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/c.png -------------------------------------------------------------------------------- /waveform/exp_tb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/exp_tb.png -------------------------------------------------------------------------------- /waveform/graph.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/graph.PNG -------------------------------------------------------------------------------- /waveform/mul_tb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/mul_tb.png -------------------------------------------------------------------------------- /waveform/sc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/sc1.png -------------------------------------------------------------------------------- /waveform/schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/schematic.png -------------------------------------------------------------------------------- /waveform/smax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/smax.png -------------------------------------------------------------------------------- /waveform/softmax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomran/softmax/330a16712d44a0195011710e24b65e7732e784b0/waveform/softmax.png --------------------------------------------------------------------------------