OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_noc/] [route_torus.v] - Rev 56

Go to most recent revision | Compare with Previous | Blame | View Log

`timescale 1ns/1ps
 
/**********************************************************************
**	File:  route_torus.v
**    
**	Copyright (C) 2014-2017  Alireza Monemi
**    
**	This file is part of ProNoC 
**
**	ProNoC ( stands for Prototype Network-on-chip)  is free software: 
**	you can redistribute it and/or modify it under the terms of the GNU
**	Lesser General Public License as published by the Free Software Foundation,
**	either version 2 of the License, or (at your option) any later version.
**
** 	ProNoC is distributed in the hope that it will be useful, but WITHOUT
** 	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** 	or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
** 	Public License for more details.
**
** 	You should have received a copy of the GNU Lesser General Public
** 	License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
**
**
**	Description: 
**	Different routing algorithms (determinstic,partially adaptive and fully adaptive)
**	for 2D torus-based topology
**
**************************************************************/
 
 
/********************************************
                    Deterministic
*********************************************/
 
    /********************************************
                        TRANC
    *********************************************/
module tranc_xy_routing #(
    parameter NX   =    4,
    parameter NY   =    4   
)
(
    current_x,
    current_y,
    dest_x,
    dest_y,
    destport_encoded
 
);
 
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end 	   
      end   
    endfunction // log2 
 
    localparam  P           =   5,
                Xw          =   log2(NX),
                Yw          =   log2(NY),
                Pw          =   log2(P),
                DSTw        =   P-1;
 
 
    input   [Xw-1       :   0] current_x;
    input   [Yw-1       :   0] current_y;
    input   [Xw-1       :   0] dest_x;
    input   [Yw-1       :   0] dest_y;
    output  [DSTw -1    :   0] destport_encoded;
 
    localparam      
        LOCAL   =   5'b00001,  
        EAST    =   5'b00010,   
        NORTH   =   5'b00100,    
        WEST    =   5'b01000,  
        SOUTH   =   5'b10000;    
 
 
    wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min;
    wire same_x,same_y;
 
 
    tranc_dir #(
        .NX(NX),
        .NY(NY)
    )
    tranc_dir(
        .tranc_x_plus(tranc_x_plus),
        .tranc_x_min(tranc_x_min),
        .tranc_y_plus(tranc_y_plus),
        .tranc_y_min(tranc_y_min),
        .same_x(same_x),
        .same_y(same_y),
        .current_x(current_x),
        .current_y(current_y),
        .dest_x(dest_x),
        .dest_y(dest_y)
 
    );
 
        reg [P-1 : 0] dstport_one_hot;
 
 
    always@(*)begin
        if (same_x & same_y) dstport_one_hot= LOCAL;
        else    begin 
            if            (tranc_x_plus)     dstport_one_hot= EAST;
            else if        (tranc_x_min)    dstport_one_hot= WEST;
            else if     (tranc_y_plus)    dstport_one_hot= SOUTH;
            else                        dstport_one_hot= NORTH;
        end
    end
 
    mesh_tori_encode_dstport conv(
    	.dstport_one_hot(dstport_one_hot),
    	.dstport_encoded(destport_encoded)
    );
 
 
 
 
    endmodule
 
/********************************************
                    Partial adaptive
*********************************************/
 
    /********************************************
                    TRANC West-First 
    *********************************************/
 
 
    module tranc_west_first_routing #(
       parameter NX   =   4,
       parameter NY    =   4
    )
    (       
        current_x,  // current router x address
        current_y,  // current router y address
        dest_x,     // destination x address
        dest_y,     // destination y address
        destport    // router output port
 
 
    );
 
 
 
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end        
      end   
    endfunction // log2 
 
 
    localparam  P   =   5,
                P_1 =   P-1,
                Xw  =   log2(NX),
                Yw  =   log2(NY);
 
    input  [Xw-1        :0] current_x;
    input  [Yw-1        :0] current_y;
    input  [Xw-1        :0] dest_x;
    input  [Yw-1        :0] dest_y;
    output [P_1-1       :0] destport;
 
 
 
    localparam LOCAL=   3'd0;  
    localparam EAST =   3'd1; 
    localparam NORTH=   3'd2;  
    localparam WEST =   3'd3;  
    localparam SOUTH=   3'd4;  
 
    wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min;
    wire same_x,same_y;
 
 
    tranc_dir #(
        .NX(NX),
        .NY(NY)
    )
    tranc_dir(
        .tranc_x_plus(tranc_x_plus),
        .tranc_x_min(tranc_x_min),
        .tranc_y_plus(tranc_y_plus),
        .tranc_y_min(tranc_y_min),
        .same_x(same_x),
        .same_y(same_y),
        .current_x(current_x),
        .current_y(current_y),
        .dest_x(dest_x),
        .dest_y(dest_y)
 
    );
 
    reg [P-1    :    0]    possible_out_port;
 
    always @(*)begin     
        possible_out_port = 5'd0;
        if(same_x && same_y) begin
            possible_out_port [LOCAL]=1'b1;
        end
        else if       (tranc_x_min) begin 
            possible_out_port [WEST]    = 1'b1;
        end
        else if (tranc_x_plus && tranc_y_min) begin
            possible_out_port [EAST]=1'b1;
            possible_out_port [NORTH]=1'b1;
        end
        else if(tranc_x_plus && tranc_y_plus) begin
            possible_out_port [EAST]=1'b1;
            possible_out_port [SOUTH]=1'b1;
        end
        else if( tranc_x_plus && same_y) begin 
            possible_out_port [EAST]=1'b1;
        end
        else if(same_x && tranc_y_min) begin 
            possible_out_port [NORTH]=1'b1;
        end
        else if(same_x && tranc_y_plus) begin 
            possible_out_port [SOUTH]=1'b1;
        end
    end    
 
    // code the destination port
    wire x,y,a,b;
    assign x = tranc_x_plus;
    assign y = tranc_y_plus;
    assign a = possible_out_port[EAST] | possible_out_port[WEST]; 
    assign b = possible_out_port[NORTH]| possible_out_port[SOUTH];
    assign destport = {x,y,a,b};
 
 
    endmodule
 
 
 
    /********************************************
                    TRANC North-Last 
    *********************************************/
 
 
    module tranc_north_last_routing #(
       parameter NX   =   4,
       parameter NY    =   4
    )
    (       
        current_x,  // current router x address
        current_y,  // current router y address
        dest_x,     // destination x address
        dest_y,     // destination y address
        destport    // router output port
 
 
    );
 
 
 
 
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end 	   
      end   
    endfunction // log2 
 
 
    localparam  P   =   5,
                P_1 =   P-1,
                Xw  =   log2(NX),
                Yw  =   log2(NY);
 
    input  [Xw-1        :0] current_x;
    input  [Yw-1        :0] current_y;
    input  [Xw-1        :0] dest_x;
    input  [Yw-1        :0] dest_y;
    output [P_1-1       :0] destport;
 
 
 
    localparam LOCAL=   3'd0;  
    localparam EAST =   3'd1; 
    localparam NORTH=   3'd2;  
    localparam WEST =   3'd3;  
    localparam SOUTH=   3'd4;  
 
    wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min;
    wire same_x,same_y;
 
 
    tranc_dir #(
        .NX(NX),
        .NY(NY)
    )
    tranc_dir(
        .tranc_x_plus(tranc_x_plus),
        .tranc_x_min(tranc_x_min),
        .tranc_y_plus(tranc_y_plus),
        .tranc_y_min(tranc_y_min),
        .same_x(same_x),
        .same_y(same_y),
        .current_x(current_x),
        .current_y(current_y),
        .dest_x(dest_x),
        .dest_y(dest_y)
 
    );
 
    reg [P-1    :   0]  possible_out_port;
 
     // north last routing algorithm does not allow turns from north to east or from north to west.
 
   always @(*)begin     
        possible_out_port       = 5'd0;
        if(same_x &&  same_y) begin 
            possible_out_port [LOCAL]=1'b1;
        end
        else if (tranc_x_min && tranc_y_min) begin 
            possible_out_port   [WEST]= 1'b1;
           // possible_out_port   [NORTH]= 1'b1;
        end 
        else if (tranc_x_min && tranc_y_plus) begin 
            possible_out_port   [WEST]= 1'b1;
            possible_out_port   [SOUTH]= 1'b1;
        end 
        else if (tranc_x_plus &&  tranc_y_min) begin 
            possible_out_port   [EAST]= 1'b1;
           // possible_out_port   [NORTH]= 1'b1;
 
        end
        else if (tranc_x_plus &&  tranc_y_plus) begin 
            possible_out_port   [EAST]= 1'b1;
            possible_out_port   [SOUTH]= 1'b1;
        end
        else if (tranc_x_min && same_y) begin 
            possible_out_port   [WEST]= 1'b1;
        end
        else if (tranc_x_plus && same_y) begin 
            possible_out_port   [EAST]= 1'b1;
        end
        else if (same_x && tranc_y_min) begin 
            possible_out_port   [NORTH]= 1'b1;
        end
        else if (same_x && tranc_y_plus) begin 
            possible_out_port   [SOUTH]= 1'b1;
        end
    end
 
    // code the destination port
    wire x,y,a,b;
    assign x = tranc_x_plus;
    assign y = tranc_y_plus;
    assign a = possible_out_port[EAST] | possible_out_port[WEST]; 
    assign b = possible_out_port[NORTH]| possible_out_port[SOUTH];
    assign destport = {x,y,a,b};
 
 
    endmodule
 
 
 
 
    /********************************************
                    TRANC North-Last 
    *********************************************/
 
 
    module tranc_negetive_first_routing #(
       parameter NX   =   4,
       parameter NY   =   4
    )
    (       
        current_x,  // current router x address
        current_y,  // current router y address
        dest_x,     // destination x address
        dest_y,     // destination y address
        destport    // router output port
 
 
    );
 
 
 
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end        
      end   
    endfunction // log2 
 
 
    localparam  P   =   5,
                P_1 =   P-1,
                Xw  =   log2(NX),
                Yw  =   log2(NY);
 
    input  [Xw-1        :0] current_x;
    input  [Yw-1        :0] current_y;
    input  [Xw-1        :0] dest_x;
    input  [Yw-1        :0] dest_y;
    output [P_1-1       :0] destport;
 
 
 
    localparam LOCAL=   3'd0;  
    localparam EAST =   3'd1; 
    localparam NORTH=   3'd2;  
    localparam WEST =   3'd3;  
    localparam SOUTH=   3'd4;  
 
    wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min;
    wire same_x,same_y;
 
 
    tranc_dir #(
        .NX(NX),
        .NY(NY)
    )
    tranc_dir(
        .tranc_x_plus(tranc_x_plus),
        .tranc_x_min(tranc_x_min),
        .tranc_y_plus(tranc_y_plus),
        .tranc_y_min(tranc_y_min),
        .same_x(same_x),
        .same_y(same_y),
        .current_x(current_x),
        .current_y(current_y),
        .dest_x(dest_x),
        .dest_y(dest_y)
 
    );
 
    reg [P-1    :   0]  possible_out_port;
 
     // The negetive fist routing algorithm does net allow turns from north to west or from east to south.
 
   always @(*)begin     
        possible_out_port       = 5'd0;
        if(same_x &&  same_y) begin 
            possible_out_port [LOCAL]=1'b1;
        end
        else if (tranc_x_min && tranc_y_min) begin 
            possible_out_port   [WEST]= 1'b1;
           // possible_out_port   [NORTH]= 1'b1;
        end 
        else if (tranc_x_min && tranc_y_plus) begin 
            possible_out_port   [WEST]= 1'b1;
            possible_out_port   [SOUTH]= 1'b1;
        end 
        else if (tranc_x_plus &&  tranc_y_min) begin 
            possible_out_port   [EAST]= 1'b1;
            possible_out_port   [NORTH]= 1'b1;
 
        end
        else if (tranc_x_plus &&  tranc_y_plus) begin 
           // possible_out_port   [EAST]= 1'b1;
            possible_out_port   [SOUTH]= 1'b1;
        end
        else if (tranc_x_min && same_y) begin 
            possible_out_port   [WEST]= 1'b1;
        end
        else if (tranc_x_plus && same_y) begin 
            possible_out_port   [EAST]= 1'b1;
        end
        else if (same_x && tranc_y_min) begin 
            possible_out_port   [NORTH]= 1'b1;
        end
        else if (same_x && tranc_y_plus) begin 
            possible_out_port   [SOUTH]= 1'b1;
        end
    end
 
    // code the destination port
    wire x,y,a,b;
    assign x = tranc_x_plus;
    assign y = tranc_y_plus;
    assign a = possible_out_port[EAST] | possible_out_port[WEST]; 
    assign b = possible_out_port[NORTH]| possible_out_port[SOUTH];
    assign destport = {x,y,a,b};
 
 
    endmodule
 
 
 
/***********************************
        fully adaptive
 
***********************************/
 
    /************************************
 
        Duato’s Fully Adaptive
 
    *************************************/    
 
 
 
    module tranc_duato_routing #(
        parameter NX  =   4,
        parameter NY  =   4
    )
    (       
        current_x,  // current router x address
        current_y,  // current router y address
        dest_x,     // destination x address
        dest_y,     // destination y address
        destport    // router output port
 
 
    );
 
 
 
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end        
      end   
    endfunction // log2 
 
 
    localparam  P   =   5,
                P_1 =   P-1,
                Xw  =   log2(NX),
                Yw  =   log2(NY);
 
    input  [Xw-1        :0] current_x;
    input  [Yw-1        :0] current_y;
    input  [Xw-1        :0] dest_x;
    input  [Yw-1        :0] dest_y;
    output [P_1-1       :0] destport;
 
 
 
    localparam LOCAL=   3'd0;  
    localparam EAST =   3'd1; 
    localparam NORTH=   3'd2;  
    localparam WEST =   3'd3;  
    localparam SOUTH=   3'd4;  
 
 
    wire tranc_x_plus,tranc_y_plus,tranc_x_min,tranc_y_min;
    wire same_x,same_y;
 
 
    tranc_dir #(
        .NX(NX),
        .NY(NY)
    )
    tranc_dir(
        .tranc_x_plus(tranc_x_plus),
        .tranc_x_min(tranc_x_min),
        .tranc_y_plus(tranc_y_plus),
        .tranc_y_min(tranc_y_min),
        .same_x(same_x),
        .same_y(same_y),
        .current_x(current_x),
        .current_y(current_y),
        .dest_x(dest_x),
        .dest_y(dest_y)
 
    );
 
 
    reg [P-1    :    0]    possible_out_port;
 
 
    always @(*)begin     
        possible_out_port         = 5'd0;
        if(same_x &&  same_y) begin 
            possible_out_port [LOCAL]=1'b1;
        end
        else if (tranc_x_min && tranc_y_min) begin 
            possible_out_port     [WEST]= 1'b1;
            possible_out_port     [NORTH]= 1'b1;
        end 
        else if (tranc_x_min && tranc_y_plus) begin 
            possible_out_port     [WEST]= 1'b1;
            possible_out_port     [SOUTH]= 1'b1;
        end 
        else if (tranc_x_min &&    same_y) begin 
            possible_out_port     [WEST]= 1'b1;
        end
        else if (tranc_x_plus &&  tranc_y_min) begin 
            possible_out_port     [EAST]= 1'b1;
            possible_out_port     [NORTH]= 1'b1;
 
        end
        else if (tranc_x_plus &&  tranc_y_plus) begin 
            possible_out_port     [EAST]= 1'b1;
            possible_out_port     [SOUTH]= 1'b1;
        end
        else if (tranc_x_plus && same_y) begin 
            possible_out_port     [EAST]= 1'b1;
        end
        else if (same_x && tranc_y_min) begin 
            possible_out_port     [NORTH]= 1'b1;
        end
        else if (same_x && tranc_y_plus) begin 
            possible_out_port     [SOUTH]= 1'b1;
        end
    end
 
    // code the destination port
    wire x,y,a,b;
    assign x = tranc_x_plus;
    assign y = tranc_y_plus;
    assign a = possible_out_port[EAST] | possible_out_port[WEST]; 
    assign b = possible_out_port[NORTH]| possible_out_port[SOUTH];
    assign destport = {x,y,a,b};
 
 
    endmodule
 
 
 
    /****************************************
 
       tranc_dir
 
 
    ****************************************/
 
module tranc_dir #(
    parameter NX   =    4,
    parameter NY   =    4
)(
    current_x,
    current_y,
    dest_x,
    dest_y,
    tranc_x_plus,
    tranc_x_min,
    tranc_y_plus,
    tranc_y_min,
    same_x,
    same_y
);
 
 
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end        
      end   
    endfunction // log2 
 
    /* verilator lint_off WIDTH */
    localparam  Xw          =   log2(NX),
                Yw          =   log2(NY);
 
 
    output reg tranc_x_plus;
    output reg tranc_x_min;
    output reg tranc_y_plus;
    output reg tranc_y_min;
    output     same_x,same_y;
 
    input   [Xw-1       :   0] current_x;
    input   [Yw-1       :   0] current_y;
    input   [Xw-1       :   0] dest_x;
    input   [Yw-1       :   0] dest_y;
 
    localparam SIGNED_X_WIDTH   =  (Xw<3) ? 4 : Xw+1;
    localparam SIGNED_Y_WIDTH   =  (Yw<3) ? 4 : Yw+1;
 
    wire signed [SIGNED_X_WIDTH-1       :0] xc;//current 
    wire signed [SIGNED_X_WIDTH-1       :0] xd;//destination
    wire signed [SIGNED_Y_WIDTH-1       :0] yc;//current 
    wire signed [SIGNED_Y_WIDTH-1       :0] yd;//destination
    wire signed [SIGNED_X_WIDTH-1       :0] xdiff;
    wire signed [SIGNED_Y_WIDTH-1       :0] ydiff; 
 
 
    assign  xc  ={{(SIGNED_X_WIDTH-Xw){1'b0}}, current_x [Xw-1      :0]};
    assign  yc  ={{(SIGNED_Y_WIDTH-Yw){1'b0}}, current_y [Yw-1      :0]};
    assign  xd  ={{(SIGNED_X_WIDTH-Xw){1'b0}}, dest_x};
    assign  yd  ={{(SIGNED_Y_WIDTH-Yw){1'b0}}, dest_y};
    assign  xdiff   = xd-xc;
    assign  ydiff   = yd-yc;
 
 
    always@ (*)begin 
        tranc_x_plus    =1'b0;
        tranc_x_min     =1'b0;
        tranc_y_plus    =1'b0;
        tranc_y_min     =1'b0;
        if(xdiff!=0)begin 
            if ((xdiff ==1) || 
                 (xdiff == (-NX+1)) ||
                 ((xc == (NX-4)) && (xd == (NX-2))) ||
                 ((xc >= (NX-2)) && (xd <= (NX-4))) ||
                 ((xdiff> 0) && (xd<= (NX-3)))) 
                    tranc_x_plus    = 1'b1;
            else    tranc_x_min     = 1'b1;
        end
        if(ydiff!=0)begin   
            if ((ydiff ==1) ||
                (ydiff == (-NY+1)) ||
                ((yc == (NY-4)) && (yd == (NY-2))) ||
                ((yc    >= NY-2) && (yd<= NY-4)) ||
                ((ydiff > 0) && (yd<= NY-3)))
                    tranc_y_plus    = 1'b1;
            else    tranc_y_min     = 1'b1;
        end
    end//always
 
    assign same_x = (xdiff == 0);
    assign same_y = (ydiff == 0);
 
    /* verilator lint_on WIDTH */
 
endmodule
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.