appu1985
Member level 2
Code:
module system(clk,mode,x,p,pim);
parameter elements = 10; //This is the number of processing elements we want to have it in our design.
input clk;
input [1:0]mode;
input [7:0]x;
input [3:0]p;
output [3:0]pim;
wire [elements:0] conti;
wire [elements:0] contx;
wire [elements:0] contp;
wire [elements:0] contpsw;
wire [elements:0] contpsy;
wire [7:0]tempi;
wire [7:0]tempx;
wire [3:0]tempp;
wire [4:0]temppsw;
wire [12:0]temppsy;
genvar n;
reg [15:0]count;
reg [12:0]arrayy [15:0];
reg [12:0]sumy;
reg [12:0]temp;
reg [12:0]min;
reg [3:0]index;
integer i;
//Below is the instantiation of the Processing Elements to be used. for processing
always @(posedge clk)
count <= count + 1;
assign contx[0] = x;
assign conti[0] =count;
assign contpsw[0]=0;
assign contpsy[0]=0;
generate for ( n=0;n<elements;n=n+1)
begin : pelements
pe3 process(clk,conti[n],contx[n],contp[n],contpsw[n],contpsy[n],mode,conti[n+1],contx[n+1],contp[n+1],contpsw[n+1],contpsy[n+1]);
end
endgenerate
assign tempi = conti[elements];
assign tempx = contx[elements];
assign tempp = contp[elements];
assign temppsw = contpsw[elements];
assign temppsy = contpsy[elements];
always @(posedge clk)
begin
if(mode == 2'b11)
begin
sumy <= sumy + temppsy;
if(contp[elements] != contp[elements-1])
begin
arrayy[tempp] <= sumy;
end
end
end
always @(posedge clk)
begin
if(tempp == 15)
begin
index <= 0;
min <= arrayy[index];
for (i=1;i<16;i=i+1)
begin
if(min > arrayy[i])
begin
min <= arrayy[i];
index <= i;
//Search for min in the arrayy and then identify the index of it and display the output
end
end
end
end
assign pim = index;
endmodule
module pe3(clk,i,x,p,psw,psyi,mode,io,xo,po,pswo,psyo);
//Here evey where PE refers to the PROCESSING ELEMENT
parameter divfac=128; //The factor used to implement decimal multipication of learn rate and weight.
parameter size = 4; //The Image size or the number of pixels in the image
//Input ports of the PROCESSING ELEMENT
input clk;
input [7:0]i; //Index of the input pixel
input [7:0]x; //Value of the pixel input
input [3:0]p; //The Index of the person whose image is being sent
input [4:0]psw; //Partial Sum for weight updating
input [12:0]psyi; //Partial Sum for output calculation
input [1:0]mode; //To select the operation as Recognition Phase or Training Phase 00,01- Recognition
//00- Projection Evaluation in Training Phase
//01- Weight Updation in Training Phase
//11 - Recognition Phase
//Output ports of the PROCESSING ELEMENT
output [7:0]io; //The index of the pixel which is evaluated at this PE and going to next PE
output [7:0]xo; //The value of pixel going to next PE
output [3:0]po; //The index value of the person whose image is under processing
output [4:0]pswo; //The calculated the Partial Sum of Weight update sent to next PE as well as stored here
output [12:0]psyo;
//Register Declarations inside the PROCESSING ELEMENT
reg [4:0]w [size-1:0]; //A register in the processig element to store the weights of the Image
reg [12:0]ylearn [15:0]; //A register to store the projection "Y" of each image max 16 images
reg [4:0]psw1; //A register to store the partial sum evaluated
reg [12:0]pso1; //A register to store the Partial Sum for evaluating the output projection " Y ".
reg [15:0]count; //A register which counts the number of pixels entered the PE and counts which helps in evaluating the Projections
reg [4:0]t; //A register used to evaluate the Partial Sum during Weight updation
reg [12:0]yrcog; //A register which stores the projections during the recognition phase of the new image
reg [12:0]rectmp;
reg [12:0]psyo; //A register which accumulates the partial sum before the projection is evaluated
//Wire Declaration as used inside the processing element
wire [4:0]w1; //This returns the updated weight from the Out22 module and is stored in W reg.
wire [12:0]psj; //This returns the Partial Sum for projection evaluation from the Out11 module
wire [4:0]pswo;
out22 s2(clk,w[i],ylearn[p],x,psw1,w1); //Module which is used for Weight Updation
out11 s1(clk,x,w[i],psy,psj); //module which is used for evaluating the projections
//First Mode of Operation when the projections are to be evaluated.
always @(posedge clk) // MODE - OO coressponds to PROJECTION EVALUATION STAGE
begin
count <= count + 1 ; //Counter is incremented till the image end is reached
if(mode == 2'b00 ) //It checks if the mode of operation is for Output evaluation
begin
pso1 <= pso1 + psj; //Keeps on accumulating the Partial Sum for Output evaluation
if(count==size) //If one image has passed then it starts assigning the outputs . size is a parmameter holding the image size.
begin //This is only after N clock pulses if the number of pixels in the image were N
ylearn[p] <= psj; //The Output is assigned to Ylearn the respective projection
end
end
//Once all the outputs are evaluated the mode is changed to 00 or 01 to Update the weights.
if(mode == 2'b01) //MODE - 01 corresponds to evaluating and updating weights.
begin
t <= (w[i]*ylearn[p])/divfac; // t register is assigned the partial sum which is divided by divfac = 128 to enable the decimal arithmatic operations
psw1 <= psw + t; //PSW1 accumulates the partial sum of the weight updation formula
//Now for the jth PE if the PS has been evaluattes
w[i] <= w1; //The new updated weight from the Out2 module comes as w1 which is assigned to w[i].
end
end
assign pswo = psw1; // Assigns the value of psw1 to psw whenevr it changes.
//Now we shall operate for the recognition phase.
always @(posedge clk) //MODE - 11 Corresponds to last phase of Recognition phase which implies a new input image.
begin
if(mode == 2'b11)
begin
rectmp <=rectmp + (x * (w[i]/128));//The register rectemp in each PE evaluated the projection and stores them in the register.
if(i == size) //When the entire image has passed through a processign element the projection has been computed and is assigned to a separate Register "yrcog".
begin //This is only after N clock pulses if the number of pixels in the image were N
yrcog <= rectmp;
psyo <= (psyi - yrcog);
end
end
end
//Recognition Phase ends here
//Now the inputs to this PE are to be transferred to next one.
assign io = i; //The index of the input pixel is passed onto the next PE.
assign xo = x; //The pixel (value) processed by this PE is passed to next for its processing.
assign po = p; //The image index (Which number of the image is it.?) is also passed on to the next one.
endmodule
module out11(clk,xi,w,psi,psj);
parameter divfac = 128;
input clk;
input [7:0] xi; //The pixel Value input to the PS Calculator for projection.
input [7:0] w ; //The weight vector value input to the PS Calculator for projection evaluation.
input [12:0] psi; //The Input Partial Sum from previous clock pulse.
reg [12:0]m; //The new evaluated output of projection
reg [12:0]psm; //It stores the value of the Partial Sum until the complete image has passed.
//output [12:0]t; //The output to the Output vector "Y "
output [12:0]psj; //The PS Accumulating register in PE which is sent as output.
always @ (clk)
begin
m <= xi * (w/divfac);//It evaluates the projection and stores in m
psm <= m + psi; //psma accumulates the previous partial sum with the newly evaluated .
end
// assign t= m;
assign psj = psm; //The projection is assigned to the output .
endmodule
module out22(clk,w,y,xi,psw,w2);
parameter lrate= 13; //The learning rate of the NN which is indeed (13/128) = 0.01.It simplifies the structure of the algorithm .
parameter divfac = 128;
input [12:0]y ; //The input value of the Projection from the PE.
input [7:0] xi; //The pixel on whose arrival the weights are updated.
input [4:0] w ; //The weight value of the corresponding pixel which will be updated.
input [4:0]psw; //The partial sum which is entering from the previous module and which needs to be accumulated.
input clk;
reg [12:0]d; //The register used for storing a value during the computation of weight according to Hebbian Algorithm.
reg [20:0]out; //The register used for storing a value during the computation of weight according to Hebbian Algorithm.
reg [20:0]temp; //The register used for storing a value during the computation of weight according to Hebbian Algorithm.
reg [20:0]temp1; //The register used for storing a value during the computation of weight according to Hebbian Algorithm.
reg [15:0]y2; //The register used for storing a value during the computation of weight according to Hebbian Algorithm.
reg [20:0]w1; //This is then new weight calculate at the kth time instant.
output [20:0]w2; //The new weight which is being evaluated is returned.
wire [20:0]w2;
always @(posedge clk)
begin
d <= (lrate * y)/divfac; //The entire expression to be evaluated is
out <= d * xi; //w(k+1) = lrate*x*y - w(k) + SUMMATION(w * y)
temp <= out + (w/divfac); //Now actually since we are getting pixels one by one so we keep
y2 <= (w * y)/(128*128) ; //accumulating the value in the summation which gets done at each stage of input
temp1 <= psw + y2; //Finally when one Summation is done we update the weight.
w1 <= (temp - temp1);
end
assign w2 = w1;
endmodule
The schematic layout of the code doesnt display the internal structure after synthesis.Here system is the top module .While the individual modules give a decent schematic layout afte synthesis.I am using Xilinx 9.1ise