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/] [fattree_route.v] - Rev 48

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

`timescale 1ns / 1ps
/**************************************
*
*   fattree rout function
*
***************************************/
 
// ============================================================
//  FATTREE: Nearest Common Ancestor w/ Random  Routing Up
// ============================================================
 
module fattree_nca_random_up_routing  #(
   parameter K   = 2, // number of last level individual router`s endpoints.
   parameter L   = 2 // Fattree layer number (The height of FT)
 
)
(
    reset,
    clk,
    current_addr_encoded,    // connected to current router x address
    current_level,    //connected to current router y address
    dest_addr_encoded,        // destination address
    destport_encoded    // 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
        Kw = log2(K),
        LKw= L*Kw,
        Lw = log2(L);
 
 
 
    input reset,clk;
    input  [LKw-1 :0]    current_addr_encoded;
    input  [Lw-1  :0]    current_level;    
    input  [LKw-1 :0]    dest_addr_encoded;
    output [K :0]    destport_encoded;
    /******************
        destport_encoded format in fat tree. K+1 bit
        destport[K] 
            1'b0  : go down 
            1'b1  : go up
        destport[K-1: 0]: 
            onehot coded. asserted bit show the output port locatation     
    *******************/
 
 
 
    wire  [Kw-1 :0]  current_addr [L-1 : 0];
    wire  [Kw-1 :0]  parrent_dest_addr [L-1 : 0];
    wire  [Kw-1 :0]  dest_addr [L-1 : 0];
    wire  [Kw-1 :0]  current_node_dest_port;
 
    wire [L-1 : 0] parrents_node_missmatch; 
 
    reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
 
`ifdef SYNC_RESET_MODE 
    always @ (posedge clk )begin 
`else 
    always @ (posedge clk or posedge reset)begin 
`endif  
        if(reset) begin 
            counter <= 1;
        end 
        else begin 
            counter <= {counter[0],counter[K-1:1]};         
        end    
    end
 
    assign current_addr [0]={Kw{1'b0}}; 
    assign parrent_dest_addr [0]={Kw{1'b0}}; 
 
    genvar i;
    generate 
    for(i=1; i<L; i=i+1)begin : caddr
        /* verilator lint_off WIDTH */ 
        assign current_addr [i] = (current_level <i)? current_addr_encoded[i*Kw-1 : (i-1)*Kw] : {Kw{1'b0}};
        assign parrent_dest_addr [i] = (current_level<i)? dest_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
        /* verilator lint_on WIDTH */ 
    end
 
 
    for(i=0; i<L; i=i+1) begin : daddr
       // assign current_addr [i] = (current_level >=i)? current_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
 
        assign dest_addr [i] =  dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
        assign parrents_node_missmatch[i]=  current_addr [i] !=  parrent_dest_addr [i]; 
    end//for
    endgenerate
 
   assign current_node_dest_port = dest_addr[current_level];
   wire [K-1:0] current_node_dest_port_one_hot;
 
   bin_to_one_hot #(
    .BIN_WIDTH(Kw),
    .ONE_HOT_WIDTH(K)
   )
   conv
   (
    .bin_code(current_node_dest_port),
    .one_hot_code(current_node_dest_port_one_hot)
   ); 
 
    assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,counter} :  /*go down*/{1'b0,current_node_dest_port_one_hot};
 
endmodule
 
 
 
// ============================================================
//  FATTREE: Nearest Common Ancestor w/ destination port Up. 
//  The up port is selected based on destination connected port num
// ============================================================
 
module fattree_nca_destp_up_routing  #(
   parameter K   = 2, // number of last level individual router`s endpoints.
   parameter L   = 2 // Fattree layer number (The height of FT)
 
)
(
    reset,
    clk,
    current_addr_encoded,    // connected to current router x address
    current_level,    //connected to current router y address
    dest_addr_encoded,        // destination address
    destport_encoded    // 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
        Kw = log2(K),
        LKw= L*Kw,
        Lw = log2(L);
 
 
 
    input reset,clk;
    input  [LKw-1 :0]    current_addr_encoded;
    input  [Lw-1  :0]    current_level;    
    input  [LKw-1 :0]    dest_addr_encoded;
    output [K :0]    destport_encoded;
    /******************
        destport_encoded format in fat tree. K+1 bit
        destport[K] 
            1'b0  : go down 
            1'b1  : go up
        destport[K-1: 0]: 
            onehot coded. asserted bit show the output port locatation     
    *******************/
 
 
 
    wire  [Kw-1 :0]  current_addr [L-1 : 0];
    wire  [Kw-1 :0]  parrent_dest_addr [L-1 : 0];
    wire  [Kw-1 :0]  dest_addr [L-1 : 0];
    wire  [Kw-1 :0]  current_node_dest_port;
 
    wire [L-1 : 0] parrents_node_missmatch; 
 
    reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
 
`ifdef SYNC_RESET_MODE 
    always @ (posedge clk )begin 
`else 
    always @ (posedge clk or posedge reset)begin 
`endif  
        if(reset) begin 
            counter <= 1;
        end 
        else begin 
            counter <= {counter[0],counter[K-1:1]};         
        end    
    end
 
    assign current_addr [0]={Kw{1'b0}}; 
    assign parrent_dest_addr [0]={Kw{1'b0}}; 
 
    genvar i;
    generate 
    for(i=1; i<L; i=i+1) begin : caddr
        assign current_addr [i] = (current_level <i)? current_addr_encoded[i*Kw-1 : (i-1)*Kw] : {Kw{1'b0}};
        assign parrent_dest_addr [i] = (current_level<i)? dest_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
    end
 
 
    for(i=0; i<L; i=i+1) begin : daddr
       // assign current_addr [i] = (current_level >=i)? current_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
 
        assign dest_addr [i] =  dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
        assign parrents_node_missmatch[i]=  current_addr [i] !=  parrent_dest_addr [i]; 
    end//for
    endgenerate
 
   assign current_node_dest_port = dest_addr[current_level];
   wire [K-1:0] current_node_dest_port_one_hot;
 
   bin_to_one_hot #(
    .BIN_WIDTH(Kw),
    .ONE_HOT_WIDTH(K)
   )
   conv
   (
    .bin_code(current_node_dest_port),
    .one_hot_code(current_node_dest_port_one_hot)
   ); 
 
    assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,current_node_dest_port_one_hot} :  /*go down*/{1'b0,current_node_dest_port_one_hot};
 
endmodule
 
 
// ============================================================
//  FATTREE: Nearest Common Ancestor w/ straight port Up. 
//  The up port is in the same column as reciver port
// ============================================================
 
module fattree_nca_straight_up_routing  #(
   parameter K   = 2, // number of last level individual router`s endpoints.
   parameter L   = 2 // Fattree layer number (The height of FT)
 
)
(
    reset,
    clk,
    current_addr_encoded,    // connected to current router x address
    current_level,    //connected to current router y address
    dest_addr_encoded,        // destination address
    destport_encoded    // 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
        Kw = log2(K),
        LKw= L*Kw,
        Lw = log2(L);
 
 
 
    input reset,clk;
 
    input  [LKw-1 :0]    current_addr_encoded;
    input  [Lw-1  :0]    current_level;    
    input  [LKw-1 :0]    dest_addr_encoded;
    output [K :0]    destport_encoded;
 
    /******************
        destport_encoded format in fat tree. K+1 bit
        destport[K] 
            1'b0  : go down 
            1'b1  : go up
        destport[K-1: 0]: 
            onehot coded. asserted bit show the output port locatation     
    *******************/
 
 
 
    wire  [Kw-1 :0]  current_addr [L-1 : 0];
    wire  [Kw-1 :0]  parrent_dest_addr [L-1 : 0];
    wire  [Kw-1 :0]  dest_addr [L-1 : 0];
    wire  [Kw-1 :0]  current_node_dest_port;
 
    wire [L-1 : 0] parrents_node_missmatch; 
 
    reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
 
`ifdef SYNC_RESET_MODE 
    always @ (posedge clk )begin 
`else 
    always @ (posedge clk or posedge reset)begin 
`endif  
        if(reset) begin 
            counter <= 1;
        end 
        else begin 
            counter <= {counter[0],counter[K-1:1]};         
        end    
    end
 
    assign current_addr [0]={Kw{1'b0}}; 
    assign parrent_dest_addr [0]={Kw{1'b0}}; 
 
    genvar i;
    generate 
    for(i=1; i<L; i=i+1)begin : caddr
        assign current_addr [i] = (current_level <i)? current_addr_encoded[i*Kw-1 : (i-1)*Kw] : {Kw{1'b0}};
        assign parrent_dest_addr [i] = (current_level<i)? dest_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
    end
 
 
    for(i=0; i<L; i=i+1)begin : daddr
       // assign current_addr [i] = (current_level >=i)? current_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
 
        assign dest_addr [i] =  dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
        assign parrents_node_missmatch[i]=  current_addr [i] !=  parrent_dest_addr [i]; 
    end//for
    endgenerate
 
   assign current_node_dest_port = dest_addr[current_level];
   wire [K-1:0] current_node_dest_port_one_hot;
 
   bin_to_one_hot #(
    .BIN_WIDTH(Kw),
    .ONE_HOT_WIDTH(K)
   )
   conv
   (
    .bin_code(current_node_dest_port),
    .one_hot_code(current_node_dest_port_one_hot)
   ); 
 
    // if going up the destination port num is statis straigh. It will be filled at reciver port of the next router so leave it empty
    assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,{K{1'b0}}} :  /*go down*/{1'b0,current_node_dest_port_one_hot};
 
endmodule
 
 
module    fattree_destport_up_select #(
      parameter   K=3,
      parameter   SW_LOC=0
)(
        destport_in,
        destport_o
);
 
    input  [K :0]    destport_in;
    output [K :0]    destport_o;
 
    localparam [K-1 : 0] SW_LOC_ONHOT = 1<< SW_LOC; 
 
 
    wire going_up = destport_in[K];
    assign destport_o = (going_up)?  {1'b1,SW_LOC_ONHOT[K-1 : 0]} : destport_in;
 
endmodule
 
 
 
/*************************
 *  fattree_conventional_routing 
 * **********************/
 
 
module fattree_conventional_routing #(
    parameter ROUTE_NAME = "NCA_RND_UP",
    parameter K   = 2, // number of last level individual router`s endpoints.
    parameter L   = 2 // Fattree layer number (The height of FT)
 )
(
    reset,
    clk,
    current_addr_encoded,    // connected to current router x address
    current_level,    //connected to current router y address
    dest_addr_encoded,        // destination address
    destport_encoded    // 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
        Kw = log2(K),
        LKw= L*Kw,
        Lw = log2(L);
 
 
 
    input reset,clk;
    input  [LKw-1 :0]    current_addr_encoded;
    input  [Lw-1  :0]    current_level;    
    input  [LKw-1 :0]    dest_addr_encoded;
    output [K :0]    destport_encoded;
 
 
    generate 
    /* verilator lint_off WIDTH */ 
    if( ROUTE_NAME == "NCA_RND_UP")begin :nca_rnd
    /* verilator lint_on WIDTH */ 
        fattree_nca_random_up_routing #(
            .K(K),
            .L(L)
        )
        nca_random_up
        (
            .reset(reset),
            .clk(clk),
            .current_addr_encoded(current_addr_encoded),
            .current_level(current_level),
            .dest_addr_encoded(dest_addr_encoded),
            .destport_encoded(destport_encoded)
        );
     /* verilator lint_off WIDTH */ 
    end else if ( ROUTE_NAME == "NCA_DST_UP")begin :nca_dst
    /* verilator lint_on WIDTH */ 
        fattree_nca_destp_up_routing #(
            .K(K),
            .L(L)
        )
        nca_random_up
        (
            .reset(reset),
            .clk(clk),
            .current_addr_encoded(current_addr_encoded),
            .current_level(current_level),
            .dest_addr_encoded(dest_addr_encoded),
            .destport_encoded(destport_encoded)
        );
   /* verilator lint_off WIDTH */ 
   end else if ( ROUTE_NAME == "NCA_STRAIGHT_UP")begin :nca_straight
    /* verilator lint_on WIDTH */ 
        fattree_nca_straight_up_routing #(
            .K(K),
            .L(L)
        )
        nca_straight_up
        (
            .reset(reset),
            .clk(clk),
            .current_addr_encoded(current_addr_encoded),
            .current_level(current_level),
            .dest_addr_encoded(dest_addr_encoded),
            .destport_encoded(destport_encoded)
        );
    end else begin 
        // synthesis translate_off
        initial begin 
            $display( "\t ERROR: %s is an undefined routing algorithm for FATTREE topology",ROUTE_NAME);
            $finish;
        end
        // synthesis translate_on
    end
    endgenerate
 
endmodule
 
 
/************************************
 
     fattree_look_ahead_routing
 
*************************************/
 
module fattree_look_ahead_routing #(
    parameter ROUTE_NAME = "NCA_RND_UP",
    parameter P = 4,
    parameter L = 2,
    parameter K = 2
 
)
(
    reset,
    clk,
    destport_encoded,// current router destination port 
    dest_addr_encoded,
    neighbors_rx,
    neighbors_ry,
    lkdestport_encoded // look ahead destination 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
        Kw = log2(K),
        LKw= L*Kw,
        Lw = log2(L),
        PLw = P * Lw,
        PLKw = P * LKw;
 
    input  [K :0]    destport_encoded;
    input  [LKw-1 :0]    dest_addr_encoded;
    input  [PLKw-1 : 0]  neighbors_rx;
    input  [PLw-1 : 0]  neighbors_ry;
    output [K: 0]    lkdestport_encoded;
    input                   reset,clk;
 
    reg  [K :0]    destport_encoded_delayed;
    reg  [LKw-1 :0]    dest_addr_encoded_delayed;
 
     fattree_deterministic_look_ahead_routing #(
        .P(P),
        .ROUTE_NAME(ROUTE_NAME),
        .K(K),
        .L(L)
     )
     look_ahead_routing
     (
        .reset(reset),
        .clk(clk),
        .destport_encoded(destport_encoded_delayed),
        .dest_addr_encoded(dest_addr_encoded_delayed),
        .neighbors_rx(neighbors_rx),
        .neighbors_ry(neighbors_ry),
        .lkdestport_encoded(lkdestport_encoded)
     );
 
 
`ifdef SYNC_RESET_MODE 
    always @ (posedge clk )begin 
`else 
    always @ (posedge clk or posedge reset)begin 
`endif  
        if(reset)begin
            destport_encoded_delayed <= {(K+1){1'b0}};
            dest_addr_encoded_delayed<= {LKw{1'b0}};
        end else begin
            destport_encoded_delayed<=destport_encoded;
            dest_addr_encoded_delayed<=dest_addr_encoded;
        end//else reset
    end//always
 
endmodule
 
 
 
 
 
 
 
/************************************************
 
        deterministic_look_ahead_routing
**********************************************/
 
 
module  fattree_deterministic_look_ahead_routing #(
    parameter P=4,
    parameter ROUTE_NAME = "NCA_RND_UP",
    parameter K   = 2, // number of last level individual router`s endpoints.
    parameter L   = 2 // Fattree layer number (The height of FT)
 
  )
  (
    reset,
    clk,
    destport_encoded,// current router destination port 
    dest_addr_encoded,
    neighbors_rx,
    neighbors_ry,
    lkdestport_encoded // look ahead destination 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
        Kw = log2(K),
        LKw= L*Kw,
        Lw = log2(L),
        PLw = P * Lw,
        PLKw = P * LKw;
 
    input reset,clk;
    input  [K :0]    destport_encoded;
    input  [LKw-1 :0]    dest_addr_encoded;
    input  [PLKw-1 : 0]  neighbors_rx;
    input  [PLw-1 : 0]  neighbors_ry;
    output [K: 0]    lkdestport_encoded;
 
 
    wire  [LKw-1 :0]    next_addr_encoded;
    wire  [Lw-1  :0]    next_level;  
    wire  [K : 0] lkdestport_encoded;  
    wire  [2*K-1 : 0] destport_decoded;
 
    fattree_destport_decoder #(
        .K(K)
    )
    fattree_destport_decoder(
        .destport_encoded_i(destport_encoded),
        .destport_decoded_o(destport_decoded)
    ); 
 
 
    next_router_addr_selector_onehot #(
         .P(P),
         .RXw(LKw), 
         .RYw(Lw)
    )
    addr_predictor
    (
        .destport_onehot(destport_decoded[P-1 : 0]),
        .neighbors_rx(neighbors_rx),
        .neighbors_ry(neighbors_ry),
        .next_rx(next_addr_encoded),
        .next_ry(next_level)
    );
 
 
    fattree_conventional_routing #(        
        .ROUTE_NAME(ROUTE_NAME),
        .K(K),
        .L(L)        
    )
    conv_routing
    (
        .reset(reset),
        .clk(clk),
        .current_addr_encoded(next_addr_encoded),
        .current_level(next_level),
        .dest_addr_encoded(dest_addr_encoded),
        .destport_encoded(lkdestport_encoded)
    );
 
 endmodule
 
 module fattree_destport_decoder #(
     parameter K=2
 
 )(
    destport_decoded_o,
    destport_encoded_i  
 );
 
    input [K:0] destport_encoded_i;
    output [2*K-1 : 0] destport_decoded_o;     
 
    assign destport_decoded_o =   (destport_encoded_i[K])? /*go up*/    {destport_encoded_i[K-1:0],{K{1'b0}}}:
                                                           /*go down*/   {{K{1'b0}},destport_encoded_i[K-1:0]};    
 
endmodule
 
 
 
 
/**********
 *  fattree_mask_non_assignable_destport
 * ********/
 
module fattree_mask_non_assignable_destport #(
    parameter K=4,
    parameter P=2*K,
    parameter SW_LOC = 0        
)
(
    destport_in,
    destport_out        
);
 
    input [2*K-1 : 0] destport_in;
    output [2*K-1 : 0] destport_out;
 
    generate 
    if(P<=K)begin :root //This is a root node there is conectivety between all ports
        assign destport_out = destport_in;    
    end else begin: leaf
        if(SW_LOC < K) begin: down // This port located in lower side of the router. It can send packet to any destport 
            assign destport_out = destport_in;   
        end else begin : up // // This port located in upper side of the router. It cannot send packet to upper port anymore
            assign destport_out[2*K-1 : K] = {K{1'b0}};   
            assign destport_out[K-1 : 0] = destport_in [K-1 : 0];           
        end
    end
    endgenerate
endmodule
 
/********************
 
    distance_gen 
 
********************/
 
module fattree_distance_gen #(
    parameter K= 4,    
    parameter L= 4
)(
    src_addr_encoded,    
    dest_addr_encoded,       
    distance
 
);
 
    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
        Kw = log2(K),
        LKw= L*Kw,
        DISTw= log2(2*L+1);
 
     input  [LKw-1 :0]    src_addr_encoded;
     input  [LKw-1 :0]    dest_addr_encoded;
     output reg [DISTw-1 : 0] distance;
 
 
 
     wire  [Kw-1 :0]  dest_addr [L-1 : 0];
     wire  [Kw-1 :0]  src_addr [L-1 : 0];
     wire  [L-1 : 0] diffrent;
 
 
    genvar i;
    generate 
    for(i=0; i<L; i=i+1)begin : daddr      
        assign dest_addr [i] =  dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
        assign src_addr [i] =  src_addr_encoded[(i+1)*Kw-1 : i*Kw];
        assign diffrent[i] = dest_addr [i] != src_addr [i];
    end//for
    endgenerate
 
    wire [11:0] tmp;
    assign tmp= {{(12-L){1'b0}},diffrent};
    /* verilator lint_off WIDTH */
    always @(*)begin
        if (tmp[10]) distance =21;
        else if (tmp[9]) distance =19;
        else if (tmp[8]) distance =17;
        else if (tmp[7]) distance =15;
        else if (tmp[6]) distance =13;
        else if (tmp[5]) distance =11;
        else if (tmp[4]) distance =9;
        else if (tmp[3]) distance =7;
        else if (tmp[2]) distance =5;
        else if (tmp[1]) distance =3;
        else distance =1;    
    end
    /* verilator lint_on WIDTH */
 
 
 
 
endmodule
 
/**************
    fattree_addr_encoder
    most probably it is only needed for simulation purposes
***************/  
 
module  fattree_addr_encoder #(
    parameter   K=2,
    parameter   L=2
 
)(
    id,
    code
);
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end        
      end   
    endfunction // log2 
 
    function integer powi;
        input integer x,y;
        integer i;begin //compute x to the y
        powi=1;
        for (i = 0; i <y; i=i+1 ) begin 
            powi=powi * x;
        end
        end   
    endfunction // log2 
 
    function integer addrencode;
        input integer pos,k,n,kw;
        integer pow,i,tmp;begin
        addrencode=0;
        pow=1;
        for (i = 0; i <n; i=i+1 ) begin 
            tmp=(pos/pow);
            tmp=tmp%k;
            tmp=tmp<<i*kw;
            addrencode=addrencode | tmp;
            pow=pow * k;
        end
        end   
    endfunction // log2 
 
 
    localparam       
        NE = powi( K,L ),  //total number of endpoints
        NEw = log2(NE),
        Kw=log2(K),
        LKw=L*Kw;
 
 
     input [NEw-1 :0] id;
     output [LKw-1 : 0] code;
 
    wire [LKw-1 : 0 ] codes [NE-1 : 0];
    genvar i;
    generate 
    for(i=0; i< NE; i=i+1) begin : endpoints
        //Endpoint decoded address
        localparam [LKw-1 : 0] ENDPX= addrencode(i,K,L,Kw);
        assign codes[i] = ENDPX;            
    end
    endgenerate
 
    assign code = codes[id];
endmodule
 
 
 
/**************
    fattree_addr_decoder
    most probably it is only needed for simulation 
***************/  
 
module  fattree_addr_decoder #(
    parameter   K=2,
    parameter   L=2
 
)(
    id,
    code
);
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end        
      end   
    endfunction // log2 
 
    function integer powi;
        input integer x,y;
        integer i;begin //compute x to the y
        powi=1;
        for (i = 0; i <y; i=i+1 ) begin 
            powi=powi * x;
        end
        end   
    endfunction // log2 
 
    function integer addrencode;
        input integer pos,k,n,kw;
        integer pow,i,tmp;begin
        addrencode=0;
        pow=1;
        for (i = 0; i <n; i=i+1 ) begin 
            tmp=(pos/pow);
            tmp=tmp%k;
            tmp=tmp<<i*kw;
            addrencode=addrencode | tmp;
            pow=pow * k;
        end
        end   
    endfunction // log2 
 
 
    localparam       
        NE = powi( K,L ),  //total number of endpoints
        NEw = log2(NE),
        Kw=log2(K),
        LKw=L*Kw;
 
 
     output [NEw-1 :0] id;
     input  [LKw-1 : 0] code;
 
    wire  [NEw-1 : 0] codes  [2**LKw-1 : 0 ];
    genvar i;
    generate 
    for(i=0; i< NE; i=i+1) begin : endpoints
        //Endpoint decoded address
        /* verilator lint_off WIDTH */
        localparam [LKw-1 : 0] ENDPX= addrencode(i,K,L,Kw);
        /* verilator lint_on WIDTH */
        assign codes[ENDPX] = i;            
    end
    endgenerate
 
    assign id = codes[code];
endmodule
 
/**************
 * mesh_torus_ssa_check_destport_conflict
 * check if the incomming flit goes to SS port
 * ************/
 
module fattree_ssa_check_destport #(
    parameter DSTPw = 5,
    parameter SS_PORT=0
)
(
    destport_encoded, //exsited packet dest port
    destport_in_encoded, // incomming packet dest port
    ss_port_hdr_flit, // asserted if the header incomming flit goes to ss port
    ss_port_nonhdr_flit // asserted if the body or tail incomming flit goes to ss port
 );
 
    localparam K= DSTPw-1;
    localparam SS_LOC = (SS_PORT < K)? SS_PORT : SS_PORT-K;
 
    input [DSTPw-1 : 0] destport_encoded, destport_in_encoded; 
    output ss_port_hdr_flit, ss_port_nonhdr_flit;
 
 
/******************
        destport_encoded format in fat tree. K+1 bit
        destport[K] 
            1'b0  : go down 
            1'b1  : go up
        destport[K-1: 0]: 
            onehot coded. asserted bit show the output port locatation     
*******************/
 
    wire up_flg = destport_encoded[DSTPw-1];
    wire up_flg_in = destport_in_encoded[DSTPw-1];
    wire down_flg = ~destport_encoded[DSTPw-1];
    wire down_flg_in = ~destport_in_encoded[DSTPw-1];   
 
 
    generate 
    if(SS_PORT < K) begin :SS_DOWN // the ssa port is located in down router side
        assign ss_port_hdr_flit = destport_in_encoded [SS_LOC] & down_flg_in;   
        assign ss_port_nonhdr_flit =  destport_encoded[SS_LOC] & down_flg;   
    end else begin : SS_UP
        assign ss_port_hdr_flit = destport_in_encoded [SS_LOC] & up_flg_in;   
        assign ss_port_nonhdr_flit =  destport_encoded[SS_LOC] & up_flg;       
    end
    endgenerate    
 
endmodule
 
/*
module fattree_add_ss_port #(   
    parameter SW_LOC=1,
    parameter P=5
)(
    destport_in,
    destport_out 
);
    localparam
        P_1     =   P-1,
        DISABLED   =    P;
 
    localparam  SS_PORT_FATTREE_EVEN =  (SW_LOC < (P/2) )? (P/2)+ SW_LOC-1 : SW_LOC - (P/2);
    localparam  SS_PORT_FATTREE_ODD  =  (SW_LOC == (P-1)/2)?   DISABLED:
                                        (SW_LOC < ((P+1)/2) )? ((P+1)/2)+ SW_LOC-1 : SW_LOC - ((P+1)/2);
 
    localparam  SS_PORT_FATTREE = (P[0]==1'b0) ? SS_PORT_FATTREE_EVEN : SS_PORT_FATTREE_ODD;
 
    localparam  SS_PORT      =   SS_PORT_FATTREE;
 
 
 
 
    input       [P_1-1  :   0] destport_in;
    output reg  [P_1-1  :   0] destport_out; 
 
 
 
    always @(*)begin 
        destport_out=destport_in;
        if( SS_PORT != DISABLED ) begin 
            if(destport_in=={P_1{1'b0}}) destport_out[SS_PORT]= 1'b1;
        end    
    end 
 
 
endmodule
 */
module fattree_router_addr_decode #(
    parameter K=4,
    parameter L=4
)(
    r_addr,
    rx,
    rl
    //valid
);
 
    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
        Kw = log2(K),
        LKw= L*Kw,
        Lw = log2(L),
        RAw= LKw + Lw;
 
    input   [RAw-1 : 0]   r_addr;
    output  [LKw-1 :0]    rx;
    output  [Lw-1  :0]    rl;  
 
    assign {rl,rx} = r_addr;
 
endmodule
 
 
//decode and mask destport  
module  fattree_destp_generator #(
    parameter K=2,
    parameter P=2*K,
    parameter SW_LOC=0,
    parameter DSTPw=4,
    parameter SELF_LOOP_EN = "NO"
)(
    dest_port_in_encoded,
    dest_port_out
);
 
    localparam P_1 = (SELF_LOOP_EN == "NO")? P-1 : P;
    input  [DSTPw-1:0] dest_port_in_encoded;
    output [P_1-1 : 0] dest_port_out;
 
 
    wire [2*K-1 : 0] destport_decoded;
    wire [2*K-1 : 0] destport_masked;
 
 
        fattree_destport_decoder #(           
            .K(K)
        )
        destport_decoder
        (
            .destport_encoded_i(dest_port_in_encoded),
            .destport_decoded_o(destport_decoded)
        );
 
        fattree_mask_non_assignable_destport #(
            .K(K),
            .P(P),
            .SW_LOC(SW_LOC)        
        )
        mask
        (
            .destport_in(destport_decoded),
            .destport_out(destport_masked)        
        );
 
        generate 
        if(SELF_LOOP_EN == "NO") begin : nslp
            remove_sw_loc_one_hot #(
                .P(P),
                .SW_LOC(SW_LOC)
            )
            conv
            (
                .destport_in(destport_masked[P-1 : 0]),
                .destport_out(dest_port_out[P_1-1  :   0 ])
            );  
        end else begin : slp 
            assign dest_port_out= destport_masked [P_1-1  :   0 ];
        end
        endgenerate
 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.