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/] [arbiter.v] - Rev 54

Compare with Previous | Blame | View Log

 `timescale     1ns/1ps
/**********************************************************************
**	File: arbiter.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: 
**	This file contains several Fixed prority and round robin 
**	arbiters 
**
******************************************************************************/ 
 
 
/*****************************************
*        
* general round robin arbiter
* 
*
******************************************/
`include "pronoc_def.v"
 
 
 
module arbiter #(
    parameter    ARBITER_WIDTH    =8
 
)
(    
   clk, 
   reset, 
   request, 
   grant,
   any_grant
);
 
 
    input    [ARBITER_WIDTH-1             :    0]    request;
    output    [ARBITER_WIDTH-1            :    0]    grant;
    output                                        any_grant;
    input                                        clk;
    input                                        reset;
 
 
 
    generate 
    if(ARBITER_WIDTH==1)  begin: w1
        assign grant= request;
        assign any_grant =request;
    end else if(ARBITER_WIDTH<=4) begin: w4
        //my own arbiter 
        my_one_hot_arbiter #(
            .ARBITER_WIDTH    (ARBITER_WIDTH)
        )
        one_hot_arb
        (    
            .clk            (clk), 
            .reset         (reset), 
            .request        (request), 
            .grant        (grant),
            .any_grant    (any_grant)
        );
 
    end else begin : wb4
 
        thermo_arbiter #(
            .ARBITER_WIDTH    (ARBITER_WIDTH)
        )
        one_hot_arb
        (    
            .clk            (clk), 
            .reset         (reset), 
            .request        (request), 
            .grant        (grant),
            .any_grant    (any_grant)
        );
    end
    endgenerate
endmodule
 
/*****************************************
*
*        arbiter_priority_en
* RRA with external priority enable signal
*
******************************************/
 
module arbiter_priority_en #(
        parameter    ARBITER_WIDTH    =8
 
)
(    
   clk, 
   reset, 
   request, 
   grant,
   any_grant,
   priority_en
);
 
 
 
 
    input        [ARBITER_WIDTH-1             :    0]    request;
    output    [ARBITER_WIDTH-1            :    0]    grant;
    output                                            any_grant;
    input                                                clk;
    input                                                reset;
    input                                              priority_en;
 
 
    generate 
    if(ARBITER_WIDTH==1)  begin: w1
        assign grant= request;
        assign any_grant =request;
    end else if(ARBITER_WIDTH<=4) begin: w4
        //my own arbiter 
        my_one_hot_arbiter_priority_en #(
            .ARBITER_WIDTH    (ARBITER_WIDTH)
        )
        one_hot_arb
        (    
            .clk            (clk), 
            .reset         (reset), 
            .request        (request), 
            .grant        (grant),
            .any_grant    (any_grant),
            .priority_en (priority_en)
 
        );
 
    end else begin :wb4
 
        thermo_arbiter_priority_en #(
            .ARBITER_WIDTH    (ARBITER_WIDTH)
        )
        one_hot_arb
        (    
            .clk            (clk), 
            .reset         (reset), 
            .request        (request), 
            .grant        (grant),
            .any_grant    (any_grant),
            .priority_en (priority_en)
        );
    end
endgenerate
endmodule
 
 
 
/******************************************************
*	my_one_hot_arbiter
* RRA with binary-coded priority register. Binary-coded 
* Priority results in less area cost and CPD for arbire 
* width of 4 and smaller only. 
*
******************************************************/
 
 
 
module my_one_hot_arbiter #(
    parameter ARBITER_WIDTH    =4
 
 
)
(
    input        [ARBITER_WIDTH-1             :    0]    request,
    output    [ARBITER_WIDTH-1            :    0]    grant,
    output                                            any_grant,
    input                                                clk,
    input                                                reset
);
 
    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 ARBITER_BIN_WIDTH= log2(ARBITER_WIDTH);
    reg     [ARBITER_BIN_WIDTH-1        :    0]     low_pr;
    wire     [ARBITER_BIN_WIDTH-1        :    0]     grant_bcd;
 
    one_hot_to_bin #(
        .ONE_HOT_WIDTH    (ARBITER_WIDTH)
    )conv
    (
    .one_hot_code(grant),
    .bin_code(grant_bcd)
 
    );
 
    always @ (`pronoc_clk_reset_edge )begin 
        if(`pronoc_reset) begin
            low_pr    <=    {ARBITER_BIN_WIDTH{1'b0}};
        end else begin
            if(any_grant) low_pr <= grant_bcd;
        end
    end
 
 
    assign any_grant = | request;
 
    generate 
        if(ARBITER_WIDTH    ==2) begin: w2        arbiter_2_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
        if(ARBITER_WIDTH    ==3) begin: w3        arbiter_3_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
        if(ARBITER_WIDTH    ==4) begin: w4        arbiter_4_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
    endgenerate
 
endmodule
 
 
module arbiter_2_one_hot(
     input      [1             :    0]    in,
     output    reg[1                :    0]    out,
     input                                low_pr
);
always @(*) begin
     out=2'b00;
      case(low_pr)
         1'd0:
             if(in[1])                 out=2'b10;
             else if(in[0])         out=2'b01;
         1'd1:
             if(in[0])                 out=2'b01;
             else if(in[1])         out=2'b10;
          default: out=2'b00;
     endcase 
  end
 endmodule 
 
 
 
 
module arbiter_3_one_hot(
     input      [2             :    0]    in,
     output    reg[2                :    0]    out,
     input        [1                :    0]    low_pr
);
always @(*) begin
  out=3'b000;
      case(low_pr)
         2'd0:
             if(in[1])                 out=3'b010;
             else if(in[2])         out=3'b100;
             else if(in[0])         out=3'b001;
         2'd1:
             if(in[2])                 out=3'b100;
             else if(in[0])         out=3'b001;
             else if(in[1])         out=3'b010;
         2'd2:
             if(in[0])                 out=3'b001;
             else if(in[1])         out=3'b010;
             else if(in[2])         out=3'b100;
         default: out=3'b000;
     endcase 
  end
 endmodule 
 
 
 module arbiter_4_one_hot(
     input      [3             :    0]    in,
     output    reg[3                :    0]    out,
     input        [1                :    0]    low_pr
);
always @(*) begin
  out=4'b0000;
      case(low_pr)
         2'd0:
             if(in[1])                 out=4'b0010;
             else if(in[2])         out=4'b0100;
             else if(in[3])         out=4'b1000;
             else if(in[0])         out=4'b0001;
         2'd1:
             if(in[2])                 out=4'b0100;
             else if(in[3])         out=4'b1000;
             else if(in[0])         out=4'b0001;
             else if(in[1])         out=4'b0010;
         2'd2:
             if(in[3])                 out=4'b1000;
             else if(in[0])         out=4'b0001;
             else if(in[1])         out=4'b0010;
             else if(in[2])         out=4'b0100;
         2'd3:
             if(in[0])                 out=4'b0001;
             else if(in[1])         out=4'b0010;
             else if(in[2])         out=4'b0100;
             else if(in[3])         out=4'b1000;
         default: out=4'b0000;
     endcase 
  end
 endmodule 
 
 
/******************************************************
*	my_one_hot_arbiter_priority_en
* 
******************************************************/
 
 
 
module my_one_hot_arbiter_priority_en #(
    parameter ARBITER_WIDTH    =4
 
 
)
(
    input        [ARBITER_WIDTH-1             :    0]    request,
    output    [ARBITER_WIDTH-1            :    0]    grant,
    output                                            any_grant,
    input                                                clk,
    input                                                reset,
    input                                                priority_en
);
 
    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 ARBITER_BIN_WIDTH= log2(ARBITER_WIDTH);
    reg     [ARBITER_BIN_WIDTH-1        :    0]     low_pr;
    wire     [ARBITER_BIN_WIDTH-1        :    0]     grant_bcd;
 
    one_hot_to_bin #(
        .ONE_HOT_WIDTH    (ARBITER_WIDTH)
    )conv 
    (
        .one_hot_code(grant),
        .bin_code(grant_bcd)
    );
 
    always @ (`pronoc_clk_reset_edge )begin 
        if(`pronoc_reset) begin
            low_pr    <=    {ARBITER_BIN_WIDTH{1'b0}};
        end else begin
            if(priority_en) low_pr <= grant_bcd;
        end
    end
 
 
    assign any_grant = | request;
 
    generate 
        if(ARBITER_WIDTH    ==2) begin :w2        arbiter_2_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
        if(ARBITER_WIDTH    ==3) begin :w3        arbiter_3_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
        if(ARBITER_WIDTH    ==4) begin :w4        arbiter_4_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
    endgenerate
 
endmodule   
 
 
 
/*******************
*
*    thermo_arbiter RRA
*
********************/
 
module thermo_gen #(
    parameter WIDTH=16
 
 
)(
    input  [WIDTH-1    :    0]in,
    output [WIDTH-1    :    0]out
);
    genvar i;
    generate
    for(i=0;i<WIDTH;i=i+1)begin :lp
        assign out[i]= | in[i    :0];    
    end
    endgenerate
 
endmodule
 
 
 
 
module thermo_arbiter #(
 parameter    ARBITER_WIDTH    =4
 
)
(    
   clk, 
   reset, 
   request, 
   grant,
   any_grant
);
 
 
 
 
    input        [ARBITER_WIDTH-1             :    0]    request;
    output    [ARBITER_WIDTH-1            :    0]    grant;
    output                                            any_grant;
    input                                                reset,clk;
 
 
    wire        [ARBITER_WIDTH-1             :    0]    termo1,termo2,mux_out,masked_request,edge_mask;
    reg        [ARBITER_WIDTH-1             :    0]    pr;
 
 
    thermo_gen #(
        .WIDTH(ARBITER_WIDTH)
    ) tm1
    (
        .in(request),
        .out(termo1)
    );
 
 
 
 
    thermo_gen #(
        .WIDTH(ARBITER_WIDTH)
    ) tm2
    (
        .in(masked_request),
        .out(termo2)
    );
 
 
    assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1;
    assign masked_request= request & pr;
    assign any_grant=termo1[ARBITER_WIDTH-1];
 
    always @ (`pronoc_clk_reset_edge )begin 
            if(`pronoc_reset) pr<= {ARBITER_WIDTH{1'b1}};
        else begin 
            if(any_grant) pr<= edge_mask;
        end
 
    end
 
    assign edge_mask= {mux_out[ARBITER_WIDTH-2:0],1'b0};
    assign grant= mux_out ^ edge_mask;
 
 
 
endmodule
 
 
 
 
 
module thermo_arbiter_priority_en #(
 parameter    ARBITER_WIDTH    =4
 
)
(    
   clk, 
   reset, 
   request, 
   grant,
   any_grant,
   priority_en
);
 
 
 
 
    input        [ARBITER_WIDTH-1             :    0]    request;
    output    [ARBITER_WIDTH-1            :    0]    grant;
    output                                            any_grant;
    input                                                reset,clk;
    input priority_en;
 
    wire        [ARBITER_WIDTH-1             :    0]    termo1,termo2,mux_out,masked_request,edge_mask;
    reg        [ARBITER_WIDTH-1             :    0]    pr;
 
 
    thermo_gen #(
        .WIDTH(ARBITER_WIDTH)
    ) tm1
    (
        .in(request),
        .out(termo1)
    );
 
 
 
 
    thermo_gen #(
        .WIDTH(ARBITER_WIDTH)
    ) tm2
    (
        .in(masked_request),
        .out(termo2)
    );
 
 
    assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1;
    assign masked_request= request & pr;
    assign any_grant=termo1[ARBITER_WIDTH-1];
 
    always @ (`pronoc_clk_reset_edge )begin 
            if(`pronoc_reset) pr<= {ARBITER_WIDTH{1'b1}};
        else begin 
            if(priority_en) pr<= edge_mask;
        end
 
    end
 
    assign edge_mask= {mux_out[ARBITER_WIDTH-2:0],1'b0};
    assign grant= mux_out ^ edge_mask;
 
 
 
endmodule
 
 
 
 
 
 
 
 
module thermo_arbiter_ext_priority #(
 parameter    ARBITER_WIDTH    =4
 
)
(    
 
   request, 
   grant,
   any_grant,
   priority_in
 
);
 
 
 
 
    input        [ARBITER_WIDTH-1             :    0]    request;
    output    [ARBITER_WIDTH-1            :    0]    grant;
    output                                            any_grant;
    input   [ARBITER_WIDTH-1            :   0]  priority_in;
 
    wire        [ARBITER_WIDTH-1             :    0]    termo1,termo2,mux_out,masked_request,edge_mask;
    wire        [ARBITER_WIDTH-1             :    0]    pr;
 
 
    thermo_gen #(
        .WIDTH(ARBITER_WIDTH)
    ) tm1
    (
        .in(request),
        .out(termo1)
    );
 
 
 
 
    thermo_gen #(
        .WIDTH(ARBITER_WIDTH)
    ) tm2
    (
        .in(masked_request),
        .out(termo2)
    );
 
 
    thermo_gen #(
        .WIDTH(ARBITER_WIDTH)
    ) tm3
    (
        .in(priority_in),
        .out(pr)
    );
 
 
assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1;
assign masked_request= request & pr;
assign any_grant=termo1[ARBITER_WIDTH-1];
 
 
assign edge_mask= {mux_out[ARBITER_WIDTH-2:0],1'b0};
assign grant= mux_out ^ edge_mask;
 
 
 
endmodule
 
 
 
/********************************
*    
*   Tree arbiter
* 
*******************************/
 
module tree_arbiter #(
        parameter    GROUP_NUM        =4,
        parameter    ARBITER_WIDTH    =16
)
(    
   clk, 
   reset, 
   request, 
   grant,
   any_grant
);
 
 
    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 N = ARBITER_WIDTH;
  localparam S = log2(ARBITER_WIDTH); // ceil of log_2 of N - put manually
 
 
  // I/O interface
  input           clk;
  input           reset;
  input  [N-1:0]  request;
  output [N-1:0]  grant;
  output          any_grant;
 
 
    localparam GROUP_WIDTH    =    ARBITER_WIDTH/GROUP_NUM;
 
  wire [GROUP_WIDTH-1        :    0]    group_req    [GROUP_NUM-1        :    0];
  wire [GROUP_WIDTH-1        :    0]    group_grant [GROUP_NUM-1        :    0];
  wire [GROUP_WIDTH-1        :    0]    grant_masked[GROUP_NUM-1        :    0];
 
  wire [GROUP_NUM-1            :    0] any_group_member_req;
  wire [GROUP_NUM-1            :    0] any_group_member_grant;
 
 
    genvar i;
    generate
    for (i=0;i<GROUP_NUM;i=i+1) begin :group_lp
 
        //seprate inputs in group
        assign group_req[i]    =    request[(i+1)*GROUP_WIDTH-1        :    i*GROUP_WIDTH];
 
        //check if any member of qrup has request
        assign any_group_member_req[i]    =    | group_req[i];
 
        //arbiterate one request from each group
        arbiter #(
            .ARBITER_WIDTH    (GROUP_WIDTH)
        )group_member_arbiter
        (    
            .clk            (clk), 
            .reset        (reset), 
            .request        (group_req[i]), 
            .grant        (group_grant[i]),
            .any_grant    ()
        );
 
    // mask the non selected groups        
        assign grant_masked [i] = (any_group_member_grant[i])?    group_grant[i]: {GROUP_WIDTH{1'b0}};
 
    //assemble the grants
        assign grant [(i+1)*GROUP_WIDTH-1        :    i*GROUP_WIDTH] = grant_masked [i];
 
 
    end
    endgenerate
 
    //select one group which has atleast one active request
 
    //arbiterate one request from each group
        arbiter #(
            .ARBITER_WIDTH    (GROUP_NUM)
        )second_arbiter
        (    
            .clk        (clk), 
            .reset        (reset), 
            .request    (any_group_member_req), 
            .grant        (any_group_member_grant),
            .any_grant    (any_grant)
        );
 
 
 
 endmodule 
 
 
 
 
 
 
/*******************************
 
    my_one_hot_arbiter_ext_priority
 
*******************************/
 
module my_one_hot_arbiter_ext_priority #(
    parameter ARBITER_WIDTH =4
 
 
)
(
    input   [ARBITER_WIDTH-1            :   0]  request,
    input   [ARBITER_WIDTH-1            :   0]  priority_in,
    output  [ARBITER_WIDTH-1            :   0]  grant,
    output                                      any_grant
);
 
    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 ARBITER_BIN_WIDTH= log2(ARBITER_WIDTH);
    wire    [ARBITER_BIN_WIDTH-1        :   0]  low_pr;
 
 
    wire [ARBITER_WIDTH-1            :   0] low_pr_one_hot = {priority_in[0],priority_in[ARBITER_BIN_WIDTH-1:1]};
 
    one_hot_to_bin #(
        .ONE_HOT_WIDTH    (ARBITER_WIDTH)
    )conv 
    (
        .one_hot_code(low_pr_one_hot),
        .bin_code(low_pr)
    );
 
 
    assign any_grant = | request;
 
    generate 
        if(ARBITER_WIDTH    ==2) begin: w2       arbiter_2_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
        if(ARBITER_WIDTH    ==3) begin: w3       arbiter_3_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
        if(ARBITER_WIDTH    ==4) begin: w4       arbiter_4_one_hot arb( .in(request) , .out(grant), .low_pr(low_pr)); end
    endgenerate
 
endmodule
 
 
/*********************************
*
*       arbiter_ext_priority
*
**********************************/
 
 
 module arbiter_ext_priority  #(
        parameter   ARBITER_WIDTH   =8
 
)
(   
 
   request, 
   grant,
   priority_in,
   any_grant
);
 
 
    input   [ARBITER_WIDTH-1            :   0]  request;
    input   [ARBITER_WIDTH-1            :   0]  priority_in;
    output  [ARBITER_WIDTH-1            :   0]  grant;
    output                                      any_grant;
 
   /*
    generate 
 
    if(ARBITER_WIDTH<=4) begin :ws4
        //my own arbiter 
        my_one_hot_arbiter_ext_priority #(
            .ARBITER_WIDTH  (ARBITER_WIDTH)
        )
        one_hot_arb
        (   
 
            .request    (request),
            .priority_in(priority_in), 
            .grant      (grant),
            .any_grant  (any_grant)
        );
 
    end else begin :wb4
    */
 
        thermo_arbiter_ext_priority #(
            .ARBITER_WIDTH  (ARBITER_WIDTH)
        )
        one_hot_arb
        (   
 
            .request    (request), 
            .priority_in(priority_in), 
            .grant      (grant),
            .any_grant   (any_grant)
        );
   // end
   // endgenerate
 
 
 
 
endmodule 
 
 
 
 
 
 
 
 
 
 
 module fixed_priority_arbiter #(
     parameter   ARBITER_WIDTH   =8,
     parameter   HIGH_PRORITY_BIT = "HSB"
 )
 (   
 
   request, 
   grant,
   any_grant
);
 
 
    input   [ARBITER_WIDTH-1            :   0]  request;
    output  [ARBITER_WIDTH-1            :   0]  grant;
    output                                      any_grant;
   /*
    wire    [ARBITER_WIDTH-1            :   0]  cout;
    reg     [ARBITER_WIDTH-1            :   0]  cin;
 
 
 
 
    assign grant    = cin & request;
    assign cout     = cin & ~request; 
 
     always @(*) begin 
        if( HIGH_PRORITY_BIT == "HSB")  cin      = {1'b1, cout[ARBITER_WIDTH-1 :1]}; // hsb has highest priority
        else                            cin      = {cout[ARBITER_WIDTH-2 :0] ,1'b1}; // lsb has highest priority
    end//always
 
    */
 
    assign  any_grant= | request;
    wire  [ARBITER_WIDTH-1            :   0] termo_code, edge_mask;
 
 
    genvar i;
    generate
    if( HIGH_PRORITY_BIT == "LSB") begin :hsb
        for(i=0;i<ARBITER_WIDTH;i=i+1)begin :lp
            assign termo_code[i]= | request[i    :0];    
        end
        assign edge_mask=  {termo_code[ARBITER_WIDTH-2:0],1'b0};
 
    end else begin :hsb
        for(i=0;i<ARBITER_WIDTH;i=i+1)begin :lp
            assign termo_code[i]= | request[ARBITER_WIDTH-1    :i];    
        end
        assign edge_mask=  {1'b0, termo_code[ARBITER_WIDTH-1:1]};
 
    end
    endgenerate
 
    assign grant= termo_code ^ edge_mask;
 
 
 
endmodule
 
 
 
 
 
 
 

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.