├── README.md ├── accelerator.v ├── accelerator_tb.v ├── comparator2.v ├── control_logic2.v ├── convolver.v ├── convolver_tb.v ├── input_mux.v ├── mac_manual.v ├── max_reg.v ├── pooler.v ├── qadd.v ├── qmult.v ├── relu.v ├── tanh_data.mem ├── tanh_lut.v └── variable_shift_reg.v /README.md: -------------------------------------------------------------------------------- 1 | # fpga-ml-accelerator 2 | This repository hosts the code for an FPGA based accelerator for convolutional neural networks 3 | a very detailed account of the entire design and design principles is present at https://thedatabus.in/introduction . 4 | -------------------------------------------------------------------------------- /accelerator.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define FIXED_POINT 1 3 | module acclerator #( 4 | parameter n = 9'h00a, //size of the input image/activation map 5 | parameter k = 9'h003, //size of the convolution window 6 | parameter p = 9'h002, //size of the pooling window 7 | parameter s = 1, //stride value during convolution 8 | parameter ptype = 1, //0 => average pooling , 1 => max_pooling 9 | parameter act_type = 0,//0 => ReLu activation function, 1=> Hyperbolic tangent activation function 10 | parameter N = 16, //Bit width of activations and weights (total datapath width) 11 | parameter Q = 12, //Number of fractional bits in case of fixed point representation 12 | parameter AW = 10, //Needed in case of tanh activation function to set the size or ROM 13 | parameter DW = 16, //Datapath width = N 14 | parameter p_sqr_inv = 16'b0000010000000000 // = 1/p**2 in the (N,Q) format being used currently 15 | )( 16 | input clk, 17 | input global_rst, 18 | input ce, 19 | input [15:0] activation, 20 | input [(k*k)*16-1:0] weight1, 21 | output [15:0] data_out, 22 | output valid_op, 23 | output end_op, 24 | output [15:0] conv_out, 25 | output conv_valid, 26 | output conv_end 27 | ); 28 | 29 | wire [N-1:0] conv_op; 30 | wire valid_conv,end_conv; 31 | wire valid_ip; 32 | wire [N-1:0] relu_op; 33 | wire [N-1:0] tanh_op; 34 | wire [N-1:0] pooler_ip; 35 | wire [N-1:0] pooler_op; 36 | reg [N-1:0] pooler_op_reg; 37 | 38 | convolver #(.n(n),.k(k),.s(s),.N(N),.Q(Q)) conv(//Convolution engine 39 | .clk(clk), 40 | .ce(ce), 41 | .weight1(weight1), 42 | .global_rst(global_rst), 43 | .activation(activation), 44 | .conv_op(conv_op), 45 | .end_conv(end_conv), 46 | .valid_conv(valid_conv) 47 | ); 48 | assign conv_valid = valid_conv; 49 | assign conv_end = end_conv; 50 | assign conv_out = conv_op; 51 | 52 | assign valid_ip = valid_conv && (!end_conv); 53 | 54 | relu #(.N(N)) act( // ReLu Activation function 55 | .din_relu(conv_op), 56 | .dout_relu(relu_op) 57 | ); 58 | 59 | tanh_lut #(.AW(AW),.DW(DW),.N(N),.Q(Q)) tanh( //Hyperbolic Tangent Activation function 60 | .clk(clk), 61 | .rst(global_rst), 62 | .phase(conv_op), 63 | .tanh(tanh_op) 64 | ); 65 | 66 | assign pooler_ip = act_type ? tanh_op : relu_op; //alternatively you could use macros to save resources when using ReLu 67 | 68 | pooler #(.N(N),.Q(Q),.m(n-k+1),.p(p),.ptype(ptype),.p_sqr_inv(p_sqr_inv)) pool( //Pooling Unit 69 | .clk(clk), 70 | .ce(valid_ip), 71 | .master_rst(global_rst), 72 | .data_in(pooler_ip), 73 | .data_out(pooler_op), 74 | .valid_op(valid_op), 75 | .end_op(end_op) 76 | ); 77 | 78 | assign data_out = pooler_op; 79 | 80 | endmodule -------------------------------------------------------------------------------- /accelerator_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define FIXED_POINT 1 3 | module accelerator_tb; 4 | 5 | // Inputs 6 | reg clk; 7 | reg ce; 8 | reg [143:0] weight1; 9 | reg global_rst; 10 | reg [15:0] activation; 11 | 12 | // Outputs 13 | wire [15:0] acc_op,conv_out; 14 | wire conv_valid,conv_end; 15 | wire end_op; 16 | wire valid_op; 17 | integer i; 18 | parameter clkp = 20; 19 | integer ip_file,r3,op_file; 20 | // Instantiate the Unit Under Test (UUT) 21 | acclerator #(.n('d6),.p('d2),.k('d3),.N('d16),.Q('d12),.ptype('d0),.s('d1),.psqr_inv(16'b0000010000000000)) uut ( 22 | .clk(clk), 23 | .ce(ce), 24 | .weight1(weight1), 25 | .global_rst(global_rst), 26 | .activation(activation), 27 | .data_out(acc_op), 28 | .valid_op(valid_op), 29 | .end_op(end_op), 30 | .conv_out(conv_out), 31 | .conv_valid(conv_valid), 32 | .conv_end(conv_end) 33 | ); 34 | 35 | initial begin 36 | // Initialize Inputs 37 | clk = 0; 38 | ce = 0; 39 | weight1 = 0; 40 | global_rst = 0; 41 | activation = 0; 42 | 43 | // Wait 100 ns for global reset to finish 44 | #100; 45 | 46 | clk = 0; 47 | ce = 0; 48 | weight1 = 0; 49 | activation = 0; 50 | global_rst =1; 51 | #60; 52 | global_rst =0; 53 | //#10; 54 | ce=1; 55 | ip_file = $fopen("activations.txt","r"); 56 | op_file = $fopen("acc_out.txt","a"); 57 | `ifdef FIXED_POINT 58 | weight1 = 144'b1111100110010111_0000001111010001_1111011010001101_1111101010010011_1111110101110100_1111110111101111_0000000110010110_1111000011010101_1111110111110100; 59 | `else 60 | weight1 = 144'h0008_0007_0006_0005_0004_0003_0002_0001_0000; 61 | `endif 62 | // Initialize Inputs 63 | for(i=0;i<36;i=i+1) begin 64 | `ifdef FIXED_POINT 65 | r3 = $fscanf(ip_file,"%b\n",activation); 66 | `else 67 | activation = i; 68 | `endif 69 | #clkp; 70 | end 71 | end 72 | always #(clkp/2) clk = ~clk; 73 | 74 | always@(posedge clk) begin 75 | if(valid_op & !end_op) begin 76 | $fdisplay(op_file,"%b",acc_op); 77 | end 78 | if(conv_end) begin 79 | if(ce) 80 | begin 81 | $fdisplay(op_file,"%s%0d","end",0); 82 | $finish; 83 | end 84 | end 85 | end 86 | endmodule -------------------------------------------------------------------------------- /comparator2.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module comparator2 #( 4 | parameter N = 16, 5 | parameter Q = 12, 6 | parameter ptype = 1 7 | )( 8 | input ce, 9 | input [N-1:0] ip1, 10 | input [N-1:0] ip2, 11 | output [N-1:0] comp_op 12 | ); 13 | 14 | wire [N-1:0] ip1_2cmp, ip2_2cmp; //two's complemented versions of the input values 15 | reg [N-1:0] temp; 16 | 17 | 18 | assign ip1_2cmp = {~ip1[N-1],~ip1[N-2:0] + 1'b1}; 19 | assign ip2_2cmp = {~ip2[N-1],~ip2[N-2:0] + 1'b1}; 20 | assign comp_op = ce ? temp : 'd0; 21 | //assign comp_op = ptype ? (ip1 + ip2) : ((ip1>ip2) ? ip1:ip2); 22 | always@(*) 23 | begin 24 | if(ptype == 0) 25 | begin 26 | temp = ip1 + ip2; //when in the average pooling mode, the comparator doubles up as the adder 27 | end 28 | else 29 | begin 30 | if( (ip1[N-1] == 0) & (ip2[N-1] == 0) ) 31 | begin 32 | temp = (ip1>ip2) ? ip1:ip2; 33 | end 34 | else if ( (ip1[N-1] == 1) & (ip2[N-1] == 1) ) 35 | begin 36 | temp = (ip1_2cmp > ip2_2cmp) ? ip2 : ip1; //higher the magnitude of a -ve no. lower its value 37 | end 38 | else if ( (ip1[N-1] == 1) & (ip2[N-1] == 0) ) 39 | begin 40 | temp = ip2; 41 | end 42 | else if ( (ip1[N-1] == 0) & (ip2[N-1] == 1) ) 43 | begin 44 | temp = ip1; 45 | end 46 | end 47 | end 48 | endmodule -------------------------------------------------------------------------------- /control_logic2.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | //1. normal case : just store the max value in the register. 4 | //2. end of one neighbourhood: store the max value to the shift register. 5 | //3. end of row: store the max value in the shift register and then load the max register from the shift register. 6 | //4. end of neighbourhood in the last row: make output valid and store the max value in the max register. 7 | //5. end of last neighbourhood of last row: make op valid and store the max value in the max register and then reset the entire module. 8 | 9 | //SIGNALS TO BE HANDLED IN EACH CASE 10 | //CASE 1 2 3 4 5 11 | //1. load _sr low high high high low 12 | //2. sel low low high high low 13 | //3. rst_m low high low low low 14 | //4. op_en low low low high high 15 | //5. global_rst low low low low high 16 | 17 | module control_logic2( 18 | input clk, 19 | input master_rst, 20 | input ce, 21 | output reg [1:0] sel, 22 | output reg rst_m, 23 | output reg op_en, 24 | output reg load_sr, 25 | output reg global_rst, 26 | output reg end_op 27 | ); 28 | 29 | parameter m = 9'h01a; 30 | parameter p = 9'h002; 31 | integer row_count =0; 32 | integer col_count =0; 33 | integer count =0; 34 | integer nbgh_row_count; 35 | 36 | always@(posedge clk) begin 37 | if(master_rst) begin 38 | sel <=0; 39 | load_sr <=0; 40 | rst_m <=0; 41 | op_en <=0; 42 | global_rst <=0; 43 | end_op <=0; 44 | end 45 | else begin 46 | if(((col_count+1)%p !=0)&&(row_count == p-1)&&(col_count == p*count + (p-2))&&ce) //op_en 47 | begin 48 | op_en <=1; 49 | end 50 | else begin 51 | op_en <=0; 52 | end 53 | if(ce) 54 | begin 55 | if(nbgh_row_count == m/p) //end_op 56 | begin 57 | end_op <=1; 58 | end 59 | else 60 | begin 61 | end_op <=0; 62 | end 63 | 64 | if(((col_count+1) % p != 0)&&(col_count == m-2)&&(row_count == p-1)) //global_rst and pause_ip 65 | begin 66 | global_rst <= 1; // (reset everything) 67 | end 68 | else 69 | begin 70 | global_rst <= 0; 71 | end 72 | 73 | 74 | 75 | //end 76 | 77 | if((((col_count+1) % p == 0)&&(count != m/p-1)&&(row_count != p-1))||((col_count == m-1)&&(row_count == p-1))) //rst_m 78 | begin 79 | rst_m <= 1; 80 | end 81 | else 82 | begin 83 | rst_m <= 0; 84 | end 85 | 86 | if(((col_count+1) % p != 0)&&(col_count == m-2)&&(row_count == p-1)) 87 | begin 88 | sel <= 2'b10; 89 | end 90 | else 91 | begin 92 | if((((col_count) % p == 0)&&(count == m/p-1)&&(row_count != p-1))|| (((col_count) % p == 0)&&(count != m/p-1)&&(row_count == p-1))) begin //sel 93 | sel<=2'b01; 94 | end 95 | else 96 | begin 97 | sel <= 2'b00; 98 | end 99 | end 100 | 101 | if((((col_count+1) % p == 0)&&((count == m/p-1)))||((col_count+1) % p == 0)&&((count != m/p-1))) //load_sr 102 | begin 103 | load_sr <= 1; //&&(row_count!=p-1) 104 | end 105 | else 106 | begin 107 | load_sr <= 0; 108 | end 109 | end 110 | end 111 | end 112 | 113 | always@(posedge clk) begin //counters 114 | if(master_rst) begin 115 | row_count <=0; 116 | col_count <=32'hffffffff; 117 | count <=32'hffffffff; 118 | nbgh_row_count <=0; 119 | end 120 | else 121 | begin 122 | if(ce) 123 | begin 124 | if(global_rst) 125 | begin 126 | row_count <=0; 127 | col_count <=32'h0;//ffffffff; 128 | count <=32'h0;//ffffffff; 129 | nbgh_row_count <= nbgh_row_count + 1'b1; 130 | end 131 | else 132 | begin 133 | if(((col_count+1) % p == 0)&&(count == m/p-1)&&(row_count != p-1)) //col_count and row_count 134 | begin 135 | col_count <= 0; 136 | row_count <= row_count + 1'b1; 137 | count <=0; 138 | end 139 | else 140 | begin 141 | col_count<=col_count+1'b1; 142 | if(((col_count+1) % p == 0)&&(count != m/p-1)) 143 | begin 144 | count <= count+ 1'b1; 145 | end 146 | end 147 | end 148 | end 149 | end 150 | end 151 | endmodule 152 | -------------------------------------------------------------------------------- /convolver.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define FIXED_POINT 1 3 | module convolver #( 4 | parameter n = 9'h00a, // activation map size 5 | parameter k = 9'h003, // kernel size 6 | parameter s = 1, // value of stride (horizontal and vertical stride are equal) 7 | parameter N = 16, //total bit width 8 | parameter Q = 12 //number of fractional bits in case of fixed point representation. 9 | )( 10 | input clk, 11 | input ce, 12 | input global_rst, 13 | input [N-1:0] activation, 14 | input [(k*k)*16-1:0] weight1, 15 | output[N-1:0] conv_op, 16 | output valid_conv, 17 | output end_conv 18 | ); 19 | 20 | wire [N-1:0] weight [0:k*k-1]; 21 | wire [N-1:0] tmp [k*k+1:0]; 22 | wire conv_vld; 23 | reg conv_vld_d1; 24 | 25 | generate 26 | genvar l; 27 | for(l=0;l= n*n+2) ? 1'b1 : 1'b0; 153 | 154 | always@(posedge clk or posedge global_rst) 155 | begin 156 | if(global_rst) 157 | conv_vld_d1<= 0; 158 | else 159 | conv_vld_d1 <= conv_vld; 160 | end 161 | 162 | `ifdef FIXED_POINT 163 | assign valid_conv = conv_vld_d1; 164 | `else 165 | assign valid_conv = conv_vld; 166 | `endif 167 | 168 | endmodule -------------------------------------------------------------------------------- /convolver_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module convolver_tb; 4 | 5 | // Inputs 6 | reg clk; 7 | reg ce; 8 | reg [143:0] weight1; 9 | reg global_rst; 10 | reg [15:0] activation; 11 | 12 | // Outputs 13 | wire [31:0] conv_op; 14 | wire end_conv; 15 | wire valid_conv; 16 | integer i; 17 | parameter clkp = 40; 18 | // Instantiate the Unit Under Test (UUT) 19 | convolver #(9'h004,9'h003,1) uut ( 20 | .clk(clk), 21 | .ce(ce), 22 | .weight1(weight1), 23 | .global_rst(global_rst), 24 | .activation(activation), 25 | .conv_op(conv_op), 26 | .end_conv(end_conv), 27 | .valid_conv(valid_conv) 28 | ); 29 | 30 | initial begin 31 | // Initialize Inputs 32 | clk = 0; 33 | ce = 0; 34 | weight1 = 0; 35 | global_rst = 0; 36 | activation = 0; 37 | 38 | // Wait 100 ns for global reset to finish 39 | #100; 40 | 41 | clk = 0; 42 | ce = 0; 43 | weight1 = 0; 44 | activation = 0; 45 | global_rst =1; 46 | #50; 47 | global_rst =0; 48 | #10; 49 | ce=1; 50 | weight1 = 144'h0008_0007_0006_0005_0004_0003_0002_0001_0000; 51 | // Initialize Inputs 52 | for(i=0;i<255;i=i+1) begin 53 | activation = i; 54 | #clkp; 55 | end 56 | end 57 | always #(clkp/2) clk=~clk; 58 | endmodule -------------------------------------------------------------------------------- /input_mux.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module input_mux #(parameter N = 16)( 4 | input [N-1:0] ip1, 5 | input [N-1:0] ip2, 6 | input [1:0] sel, 7 | output [N-1:0] op 8 | ); 9 | assign op = (sel == 2'b01) ? ip1 : ((sel == 2'b00) ? ip2: 0); 10 | endmodule 11 | -------------------------------------------------------------------------------- /mac_manual.v: -------------------------------------------------------------------------------- 1 | //`define FIXED_POINT 1 2 | module mac_manual #(parameter N = 16,parameter Q = 12)( 3 | input clk,sclr,ce, 4 | input [N-1:0] a, 5 | input [N-1:0] b, 6 | input [N-1:0] c, 7 | output [N-1:0] p 8 | ); 9 | 10 | `ifdef FIXED_POINT 11 | wire [N-1:0] mult,add; 12 | reg [N-1:0] tmp; 13 | wire ovr; 14 | qmult #(N,Q) mul ( 15 | .clk(clk), 16 | .rst(sclr), 17 | .a(a), 18 | .b(b), 19 | .q_result(mult), 20 | .overflow(ovr) 21 | ); 22 | qadd #(N,Q) add1 ( 23 | .a(mult), 24 | .b(c), 25 | .c(add) 26 | ); 27 | 28 | always@(posedge clk,posedge sclr) 29 | begin 30 | if(sclr) 31 | begin 32 | tmp <= 0; 33 | end 34 | else if(ce) 35 | begin 36 | tmp <= add; 37 | end 38 | end 39 | assign p = tmp; 40 | `else 41 | reg [N-1:0] temp; 42 | always@(posedge clk,posedge sclr) 43 | begin 44 | if(sclr) 45 | begin 46 | temp <= 0; 47 | end 48 | else if(ce) 49 | begin 50 | temp <= (a*b+c); 51 | end 52 | end 53 | assign p = temp; 54 | `endif 55 | endmodule -------------------------------------------------------------------------------- /max_reg.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module max_reg #(parameter N = 16) ( 3 | input clk, 4 | input ce, 5 | input [N-1:0] din, 6 | input rst_m, 7 | input master_rst, 8 | output reg [N-1:0] reg_op 9 | ); 10 | 11 | always@(posedge clk) 12 | begin 13 | if(master_rst) 14 | reg_op <= 0; 15 | else 16 | begin 17 | if(ce) 18 | begin 19 | if(rst_m) begin 20 | reg_op <=0; 21 | end 22 | else begin 23 | reg_op <= din; 24 | end 25 | end 26 | end 27 | end 28 | endmodule -------------------------------------------------------------------------------- /pooler.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module pooler #( 4 | parameter m = 9'h00c, 5 | parameter p = 9'h003, 6 | parameter N = 16, 7 | parameter Q = 12, 8 | parameter ptype = 1, //0-> average pooling, 1 -> max pooling 9 | parameter p_sqr_inv = 16'b0000010000000000 //this parameter is needed in average pooling case where the sum is divided by p**2. 10 | //It needs to be supplied manually and should be equal to (1/p)^2 in whatever the 11 | //(Q,N) format is being used. 12 | )( 13 | input clk, 14 | input ce, 15 | input master_rst, 16 | input [N-1:0] data_in, 17 | output [N-1:0] data_out, 18 | output valid_op, //output signal to indicate the valid output 19 | output end_op //output signal to indicate when all the valid outputs have been 20 | //produced for that particular input matrix 21 | ); 22 | 23 | wire rst_m,load_sr,global_rst;//op_en,pause_ip, 24 | wire [1:0] sel; 25 | wire [N-1:0] comp_op; 26 | wire [N-1:0] sr_op; 27 | wire [N-1:0] max_reg_op; 28 | wire [N-1:0] div_op; 29 | wire ovr; 30 | wire [N-1:0] mux_out; 31 | //reg [N-1:0] temp; 32 | 33 | control_logic2 #(m,p) log( 34 | clk, 35 | master_rst, 36 | ce, 37 | sel, 38 | rst_m, 39 | valid_op, 40 | load_sr, 41 | global_rst, 42 | end_op 43 | ); 44 | 45 | comparator2 #(.N(N),.ptype(ptype)) cmp( 46 | ce, 47 | data_in, 48 | mux_out, 49 | comp_op 50 | ); 51 | 52 | max_reg #(.N(N)) m1( 53 | clk, 54 | ce, 55 | comp_op, 56 | rst_m, 57 | master_rst, 58 | max_reg_op 59 | ); 60 | 61 | variable_shift_reg #(.WIDTH(N),.SIZE((m/p))) SR ( 62 | .d(comp_op), 63 | .clk(clk), 64 | .ce(load_sr), 65 | .rst(global_rst && master_rst), 66 | .out(sr_op) 67 | ); 68 | 69 | input_mux #(.N(N)) mux(sr_op,max_reg_op,sel,mux_out); 70 | 71 | qmult #(N,Q) mul (clk,rst_m,max_reg_op,p_sqr_inv,div_op,ovr); 72 | 73 | assign data_out = ptype ? max_reg_op : div_op; //for average pooling, we output the sum divided by p**2 74 | endmodule 75 | -------------------------------------------------------------------------------- /qadd.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module qadd #( 3 | parameter N = 16, 4 | parameter Q = 12 5 | ) 6 | ( 7 | input [N-1:0] a, 8 | input [N-1:0] b, 9 | output [N-1:0] c 10 | ); 11 | 12 | // (Q,N) = (12,16) => 1 sign-bit + 3 integer-bits + 12 fractional-bits = 16 total-bits 13 | // |S|III|FFFFFFFFFFFF| 14 | // The same thing in A(I,F) format would be A(3,12) 15 | 16 | //Since we supply every negative number in it's 2's complement form by default, all we 17 | //need to do is add these two numbers together (note that to subtract a binary number 18 | //is the same as to add its two's complement) 19 | assign c = a + b; 20 | 21 | //If for whatever reason your system (the software/testbench feeding this hadrware with 22 | //inputs) does not supply negative numbers in their two's complement form,(some people 23 | //prefer to keep the magnitude as it is and make the sign bit '1' to represent negatives) 24 | // then you should take a look at the fixed point arithmetic modules at opencores linked 25 | //above this code. 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /qmult.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // (Q,N) = (12,16) => 1 sign-bit + 3 integer-bits + 12 fractional-bits = 16 total-bits 3 | // |S|III|FFFFFFFFFFFF| 4 | // The same thing in A(I,F) format would be A(3,12) 5 | module qmult #( 6 | //Parameterized values 7 | parameter N = 16, 8 | parameter Q = 12 9 | ) 10 | ( 11 | input clk, 12 | input rst, 13 | input [N-1:0] a, 14 | input [N-1:0] b, 15 | output [N-1:0] q_result, //output quantized to same number of bits as the input 16 | output overflow //signal to indicate output greater than the range of our format 17 | ); 18 | 19 | // The underlying assumption, here, is that both fixed-point values are of the same length (N,Q) 20 | // Because of this, the results will be of length N+N = 2N bits 21 | // This also simplifies the hand-back of results, as the binimal point 22 | // will always be in the same location 23 | 24 | wire [2*N-1:0] f_result; // Multiplication by 2 values of N bits requires a 25 | // register that is N+N = 2N deep 26 | wire [N-1:0] multiplicand; 27 | wire [N-1:0] multiplier; 28 | wire [N-1:0] a_2cmp, b_2cmp; 29 | wire [N-2:0] quantized_result,quantized_result_2cmp; 30 | 31 | assign a_2cmp = {~a[N-1],~a[N-2:0]+ 1'b1}; //2's complement of a {(N-1){1'b1}} - 32 | assign b_2cmp = {~b[N-1],~b[N-2:0]+ 1'b1}; //2's complement of b {(N-1){1'b1}} - 33 | 34 | assign multiplicand = (a[N-1]) ? a_2cmp : a; 35 | assign multiplier = (b[N-1]) ? b_2cmp : b; 36 | 37 | // always @(posedge clk) //pipelining a bit in order to prevent too much combo delay 38 | // begin 39 | // if(rst) 40 | // f_result <= 0; 41 | // else 42 | assign f_result = multiplicand[N-2:0] * multiplier[N-2:0]; //We remove the sign bit for multiplication 43 | // end 44 | 45 | assign q_result[N-1] = a[N-1]^b[N-1]; //Sign bit of output would be XOR or input sign bits 46 | assign quantized_result = f_result[N-2+Q:Q]; //Quantization of output to required number of bits 47 | assign quantized_result_2cmp = ~quantized_result[N-2:0] + 1'b1; //2's complement of quantized_result {(N-1){1'b1}} - 48 | assign q_result[N-2:0] = (a[N-1]^b[N-1]) ? quantized_result_2cmp : quantized_result; //If the result is negative, we return a 2's complement representation 49 | //of the output value 50 | assign overflow = (f_result[2*N-2:N-1+Q] > 0) ? 1'b1 : 1'b0; 51 | 52 | endmodule -------------------------------------------------------------------------------- /relu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module relu #(parameter N = 16)( 4 | input [N-1:0] din_relu, 5 | output [N-1:0] dout_relu 6 | ); 7 | assign dout_relu = (din_relu[N-1] == 0)? din_relu : 0; 8 | 9 | endmodule 10 | -------------------------------------------------------------------------------- /tanh_data.mem: -------------------------------------------------------------------------------- 1 | 0000000000000000 2 | 0000000000001100 3 | 0000000000011000 4 | 0000000000100100 5 | 0000000000110000 6 | 0000000000111100 7 | 0000000001001000 8 | 0000000001010100 9 | 0000000001100000 10 | 0000000001101100 11 | 0000000001111000 12 | 0000000010000100 13 | 0000000010010000 14 | 0000000010011100 15 | 0000000010101000 16 | 0000000010110100 17 | 0000000011000000 18 | 0000000011001100 19 | 0000000011011000 20 | 0000000011100011 21 | 0000000011101111 22 | 0000000011111011 23 | 0000000100000111 24 | 0000000100010011 25 | 0000000100011111 26 | 0000000100101011 27 | 0000000100110111 28 | 0000000101000011 29 | 0000000101001111 30 | 0000000101011011 31 | 0000000101100111 32 | 0000000101110011 33 | 0000000101111111 34 | 0000000110001011 35 | 0000000110010111 36 | 0000000110100010 37 | 0000000110101110 38 | 0000000110111010 39 | 0000000111000110 40 | 0000000111010010 41 | 0000000111011110 42 | 0000000111101010 43 | 0000000111110101 44 | 0000001000000001 45 | 0000001000001101 46 | 0000001000011001 47 | 0000001000100101 48 | 0000001000110001 49 | 0000001000111100 50 | 0000001001001000 51 | 0000001001010100 52 | 0000001001100000 53 | 0000001001101011 54 | 0000001001110111 55 | 0000001010000011 56 | 0000001010001110 57 | 0000001010011010 58 | 0000001010100110 59 | 0000001010110010 60 | 0000001010111101 61 | 0000001011001001 62 | 0000001011010100 63 | 0000001011100000 64 | 0000001011101100 65 | 0000001011110111 66 | 0000001100000011 67 | 0000001100001111 68 | 0000001100011010 69 | 0000001100100110 70 | 0000001100110001 71 | 0000001100111101 72 | 0000001101001000 73 | 0000001101010100 74 | 0000001101011111 75 | 0000001101101011 76 | 0000001101110110 77 | 0000001110000010 78 | 0000001110001101 79 | 0000001110011000 80 | 0000001110100100 81 | 0000001110101111 82 | 0000001110111011 83 | 0000001111000110 84 | 0000001111010001 85 | 0000001111011101 86 | 0000001111101000 87 | 0000001111110011 88 | 0000001111111110 89 | 0000010000001010 90 | 0000010000010101 91 | 0000010000100000 92 | 0000010000101011 93 | 0000010000110111 94 | 0000010001000010 95 | 0000010001001101 96 | 0000010001011000 97 | 0000010001100011 98 | 0000010001101110 99 | 0000010001111001 100 | 0000010010000100 101 | 0000010010001111 102 | 0000010010011010 103 | 0000010010100101 104 | 0000010010110000 105 | 0000010010111011 106 | 0000010011000110 107 | 0000010011010001 108 | 0000010011011100 109 | 0000010011100111 110 | 0000010011110010 111 | 0000010011111101 112 | 0000010100001000 113 | 0000010100010010 114 | 0000010100011101 115 | 0000010100101000 116 | 0000010100110011 117 | 0000010100111101 118 | 0000010101001000 119 | 0000010101010011 120 | 0000010101011110 121 | 0000010101101000 122 | 0000010101110011 123 | 0000010101111101 124 | 0000010110001000 125 | 0000010110010011 126 | 0000010110011101 127 | 0000010110101000 128 | 0000010110110010 129 | 0000010110111101 130 | 0000010111000111 131 | 0000010111010010 132 | 0000010111011100 133 | 0000010111100110 134 | 0000010111110001 135 | 0000010111111011 136 | 0000011000000101 137 | 0000011000010000 138 | 0000011000011010 139 | 0000011000100100 140 | 0000011000101110 141 | 0000011000111001 142 | 0000011001000011 143 | 0000011001001101 144 | 0000011001010111 145 | 0000011001100001 146 | 0000011001101011 147 | 0000011001110101 148 | 0000011001111111 149 | 0000011010001001 150 | 0000011010010011 151 | 0000011010011101 152 | 0000011010100111 153 | 0000011010110001 154 | 0000011010111011 155 | 0000011011000101 156 | 0000011011001111 157 | 0000011011011001 158 | 0000011011100010 159 | 0000011011101100 160 | 0000011011110110 161 | 0000011100000000 162 | 0000011100001001 163 | 0000011100010011 164 | 0000011100011101 165 | 0000011100100110 166 | 0000011100110000 167 | 0000011100111010 168 | 0000011101000011 169 | 0000011101001101 170 | 0000011101010110 171 | 0000011101100000 172 | 0000011101101001 173 | 0000011101110010 174 | 0000011101111100 175 | 0000011110000101 176 | 0000011110001111 177 | 0000011110011000 178 | 0000011110100001 179 | 0000011110101010 180 | 0000011110110100 181 | 0000011110111101 182 | 0000011111000110 183 | 0000011111001111 184 | 0000011111011000 185 | 0000011111100010 186 | 0000011111101011 187 | 0000011111110100 188 | 0000011111111101 189 | 0000100000000110 190 | 0000100000001111 191 | 0000100000011000 192 | 0000100000100001 193 | 0000100000101001 194 | 0000100000110010 195 | 0000100000111011 196 | 0000100001000100 197 | 0000100001001101 198 | 0000100001010110 199 | 0000100001011110 200 | 0000100001100111 201 | 0000100001110000 202 | 0000100001111000 203 | 0000100010000001 204 | 0000100010001010 205 | 0000100010010010 206 | 0000100010011011 207 | 0000100010100011 208 | 0000100010101100 209 | 0000100010110100 210 | 0000100010111101 211 | 0000100011000101 212 | 0000100011001101 213 | 0000100011010110 214 | 0000100011011110 215 | 0000100011100110 216 | 0000100011101111 217 | 0000100011110111 218 | 0000100011111111 219 | 0000100100000111 220 | 0000100100010000 221 | 0000100100011000 222 | 0000100100100000 223 | 0000100100101000 224 | 0000100100110000 225 | 0000100100111000 226 | 0000100101000000 227 | 0000100101001000 228 | 0000100101010000 229 | 0000100101011000 230 | 0000100101100000 231 | 0000100101101000 232 | 0000100101101111 233 | 0000100101110111 234 | 0000100101111111 235 | 0000100110000111 236 | 0000100110001111 237 | 0000100110010110 238 | 0000100110011110 239 | 0000100110100110 240 | 0000100110101101 241 | 0000100110110101 242 | 0000100110111100 243 | 0000100111000100 244 | 0000100111001100 245 | 0000100111010011 246 | 0000100111011010 247 | 0000100111100010 248 | 0000100111101001 249 | 0000100111110001 250 | 0000100111111000 251 | 0000100111111111 252 | 0000101000000111 253 | 0000101000001110 254 | 0000101000010101 255 | 0000101000011100 256 | 0000101000100100 257 | 0000101000101011 258 | 0000101000110010 259 | 0000101000111001 260 | 0000101001000000 261 | 0000101001000111 262 | 0000101001001110 263 | 0000101001010101 264 | 0000101001011100 265 | 0000101001100011 266 | 0000101001101010 267 | 0000101001110001 268 | 0000101001111000 269 | 0000101001111111 270 | 0000101010000110 271 | 0000101010001100 272 | 0000101010010011 273 | 0000101010011010 274 | 0000101010100001 275 | 0000101010100111 276 | 0000101010101110 277 | 0000101010110101 278 | 0000101010111011 279 | 0000101011000010 280 | 0000101011001001 281 | 0000101011001111 282 | 0000101011010110 283 | 0000101011011100 284 | 0000101011100011 285 | 0000101011101001 286 | 0000101011101111 287 | 0000101011110110 288 | 0000101011111100 289 | 0000101100000010 290 | 0000101100001001 291 | 0000101100001111 292 | 0000101100010101 293 | 0000101100011100 294 | 0000101100100010 295 | 0000101100101000 296 | 0000101100101110 297 | 0000101100110100 298 | 0000101100111010 299 | 0000101101000000 300 | 0000101101000110 301 | 0000101101001101 302 | 0000101101010011 303 | 0000101101011001 304 | 0000101101011110 305 | 0000101101100100 306 | 0000101101101010 307 | 0000101101110000 308 | 0000101101110110 309 | 0000101101111100 310 | 0000101110000010 311 | 0000101110000111 312 | 0000101110001101 313 | 0000101110010011 314 | 0000101110011001 315 | 0000101110011110 316 | 0000101110100100 317 | 0000101110101010 318 | 0000101110101111 319 | 0000101110110101 320 | 0000101110111010 321 | 0000101111000000 322 | 0000101111000110 323 | 0000101111001011 324 | 0000101111010000 325 | 0000101111010110 326 | 0000101111011011 327 | 0000101111100001 328 | 0000101111100110 329 | 0000101111101011 330 | 0000101111110001 331 | 0000101111110110 332 | 0000101111111011 333 | 0000110000000001 334 | 0000110000000110 335 | 0000110000001011 336 | 0000110000010000 337 | 0000110000010101 338 | 0000110000011011 339 | 0000110000100000 340 | 0000110000100101 341 | 0000110000101010 342 | 0000110000101111 343 | 0000110000110100 344 | 0000110000111001 345 | 0000110000111110 346 | 0000110001000011 347 | 0000110001001000 348 | 0000110001001101 349 | 0000110001010010 350 | 0000110001010111 351 | 0000110001011011 352 | 0000110001100000 353 | 0000110001100101 354 | 0000110001101010 355 | 0000110001101111 356 | 0000110001110011 357 | 0000110001111000 358 | 0000110001111101 359 | 0000110010000010 360 | 0000110010000110 361 | 0000110010001011 362 | 0000110010001111 363 | 0000110010010100 364 | 0000110010011001 365 | 0000110010011101 366 | 0000110010100010 367 | 0000110010100110 368 | 0000110010101011 369 | 0000110010101111 370 | 0000110010110100 371 | 0000110010111000 372 | 0000110010111100 373 | 0000110011000001 374 | 0000110011000101 375 | 0000110011001010 376 | 0000110011001110 377 | 0000110011010010 378 | 0000110011010111 379 | 0000110011011011 380 | 0000110011011111 381 | 0000110011100011 382 | 0000110011100111 383 | 0000110011101100 384 | 0000110011110000 385 | 0000110011110100 386 | 0000110011111000 387 | 0000110011111100 388 | 0000110100000000 389 | 0000110100000100 390 | 0000110100001000 391 | 0000110100001100 392 | 0000110100010000 393 | 0000110100010100 394 | 0000110100011000 395 | 0000110100011100 396 | 0000110100100000 397 | 0000110100100100 398 | 0000110100101000 399 | 0000110100101100 400 | 0000110100110000 401 | 0000110100110100 402 | 0000110100110111 403 | 0000110100111011 404 | 0000110100111111 405 | 0000110101000011 406 | 0000110101000111 407 | 0000110101001010 408 | 0000110101001110 409 | 0000110101010010 410 | 0000110101010101 411 | 0000110101011001 412 | 0000110101011101 413 | 0000110101100000 414 | 0000110101100100 415 | 0000110101101000 416 | 0000110101101011 417 | 0000110101101111 418 | 0000110101110010 419 | 0000110101110110 420 | 0000110101111001 421 | 0000110101111101 422 | 0000110110000000 423 | 0000110110000100 424 | 0000110110000111 425 | 0000110110001010 426 | 0000110110001110 427 | 0000110110010001 428 | 0000110110010101 429 | 0000110110011000 430 | 0000110110011011 431 | 0000110110011111 432 | 0000110110100010 433 | 0000110110100101 434 | 0000110110101000 435 | 0000110110101100 436 | 0000110110101111 437 | 0000110110110010 438 | 0000110110110101 439 | 0000110110111001 440 | 0000110110111100 441 | 0000110110111111 442 | 0000110111000010 443 | 0000110111000101 444 | 0000110111001000 445 | 0000110111001011 446 | 0000110111001110 447 | 0000110111010001 448 | 0000110111010100 449 | 0000110111010111 450 | 0000110111011010 451 | 0000110111011101 452 | 0000110111100000 453 | 0000110111100011 454 | 0000110111100110 455 | 0000110111101001 456 | 0000110111101100 457 | 0000110111101111 458 | 0000110111110010 459 | 0000110111110101 460 | 0000110111111000 461 | 0000110111111011 462 | 0000110111111101 463 | 0000111000000000 464 | 0000111000000011 465 | 0000111000000110 466 | 0000111000001001 467 | 0000111000001011 468 | 0000111000001110 469 | 0000111000010001 470 | 0000111000010100 471 | 0000111000010110 472 | 0000111000011001 473 | 0000111000011100 474 | 0000111000011110 475 | 0000111000100001 476 | 0000111000100100 477 | 0000111000100110 478 | 0000111000101001 479 | 0000111000101011 480 | 0000111000101110 481 | 0000111000110001 482 | 0000111000110011 483 | 0000111000110110 484 | 0000111000111000 485 | 0000111000111011 486 | 0000111000111101 487 | 0000111001000000 488 | 0000111001000010 489 | 0000111001000101 490 | 0000111001000111 491 | 0000111001001010 492 | 0000111001001100 493 | 0000111001001110 494 | 0000111001010001 495 | 0000111001010011 496 | 0000111001010110 497 | 0000111001011000 498 | 0000111001011010 499 | 0000111001011101 500 | 0000111001011111 501 | 0000111001100001 502 | 0000111001100100 503 | 0000111001100110 504 | 0000111001101000 505 | 0000111001101010 506 | 0000111001101101 507 | 0000111001101111 508 | 0000111001110001 509 | 0000111001110011 510 | 0000111001110110 511 | 0000111001111000 512 | 0000111001111010 513 | 0000111001111100 514 | 0000111001111110 515 | 0000111010000000 516 | 0000111010000011 517 | 0000111010000101 518 | 0000111010000111 519 | 0000111010001001 520 | 0000111010001011 521 | 0000111010001101 522 | 0000111010001111 523 | 0000111010010001 524 | 0000111010010011 525 | 0000111010010101 526 | 0000111010010111 527 | 0000111010011001 528 | 0000111010011011 529 | 0000111010011101 530 | 0000111010011111 531 | 0000111010100001 532 | 0000111010100011 533 | 0000111010100101 534 | 0000111010100111 535 | 0000111010101001 536 | 0000111010101011 537 | 0000111010101101 538 | 0000111010101111 539 | 0000111010110001 540 | 0000111010110011 541 | 0000111010110100 542 | 0000111010110110 543 | 0000111010111000 544 | 0000111010111010 545 | 0000111010111100 546 | 0000111010111110 547 | 0000111010111111 548 | 0000111011000001 549 | 0000111011000011 550 | 0000111011000101 551 | 0000111011000111 552 | 0000111011001000 553 | 0000111011001010 554 | 0000111011001100 555 | 0000111011001110 556 | 0000111011001111 557 | 0000111011010001 558 | 0000111011010011 559 | 0000111011010100 560 | 0000111011010110 561 | 0000111011011000 562 | 0000111011011001 563 | 0000111011011011 564 | 0000111011011101 565 | 0000111011011110 566 | 0000111011100000 567 | 0000111011100010 568 | 0000111011100011 569 | 0000111011100101 570 | 0000111011100110 571 | 0000111011101000 572 | 0000111011101010 573 | 0000111011101011 574 | 0000111011101101 575 | 0000111011101110 576 | 0000111011110000 577 | 0000111011110001 578 | 0000111011110011 579 | 0000111011110100 580 | 0000111011110110 581 | 0000111011110111 582 | 0000111011111001 583 | 0000111011111010 584 | 0000111011111100 585 | 0000111011111101 586 | 0000111011111111 587 | 0000111100000000 588 | 0000111100000010 589 | 0000111100000011 590 | 0000111100000101 591 | 0000111100000110 592 | 0000111100000111 593 | 0000111100001001 594 | 0000111100001010 595 | 0000111100001100 596 | 0000111100001101 597 | 0000111100001110 598 | 0000111100010000 599 | 0000111100010001 600 | 0000111100010010 601 | 0000111100010100 602 | 0000111100010101 603 | 0000111100010110 604 | 0000111100011000 605 | 0000111100011001 606 | 0000111100011010 607 | 0000111100011100 608 | 0000111100011101 609 | 0000111100011110 610 | 0000111100100000 611 | 0000111100100001 612 | 0000111100100010 613 | 0000111100100011 614 | 0000111100100101 615 | 0000111100100110 616 | 0000111100100111 617 | 0000111100101000 618 | 0000111100101010 619 | 0000111100101011 620 | 0000111100101100 621 | 0000111100101101 622 | 0000111100101110 623 | 0000111100110000 624 | 0000111100110001 625 | 0000111100110010 626 | 0000111100110011 627 | 0000111100110100 628 | 0000111100110101 629 | 0000111100110111 630 | 0000111100111000 631 | 0000111100111001 632 | 0000111100111010 633 | 0000111100111011 634 | 0000111100111100 635 | 0000111100111101 636 | 0000111100111110 637 | 0000111101000000 638 | 0000111101000001 639 | 0000111101000010 640 | 0000111101000011 641 | 0000111101000100 642 | 0000111101000101 643 | 0000111101000110 644 | 0000111101000111 645 | 0000111101001000 646 | 0000111101001001 647 | 0000111101001010 648 | 0000111101001011 649 | 0000111101001100 650 | 0000111101001101 651 | 0000111101001110 652 | 0000111101001111 653 | 0000111101010000 654 | 0000111101010001 655 | 0000111101010010 656 | 0000111101010011 657 | 0000111101010100 658 | 0000111101010101 659 | 0000111101010110 660 | 0000111101010111 661 | 0000111101011000 662 | 0000111101011001 663 | 0000111101011010 664 | 0000111101011011 665 | 0000111101011100 666 | 0000111101011101 667 | 0000111101011110 668 | 0000111101011111 669 | 0000111101100000 670 | 0000111101100001 671 | 0000111101100010 672 | 0000111101100011 673 | 0000111101100011 674 | 0000111101100100 675 | 0000111101100101 676 | 0000111101100110 677 | 0000111101100111 678 | 0000111101101000 679 | 0000111101101001 680 | 0000111101101010 681 | 0000111101101010 682 | 0000111101101011 683 | 0000111101101100 684 | 0000111101101101 685 | 0000111101101110 686 | 0000111101101111 687 | 0000111101110000 688 | 0000111101110000 689 | 0000111101110001 690 | 0000111101110010 691 | 0000111101110011 692 | 0000111101110100 693 | 0000111101110100 694 | 0000111101110101 695 | 0000111101110110 696 | 0000111101110111 697 | 0000111101111000 698 | 0000111101111000 699 | 0000111101111001 700 | 0000111101111010 701 | 0000111101111011 702 | 0000111101111011 703 | 0000111101111100 704 | 0000111101111101 705 | 0000111101111110 706 | 0000111101111110 707 | 0000111101111111 708 | 0000111110000000 709 | 0000111110000001 710 | 0000111110000001 711 | 0000111110000010 712 | 0000111110000011 713 | 0000111110000100 714 | 0000111110000100 715 | 0000111110000101 716 | 0000111110000110 717 | 0000111110000110 718 | 0000111110000111 719 | 0000111110001000 720 | 0000111110001000 721 | 0000111110001001 722 | 0000111110001010 723 | 0000111110001011 724 | 0000111110001011 725 | 0000111110001100 726 | 0000111110001101 727 | 0000111110001101 728 | 0000111110001110 729 | 0000111110001111 730 | 0000111110001111 731 | 0000111110010000 732 | 0000111110010000 733 | 0000111110010001 734 | 0000111110010010 735 | 0000111110010010 736 | 0000111110010011 737 | 0000111110010100 738 | 0000111110010100 739 | 0000111110010101 740 | 0000111110010101 741 | 0000111110010110 742 | 0000111110010111 743 | 0000111110010111 744 | 0000111110011000 745 | 0000111110011001 746 | 0000111110011001 747 | 0000111110011010 748 | 0000111110011010 749 | 0000111110011011 750 | 0000111110011011 751 | 0000111110011100 752 | 0000111110011101 753 | 0000111110011101 754 | 0000111110011110 755 | 0000111110011110 756 | 0000111110011111 757 | 0000111110011111 758 | 0000111110100000 759 | 0000111110100001 760 | 0000111110100001 761 | 0000111110100010 762 | 0000111110100010 763 | 0000111110100011 764 | 0000111110100011 765 | 0000111110100100 766 | 0000111110100100 767 | 0000111110100101 768 | 0000111110100101 769 | 0000111110100110 770 | 0000111110100110 771 | 0000111110100111 772 | 0000111110100111 773 | 0000111110101000 774 | 0000111110101000 775 | 0000111110101001 776 | 0000111110101001 777 | 0000111110101010 778 | 0000111110101010 779 | 0000111110101011 780 | 0000111110101011 781 | 0000111110101100 782 | 0000111110101100 783 | 0000111110101101 784 | 0000111110101101 785 | 0000111110101110 786 | 0000111110101110 787 | 0000111110101111 788 | 0000111110101111 789 | 0000111110110000 790 | 0000111110110000 791 | 0000111110110001 792 | 0000111110110001 793 | 0000111110110010 794 | 0000111110110010 795 | 0000111110110010 796 | 0000111110110011 797 | 0000111110110011 798 | 0000111110110100 799 | 0000111110110100 800 | 0000111110110101 801 | 0000111110110101 802 | 0000111110110110 803 | 0000111110110110 804 | 0000111110110110 805 | 0000111110110111 806 | 0000111110110111 807 | 0000111110111000 808 | 0000111110111000 809 | 0000111110111000 810 | 0000111110111001 811 | 0000111110111001 812 | 0000111110111010 813 | 0000111110111010 814 | 0000111110111010 815 | 0000111110111011 816 | 0000111110111011 817 | 0000111110111100 818 | 0000111110111100 819 | 0000111110111100 820 | 0000111110111101 821 | 0000111110111101 822 | 0000111110111110 823 | 0000111110111110 824 | 0000111110111110 825 | 0000111110111111 826 | 0000111110111111 827 | 0000111111000000 828 | 0000111111000000 829 | 0000111111000000 830 | 0000111111000001 831 | 0000111111000001 832 | 0000111111000001 833 | 0000111111000010 834 | 0000111111000010 835 | 0000111111000010 836 | 0000111111000011 837 | 0000111111000011 838 | 0000111111000011 839 | 0000111111000100 840 | 0000111111000100 841 | 0000111111000101 842 | 0000111111000101 843 | 0000111111000101 844 | 0000111111000110 845 | 0000111111000110 846 | 0000111111000110 847 | 0000111111000111 848 | 0000111111000111 849 | 0000111111000111 850 | 0000111111001000 851 | 0000111111001000 852 | 0000111111001000 853 | 0000111111001001 854 | 0000111111001001 855 | 0000111111001001 856 | 0000111111001001 857 | 0000111111001010 858 | 0000111111001010 859 | 0000111111001010 860 | 0000111111001011 861 | 0000111111001011 862 | 0000111111001011 863 | 0000111111001100 864 | 0000111111001100 865 | 0000111111001100 866 | 0000111111001101 867 | 0000111111001101 868 | 0000111111001101 869 | 0000111111001101 870 | 0000111111001110 871 | 0000111111001110 872 | 0000111111001110 873 | 0000111111001111 874 | 0000111111001111 875 | 0000111111001111 876 | 0000111111001111 877 | 0000111111010000 878 | 0000111111010000 879 | 0000111111010000 880 | 0000111111010001 881 | 0000111111010001 882 | 0000111111010001 883 | 0000111111010001 884 | 0000111111010010 885 | 0000111111010010 886 | 0000111111010010 887 | 0000111111010010 888 | 0000111111010011 889 | 0000111111010011 890 | 0000111111010011 891 | 0000111111010011 892 | 0000111111010100 893 | 0000111111010100 894 | 0000111111010100 895 | 0000111111010100 896 | 0000111111010101 897 | 0000111111010101 898 | 0000111111010101 899 | 0000111111010101 900 | 0000111111010110 901 | 0000111111010110 902 | 0000111111010110 903 | 0000111111010110 904 | 0000111111010111 905 | 0000111111010111 906 | 0000111111010111 907 | 0000111111010111 908 | 0000111111011000 909 | 0000111111011000 910 | 0000111111011000 911 | 0000111111011000 912 | 0000111111011001 913 | 0000111111011001 914 | 0000111111011001 915 | 0000111111011001 916 | 0000111111011001 917 | 0000111111011010 918 | 0000111111011010 919 | 0000111111011010 920 | 0000111111011010 921 | 0000111111011011 922 | 0000111111011011 923 | 0000111111011011 924 | 0000111111011011 925 | 0000111111011011 926 | 0000111111011100 927 | 0000111111011100 928 | 0000111111011100 929 | 0000111111011100 930 | 0000111111011100 931 | 0000111111011101 932 | 0000111111011101 933 | 0000111111011101 934 | 0000111111011101 935 | 0000111111011101 936 | 0000111111011110 937 | 0000111111011110 938 | 0000111111011110 939 | 0000111111011110 940 | 0000111111011110 941 | 0000111111011111 942 | 0000111111011111 943 | 0000111111011111 944 | 0000111111011111 945 | 0000111111011111 946 | 0000111111100000 947 | 0000111111100000 948 | 0000111111100000 949 | 0000111111100000 950 | 0000111111100000 951 | 0000111111100000 952 | 0000111111100001 953 | 0000111111100001 954 | 0000111111100001 955 | 0000111111100001 956 | 0000111111100001 957 | 0000111111100010 958 | 0000111111100010 959 | 0000111111100010 960 | 0000111111100010 961 | 0000111111100010 962 | 0000111111100010 963 | 0000111111100011 964 | 0000111111100011 965 | 0000111111100011 966 | 0000111111100011 967 | 0000111111100011 968 | 0000111111100011 969 | 0000111111100100 970 | 0000111111100100 971 | 0000111111100100 972 | 0000111111100100 973 | 0000111111100100 974 | 0000111111100100 975 | 0000111111100101 976 | 0000111111100101 977 | 0000111111100101 978 | 0000111111100101 979 | 0000111111100101 980 | 0000111111100101 981 | 0000111111100101 982 | 0000111111100110 983 | 0000111111100110 984 | 0000111111100110 985 | 0000111111100110 986 | 0000111111100110 987 | 0000111111100110 988 | 0000111111100110 989 | 0000111111100111 990 | 0000111111100111 991 | 0000111111100111 992 | 0000111111100111 993 | 0000111111100111 994 | 0000111111100111 995 | 0000111111100111 996 | 0000111111101000 997 | 0000111111101000 998 | 0000111111101000 999 | 0000111111101000 1000 | 0000111111101000 1001 | 0000111111101000 1002 | 0000111111101000 1003 | 0000111111101001 1004 | 0000111111101001 1005 | 0000111111101001 1006 | 0000111111101001 1007 | 0000111111101001 1008 | 0000111111101001 1009 | 0000111111101001 1010 | 0000111111101010 1011 | 0000111111101010 1012 | 0000111111101010 1013 | 0000111111101010 1014 | 0000111111101010 1015 | 0000111111101010 1016 | 0000111111101010 1017 | 0000111111101010 1018 | 0000111111101011 1019 | 0000111111101011 1020 | 0000111111101011 1021 | 0000111111101011 1022 | 0000111111101011 1023 | 0000111111101011 1024 | 0000111111101011 -------------------------------------------------------------------------------- /tanh_lut.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define INTERPOLATE 1 3 | module tanh_lut #( 4 | parameter AW = 10, //AW will be based on the size of the ROM we can afford in our design. 5 | //in the best case AW = N; 6 | parameter DW = 16, 7 | parameter N = 16, 8 | parameter Q = 12 9 | )( 10 | input clk, 11 | input rst, 12 | input [N-1:0] phase, 13 | output [DW-1:0] tanh 14 | ); 15 | 16 | reg [AW-1:0] addra_reg; 17 | wire [DW-1:0] tanha; 18 | wire [DW-1:0] tanhb; 19 | wire ovr1,ovr2; 20 | 21 | `ifdef INTERPOLATE 22 | reg [AW-1:0] addrb_reg; 23 | `endif 24 | 25 | (* ram_style = "block" *)reg [DW-1:0] mem [(1<