`timescale 1ns / 1ps
MAXPOOL LAYER
`timescale 1ns / 1ps
module Max_pool (clk,clken);
input clk;
input clken;
//output reg [BITWIDTH * DATAWIDTH / KWIDTH * DATAHEIGHT / KHEIGHT * DATACHANNEL - 1 : 0] result
parameter integer BITWIDTH = 16,DATAWIDTH = 64,DATAHEIGHT = 64,DATACHANNEL = 3,KWIDTH = 2,KHEIGHT = 2;
integer flag_data_read = 1, flag_conv = 0, flag_max = 0, flag_final = 0, flag_prob = 0;// Flags defined for invoking "always" blocks in sequence
//integer i, j, k, r = 0, it = 0, max, t = 0;
integer count = 0;
integer image_count=-2;
integer filter_count=-2;
wire [BITWIDTH - 1 : 0] dataArray[0 : DATACHANNEL - 1][0 : DATAHEIGHT-1][0 : DATAWIDTH - 1];
wire [BITWIDTH * KHEIGHT * KWIDTH - 1 : 0]paramArray [0: DATACHANNEL - 1][0: DATAHEIGHT / KHEIGHT - 1][0: DATAWIDTH / KWIDTH - 1];
wire [BITWIDTH * DATAWIDTH * DATAHEIGHT * DATACHANNEL - 1 : 0]data;
wire [BITWIDTH * DATAWIDTH / KWIDTH * DATAHEIGHT / KHEIGHT * DATACHANNEL - 1 : 0] out;
wire [BITWIDTH*DATAWIDTH*DATAHEIGHT*DATACHANNEL-1:0] array_Image;
//wire [BITWIDTH*FILTERWIDTH*FILTERHEIGHT*FILTERCHANNEL*FILTERBATCH-1:0] array_Filter;
reg signed [BITWIDTH-1:0]Image[0:DATAWIDTH*DATAHEIGHT*DATACHANNEL-1];
//reg signed [BITWIDTH-1:0] Filters[0:FILTERWIDTH*FILTERHEIGHT*FILTERCHANNEL*FILTERBATCH-1];
wire in_when_writing=0;
wire wea = 0;
wire[BITWIDTH-1:0] filters;
wire[BITWIDTH-1:0]image_value;
reg[31:0]address_image = 0;
reg[31:0]address_filter = 0;
blk_mem_gen_0 inst0( .wea(wea), .clka(clk), .addra(address_image), .dina(in_when_writing), .douta(image_value) );
//blk_mem_gen_1 inst1( .wea(wea), .clka(clk), .addra(address_filter), .dina(in_when_writing), .douta(filters) );
always@(posedge clk)// Initializing parameter loading from BRAM
if(flag_data_read) begin
// We are skipping 2 clock edges beacause of 2 clock cycle latency in reading Block RAM
// Image Read
if (count<(DATAWIDTH*DATAHEIGHT*DATACHANNEL)+2)// counting only 1026-2 values
begin
if (image_count > -1) begin
Image[image_count] = image_value;// Reading start from 0 index
end
else begin
end
if(address_image <(DATAWIDTH*DATAHEIGHT*DATACHANNEL))
address_image = address_image + 1;
else
address_image = 0;
//$display("Image Array -> %d , %d", address_image ,image_value);
end
else begin
end
// Updating of loading parameters for next posedge if (count<(DATAWIDTH*DATAHEIGHT*DATACHANNEL)+3)// updating count variable
begin
count = count + 1;
image_count = image_count + 1;
end
else begin
end
if(count == (DATAWIDTH*DATAHEIGHT*DATACHANNEL)+3) begin
flag_data_read = 0;
flag_conv = 1;
count = count+100;
end// Stopping this always block as all reading parameters is done
else begin
end
end
generate
genvar l;
for(l=0;l<DATAWIDTH*DATAHEIGHT*DATACHANNEL;l=l+1)
begin
assign array_Image[BITWIDTH*l +: BITWIDTH] = Image [l][BITWIDTH-1:0] ;
end
endgenerate
assign data = array_Image;
genvar i, j, k, m, n;
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(j = 0; j < DATAHEIGHT; j = j + 1) begin
for(k = 0; k < DATAWIDTH; k = k + 1) begin
assign dataArray[i][j][k] = data[(i * DATAHEIGHT * DATAWIDTH + j * DATAHEIGHT + k) * BITWIDTH + BITWIDTH - 1:(i * DATAHEIGHT * DATAWIDTH + j * DATAHEIGHT + k) * BITWIDTH];
end
end
end
endgenerate
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(j = 0; j < DATAHEIGHT / KHEIGHT; j = j + 1) begin
for(k = 0; k < DATAWIDTH / KWIDTH; k = k + 1) begin
for(m = j * 2; m < j * 2 + KHEIGHT; m = m + 1) begin
for(n = k * 2; n < k * 2 + KWIDTH; n = n + 1) begin
assign paramArray[i][j][k][((m - j * 2) * KWIDTH + n - k * 2) * BITWIDTH + BITWIDTH - 1:((m - j * 2) * KWIDTH + n - k * 2) * BITWIDTH] = dataArray[i][m][n];
end
end
end
end
end
endgenerate
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(j = 0; j < DATAHEIGHT / KHEIGHT; j = j + 1) begin
for(k = 0; k < DATAWIDTH / KWIDTH; k = k + 1) begin
Max#(BITWIDTH, KHEIGHT * KWIDTH) max(paramArray[i][j][k], out[(i * DATAHEIGHT / KHEIGHT * DATAWIDTH / KWIDTH + j * DATAWIDTH / KWIDTH + k) * BITWIDTH + BITWIDTH - 1:(i * DATAHEIGHT / KHEIGHT * DATAWIDTH / KWIDTH + j * DATAWIDTH / KWIDTH + k) * BITWIDTH]);
end
end
end
endgenerate
// always @(posedge clk) begin
// if(clken == 1) begin
// result = out;
// end
// end
EndmoduleSOFTMAX LAYER
module softmax1(inputs,clk,enable,outputs,ackSoft);
parameter DATA_WIDTH=32;
localparam inputNum=10;
input [DATA_WIDTH*inputNum-1:0] inputs;
input clk;
input enable;
output reg [DATA_WIDTH*inputNum-1:0] outputs;
output reg ackSoft;
wire [DATA_WIDTH-1:0] expSum;
wire [DATA_WIDTH-1:0] expReciprocal;
wire [DATA_WIDTH-1:0] outMul;
wire [DATA_WIDTH*inputNum-1:0] exponents ;
wire [inputNum-1:0] acksExp; //acknowledge signals of exponents
wire ackDiv; //ack signal of the division unit
wire [DATA_WIDTH-1:0] expSums [inputNum:0]; //used in the multiple adders to connected to each other
reg [3:0] mulCounter;
assign expSums[0]=32'b00000000000000000000000000000000; //first one is zero to move the flow
assign expSum=expSums[inputNum]; //last one in the sum
genvar i;
generate
for (i = 0; i < inputNum; i = i + 1) begin
exponent #(.DATA_WIDTH(DATA_WIDTH)) exp (
.x(inputs[DATA_WIDTH*i+:DATA_WIDTH]),
.enable(enable),
.clk(clk),
.output_exp(exponents[DATA_WIDTH*i+:DATA_WIDTH]),
.ack(acksExp[i]));
end
endgenerate //generating 10 parallel exponent modules
genvar j;
generate
for (j = 0; j < inputNum; j = j + 1) begin
floatAdd FADD1 (exponents[DATA_WIDTH*j+:DATA_WIDTH],expSums[j],expSums[j+1]);
end
endgenerate //generating 10 parallel adding modules to get the sum of the exponents
floatReciprocal #(.DATA_WIDTH(DATA_WIDTH)) FR (.number(expSum),.clk(clk),.output_rec(expReciprocal),.ack(ackDiv),.enable(acksExp[0]));//getting reciprocal of the sum of exponents
//reciprocal activated when exponent finished
floatMult FM1 (exponents[DATA_WIDTH*mulCounter+:DATA_WIDTH],expReciprocal,outMul); //multiplication with reciprocal
always @ (negedge clk) begin
if(enable==1'b1) begin
if(ackSoft==1'b0) begin
if(ackDiv==1'b1) begin //check if the reciprocal is ready
if(mulCounter<4'b1010) begin
outputs[DATA_WIDTH*mulCounter+:DATA_WIDTH]=outMul;
mulCounter=mulCounter+1;
end
else begin
ackSoft=1'b1;
end
end
end
end
else begin
//if enable is off reset all counters and acks
mulCounter=4'b0000;
ackSoft=1'b0;
end
end
endmodulePOINTWISE CONVOLUTION
`timescale 1ns / 1ps
//Memory Unit
module mem_1#(parameter N1=1200,parameter N2=192,parameter M1=72,parameter M2=12,
parameter ip_file1="C:/Users/DIAT/Desktop/222414/pointwise/pointwise.srcs/sources_1/new/dw_op_pw_in.mem",
parameter ip_file2="C:/Users/DIAT/Desktop/222414/pointwise/pointwise.srcs/sources_1/new/filter_in_pw.mem")(
input clk,
output reg [N1-1:0] data_out1,
output reg [N2-1:0] data_out2
);
reg [N1-1:0] mem1 [0:M1-1];
reg [N2-1:0] mem2 [0:M2-1];
initial
begin
$readmemh(ip_file1,mem1);
$readmemh(ip_file2,mem2);
end
integer i=0,j=0;
always @( posedge clk)
begin
data_out1 <= mem1[i];
i=i+1;
data_out2 <= mem2[j];
j=j+1;
end
endmodule//Pointwise Convolution
module pointwise #(
parameter integer BITWIDTH = 16,
parameter integer DATAWIDTH = 5,
parameter integer DATAHEIGHT = 5,
parameter integer DATACHANNEL = 3,
parameter integer FILTERHEIGHT = 1,
parameter integer FILTERWIDTH = 1,
parameter integer FILTERBATCH = 4,
parameter integer FILTERCHANNEL=3,
parameter integer STRIDEHEIGHT = 1,
parameter integer STRIDEWIDTH = 1,
parameter integer PADDINGENABLE = 0
)
(
input clk,
input clken,
input [BITWIDTH * DATAWIDTH * DATAHEIGHT * DATACHANNEL - 1 : 0]data,
input [BITWIDTH * FILTERHEIGHT * FILTERWIDTH * FILTERCHANNEL * FILTERBATCH - 1 : 0]filterWeight,
input [BITWIDTH * FILTERBATCH - 1 : 0] filterBias,
output reg [(BITWIDTH * 2) * FILTERBATCH * (PADDINGENABLE == 0 ? (DATAWIDTH - FILTERWIDTH + 1) / STRIDEWIDTH : (DATAWIDTH / STRIDEWIDTH)) * (PADDINGENABLE == 0 ? (DATAHEIGHT - FILTERHEIGHT + 1) / STRIDEHEIGHT : (DATAHEIGHT / STRIDEHEIGHT)) - 1 : 0] result
);
//instatntiating memory to store image and filter
mem_1 mem (.clk(clk),.data_out1(data),.data_out2(filterWeight));
//intermediate wires
wire [BITWIDTH - 1 : 0] dataArray[0 : DATACHANNEL - 1][0 : DATAHEIGHT-1][0 : DATAWIDTH - 1];
wire [BITWIDTH - 1 : 0] dataArrayWithPadding[0 : DATACHANNEL - 1][0 : (PADDINGENABLE == 1 ? DATAHEIGHT + FILTERHEIGHT - 1 : DATAHEIGHT)-1][0 : (PADDINGENABLE == 1 ? DATAWIDTH + FILTERWIDTH - 1 : DATAWIDTH)-1];
wire [BITWIDTH * FILTERHEIGHT * FILTERWIDTH * DATACHANNEL - 1 : 0] paramArray[0: (PADDINGENABLE == 1 ? DATAHEIGHT / STRIDEHEIGHT: (DATAHEIGHT - FILTERHEIGHT + 1) / STRIDEHEIGHT)-1][0: (PADDINGENABLE == 1 ? DATAWIDTH / STRIDEWIDTH : (DATAWIDTH - FILTERWIDTH + 1) / STRIDEWIDTH)-1];
wire [BITWIDTH * FILTERCHANNEL * FILTERHEIGHT * FILTERWIDTH - 1 : 0] filterWeightArray[0: FILTERBATCH - 1];
wire [(BITWIDTH * 2) * FILTERBATCH * (PADDINGENABLE == 0 ? (DATAWIDTH - FILTERWIDTH + 1) / STRIDEWIDTH : (DATAWIDTH / STRIDEWIDTH)) * (PADDINGENABLE == 0 ? (DATAHEIGHT - FILTERHEIGHT + 1) / STRIDEHEIGHT : (DATAHEIGHT / STRIDEHEIGHT)) - 1 : 0] out;
genvar i, j, k, m, n;
//DATA ARRAY I.E., INPUT IMAGE
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(j = 0; j < DATAHEIGHT; j = j + 1) begin
for(k = 0; k < DATAWIDTH; k = k + 1) begin
assign dataArray[i][j][k] = data[(i * DATAHEIGHT * DATAWIDTH + j * DATAHEIGHT + k) * BITWIDTH + BITWIDTH - 1:(i * DATAHEIGHT * DATAWIDTH + j * DATAHEIGHT + k) * BITWIDTH];
end
end
end
endgenerate
//DATAARRAY WITH PADDING I.E., IF THERE'S ANY PADDING LIKE ZERO PADDING
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(m = 0; m < (PADDINGENABLE == 1 ? DATAHEIGHT + FILTERHEIGHT - 1 : DATAHEIGHT); m = m + 1) begin
for(n = 0; n < (PADDINGENABLE == 1 ? DATAWIDTH + FILTERWIDTH - 1 : DATAWIDTH); n = n + 1) begin
if(PADDINGENABLE == 1) begin
if(m < (FILTERHEIGHT / 2) || m > (DATAHEIGHT + FILTERHEIGHT / 2 - 1)) begin
assign dataArrayWithPadding[i][m][n] = 0;
end
else if(n < (FILTERWIDTH / 2) || n > (DATAWIDTH + FILTERWIDTH / 2 - 1)) begin
assign dataArrayWithPadding[i][m][n] = 0;
end
else begin
assign dataArrayWithPadding[i][m][n] = dataArray[i][m - FILTERHEIGHT / 2][n - FILTERWIDTH / 2];
end
end
else begin
assign dataArrayWithPadding[i][m][n] = dataArray[i][m][n];
end
end
end
end
endgenerate
//PARAMARRAY FOR STRIDING(SLIDING WINDOW)
generate
for(j = FILTERHEIGHT / 2; j < (PADDINGENABLE == 1 ? DATAHEIGHT + FILTERHEIGHT - 1 - FILTERHEIGHT / 2: DATAHEIGHT - FILTERHEIGHT / 2); j = j + STRIDEHEIGHT) begin
for(k = FILTERWIDTH / 2; k < (PADDINGENABLE == 1 ? DATAWIDTH + FILTERWIDTH - 1 - FILTERWIDTH / 2 : DATAWIDTH - FILTERWIDTH / 2); k = k + STRIDEWIDTH) begin
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(m = j - FILTERHEIGHT / 2; m <= j + FILTERHEIGHT / 2; m = m + 1) begin
for(n = k - FILTERWIDTH / 2; n <= k + FILTERWIDTH / 2; n = n + 1) begin
assign paramArray[(j - FILTERHEIGHT / 2) / STRIDEHEIGHT][(k - FILTERWIDTH / 2) / STRIDEWIDTH][(i * FILTERHEIGHT * FILTERWIDTH + (m - j + FILTERHEIGHT / 2) * FILTERWIDTH + (n - k + FILTERWIDTH / 2)) * BITWIDTH + BITWIDTH - 1:(i * FILTERHEIGHT * FILTERWIDTH + (m - j + FILTERHEIGHT / 2) * FILTERWIDTH + (n - k + FILTERWIDTH / 2)) * BITWIDTH] =
dataArrayWithPadding[i][m][n];
end
end
end
end
end
endgenerate
//FILTER WEIGHTS
generate
for(i = 0; i < FILTERBATCH; i = i + 1) begin
assign filterWeightArray[i] = filterWeight[(i + 1) * FILTERCHANNEL * FILTERHEIGHT * FILTERWIDTH * BITWIDTH - 1: i * FILTERCHANNEL * FILTERHEIGHT * FILTERWIDTH * BITWIDTH];
end
endgenerate
//CONVOLUTION OPERATION USING CONV KERNEL MULT AND ADD WITH THE PROVIDED FILTER
generate
for(i = 0; i < FILTERBATCH; i = i + 1) begin
for(m = 0; m < (PADDINGENABLE == 1 ? DATAHEIGHT / STRIDEHEIGHT: (DATAHEIGHT - FILTERHEIGHT + 1) / STRIDEHEIGHT); m = m + 1) begin
for(n = 0; n < (PADDINGENABLE == 1 ? DATAWIDTH / STRIDEWIDTH : (DATAWIDTH - FILTERWIDTH + 1) / STRIDEWIDTH); n = n + 1) begin
ConvKernel#(BITWIDTH, FILTERCHANNEL, FILTERHEIGHT, FILTERWIDTH) convKernel(paramArray[m][n],
filterWeightArray[i],
filterBias[(i + 1) * BITWIDTH - 1 :i * BITWIDTH],
out[(i * (PADDINGENABLE == 1 ? DATAHEIGHT / STRIDEHEIGHT: (DATAHEIGHT - FILTERHEIGHT + 1) / STRIDEHEIGHT) * (PADDINGENABLE == 1 ? DATAWIDTH / STRIDEWIDTH : (DATAWIDTH - FILTERWIDTH + 1) / STRIDEWIDTH) * BITWIDTH * 2 + m * (PADDINGENABLE == 1 ? DATAWIDTH / STRIDEWIDTH : (DATAWIDTH - FILTERWIDTH + 1) / STRIDEWIDTH) * BITWIDTH * 2 + n) * 2 * BITWIDTH + 2 * BITWIDTH - 1:(i * (PADDINGENABLE == 1 ? DATAHEIGHT / STRIDEHEIGHT: (DATAHEIGHT - FILTERHEIGHT + 1) / STRIDEHEIGHT) * (PADDINGENABLE == 1 ? DATAWIDTH / STRIDEWIDTH : (DATAWIDTH - FILTERWIDTH + 1) / STRIDEWIDTH) * BITWIDTH * 2 + m * (PADDINGENABLE == 1 ? DATAWIDTH / STRIDEWIDTH : (DATAWIDTH - FILTERWIDTH + 1) / STRIDEWIDTH) * BITWIDTH * 2 + n * 2 * BITWIDTH)]);
end
end
end
endgenerate
//OUTPUT W.R.T CLOCK
always @(posedge clk) begin
if(clken == 1) begin
result = out;
end
end
//STORING OUTPUT AGAIN IN MEMORY
integer conv_op;
initial
begin
conv_op =$fopen("C:/Users/DIAT/Desktop/222414/pointwise/pointwise.srcs/sources_1/new/conv_op_final.mem","a");
end
//W.r.t clock edge the o/p is stored in the memory
always@(posedge clk) begin
if(clken) begin
$fdisplay(conv_op,"%h",result);
end
$finish;
end
endmoduleDENSE LAYER
module FullConnect#(
parameter BITWIDTH = 8,
parameter LENGTH = 25,
parameter FILTERBATCH = 1
)
(
//input clk,
//input clken,
input [BITWIDTH * LENGTH - 1 : 0] data,
input [BITWIDTH * LENGTH * FILTERBATCH - 1 : 0] weight,
input [BITWIDTH * FILTERBATCH - 1 : 0] bias,
output [BITWIDTH * 2 * FILTERBATCH - 1 : 0] result
);
//reg [BITWIDTH * 2 * LENGTH * FILTERBATCH- 1:0] out;
wire [BITWIDTH * 2 - 1:0] out [0:FILTERBATCH - 1][0:LENGTH - 1];
wire signed [BITWIDTH - 1:0] biasArray[0:FILTERBATCH - 1];
reg signed [BITWIDTH * 2 - 1:0] resultArray [0:FILTERBATCH - 1];
//wire [BITWIDTH * 2 * FILTERBATCH - 1 : 0] out2;
genvar i, j;
generate
for(i = 0; i < FILTERBATCH; i = i + 1) begin
assign biasArray[i] = bias[(i + 1) * BITWIDTH - 1: i * BITWIDTH];
assign result[(i + 1) * BITWIDTH * 2 - 1: i * BITWIDTH * 2] = resultArray[i];
end
endgenerate
generate
for(i = 0; i < FILTERBATCH; i = i + 1) begin
for(j = 0; j < LENGTH; j = j + 1) begin
Mult#(BITWIDTH) mult(data[(j + 1) * BITWIDTH - 1:j * BITWIDTH], weight[(i * LENGTH + j) * BITWIDTH + BITWIDTH - 1 : (i * LENGTH + j) * BITWIDTH], out[i][j]);
end
end
endgenerate
integer sum, m, n;
always @(*) begin
for(m = 0; m < FILTERBATCH; m = m + 1) begin
sum = 0;
for(n = 0; n < LENGTH; n = n + 1) begin
sum = sum + out[m][n];
end
sum = sum + biasArray[m];
resultArray[m] = sum;
end
end
// always @(posedge clk) begin
// if(clken == 1) begin
// result = out2;
// end
// end
EndmoduleMAX POOLING
module Max_pool#(
parameter integer BITWIDTH = 8,
parameter integer DATAWIDTH = 28,
parameter integer DATAHEIGHT = 28,
parameter integer DATACHANNEL = 3,
parameter integer KWIDTH = 2,
parameter integer KHEIGHT = 2
)
(
//input clk,
//input clken,
input [BITWIDTH * DATAWIDTH * DATAHEIGHT * DATACHANNEL - 1 : 0]data,
output reg [BITWIDTH * DATAWIDTH / KWIDTH * DATAHEIGHT / KHEIGHT * DATACHANNEL - 1 : 0] result
);
wire [BITWIDTH - 1 : 0] dataArray[0 : DATACHANNEL - 1][0 : DATAHEIGHT-1][0 : DATAWIDTH - 1];
wire [BITWIDTH * KHEIGHT * KWIDTH - 1 : 0]paramArray [0: DATACHANNEL - 1][0: DATAHEIGHT / KHEIGHT - 1][0: DATAWIDTH / KWIDTH - 1];
//wire [BITWIDTH * DATAWIDTH / KWIDTH * DATAHEIGHT / KHEIGHT * DATACHANNEL - 1 : 0] out;
genvar i, j, k, m, n;
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(j = 0; j < DATAHEIGHT; j = j + 1) begin
for(k = 0; k < DATAWIDTH; k = k + 1) begin
assign dataArray[i][j][k] = data[(i * DATAHEIGHT * DATAWIDTH + j * DATAHEIGHT + k) * BITWIDTH + BITWIDTH - 1:(i * DATAHEIGHT * DATAWIDTH + j * DATAHEIGHT + k) * BITWIDTH];
end
end
end
endgenerate
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(j = 0; j < DATAHEIGHT / KHEIGHT; j = j + 1) begin
for(k = 0; k < DATAWIDTH / KWIDTH; k = k + 1) begin
for(m = j * 2; m < j * 2 + KHEIGHT; m = m + 1) begin
for(n = k * 2; n < k * 2 + KWIDTH; n = n + 1) begin
assign paramArray[i][j][k][((m - j * 2) * KWIDTH + n - k * 2) * BITWIDTH + BITWIDTH - 1:((m - j * 2) * KWIDTH + n - k * 2) * BITWIDTH] = dataArray[i][m][n];
end
end
end
end
end
endgenerate
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(j = 0; j < DATAHEIGHT / KHEIGHT; j = j + 1) begin
for(k = 0; k < DATAWIDTH / KWIDTH; k = k + 1) begin
Max#(BITWIDTH, KHEIGHT * KWIDTH) max(paramArray[i][j][k], result[(i * DATAHEIGHT / KHEIGHT * DATAWIDTH / KWIDTH + j * DATAWIDTH / KWIDTH + k) * BITWIDTH + BITWIDTH - 1:(i * DATAHEIGHT / KHEIGHT * DATAWIDTH / KWIDTH + j * DATAWIDTH / KWIDTH + k) * BITWIDTH]);
end
end
end
endgenerate
// always @(posedge clk) begin
// if(clken == 1) begin
// result = out;
// end
// end
EndmoduleRELU:
module Relu_activation#(
parameter integer BITWIDTH = 8,
parameter integer DATAWIDTH = 28,
parameter integer DATAHEIGHT = 28,
parameter integer DATACHANNEL = 3
)
(
//input clk,
//input clken,
input [BITWIDTH * DATAHEIGHT * DATAWIDTH * DATACHANNEL - 1:0] data,
output reg [BITWIDTH * DATAHEIGHT * DATAWIDTH * DATACHANNEL - 1:0] result
);
//wire [BITWIDTH * DATAHEIGHT * DATAWIDTH * DATACHANNEL - 1:0] out;
genvar i, j, k;
generate
for(i = 0; i < DATACHANNEL; i = i + 1) begin
for(j = 0; j < DATAHEIGHT; j = j + 1) begin
for(k = 0; k < DATAWIDTH; k = k + 1) begin
Relu#(BITWIDTH) relu(data[(i * DATAHEIGHT * DATAWIDTH + j * DATAWIDTH + k) * BITWIDTH + BITWIDTH - 1:(i * DATAHEIGHT * DATAWIDTH + j * DATAWIDTH + k) * BITWIDTH], result[(i * DATAHEIGHT * DATAWIDTH + j * DATAWIDTH + k) * BITWIDTH + BITWIDTH - 1:(i * DATAHEIGHT * DATAWIDTH + j * DATAWIDTH + k) * BITWIDTH]);
end
end
end
endgenerate // always @(posedge clk) begin
// if(clken == 1) begin
// result = out;
// end
// end
EndmoduleINSTANTIATED MODULES
module Relu#(
parameter BITWIDTH = 8,
parameter THRESSHOLD = 0
)
(
input signed [BITWIDTH - 1:0] data,
output signed [BITWIDTH - 1:0] result
);
assign result = data > THRESSHOLD ? data : THRESSHOLD;
endmodulemodule Mult#(
parameter BITWIDTH = 8
)
(
input signed [BITWIDTH-1:0] a,
input signed [BITWIDTH-1:0] b,
output signed [BITWIDTH * 2 - 1:0] c
);
assign c = a * b;
//assign c = 1;
Endmodulemodule Max#(
parameter BITWIDTH = 8,
parameter LENGTH = 4
)
(
input [BITWIDTH * LENGTH - 1 : 0] data,
output reg signed [BITWIDTH - 1 : 0] result
);
wire signed [BITWIDTH - 1:0] dataArray[0:LENGTH - 1];
genvar i;
generate
for(i = 0; i < LENGTH; i = i + 1) begin
assign dataArray[i] = data[i * BITWIDTH + BITWIDTH - 1: i * BITWIDTH];
end
endgenerate
integer j;
always @(*) begin
result = -127;
for(j = 0; j < LENGTH; j = j + 1) begin
if(dataArray[j] > result) begin
result = dataArray[j];
end
end
end
endmodulemodule Avg#(
parameter BITWIDTH = 8,
parameter LENGTH = 4
)
(
input [BITWIDTH * LENGTH - 1 : 0] data,
output reg signed [BITWIDTH - 1 : 0] result
);
wire signed [BITWIDTH - 1:0] dataArray[0:LENGTH - 1];
genvar i;
generate
for(i = 0; i < LENGTH; i = i + 1) begin
assign dataArray[i] = data[i * BITWIDTH + BITWIDTH - 1: i * BITWIDTH];
end
endgenerate
integer j, sum;
always @(*) begin
sum = 0;
for(j = 0; j < LENGTH; j = j + 1) begin
sum = sum + dataArray[j];
end
result = sum / LENGTH;
end
endmodule