循环仲裁

时间:2015-08-06 04:36:02

标签: verilog

我已经通过计数到3来编写代码,给每个请求4个时钟时间。这是运行代码

module arbiter(input clk,
        input rst_n,
        input wire [3:0] req,           // 4 requestor
        output reg [3:0] grant );       // 4 grant

reg [3:0] en ;                      // enable : priority token distributor
wire [3:0]en_d;                     // enable dummy
reg [1:0] count ;                   //for counting up to 3 everytime request is available 
wire [1:0] count_d;                 //count dummy

reg  temp;                      //differentiate between reset condition and normal clock edge               
wire [1:0] pos_one;                 // finding position of one in enable
//wire [3:0] grant_c;                   


always @( posedge clk, negedge rst_n )
begin
     if(!rst_n)
    begin
        en <= 4'b0000;
        count <= 2'b00;
        temp <= 1'b0;
        grant <= 4'd0 ;
    end
    else
    begin
        temp <= 1'b1;
        count <= count_d ;
        en <= en_d;
        //grant <= grant_c;
    end

end

// when reset load 1000 (msb priority) and when clock comes rotate or load the
// priority data as per the condition

assign en_d =(temp == 0)? 4'b1000 : ((count == 2'b11 | req[pos_one] == 0)? {en[0],en[3:1]} : en);

 //when reset assign 0 and increase count as soon as request data is available
 //on pos_one of enable
assign count_d = (temp == 0)? 2'd0 : ((req[pos_one] == 1)? count + 1 :2'b00 );

//find every time new position of one as enable becomes available
assign pos_one = (en[0] == 1)? 2'd0 : (en[1] == 1)? 2'd1 : (en[2] == 1)? 2'd2 : 2'd3 ;   

//if request available on pos_one assign enable data else if no request assign 0
always @(en)
begin
    grant <= (req[pos_one] == 1)? en  : 4'b0000;
end

endmodule

但是,如果优先级是第3个(msb)请求者位且请求不可用且请求在第一个请求者(请求:0010)(优先级:1000),那么它需要另外两个时钟周期来给予授权。所以在那里任何方法来克服这种延迟?还有什么是req [pos_one]的合成?它会是多路复用器吗?

1 个答案:

答案 0 :(得分:0)

您可以在组合逻辑块中使用for循环来计算下一个时钟周期的grant的索引和值。 for循环必须能够静态展开才能合成。

以下代码是计算值的框架。我省略了一些计算方法,以及它们取决于您的设计要求。

always @* begin // comb logic
  if (/* condition */) begin
    // keep previous
    next_grant = grant;
    next_index = index; // 'index' is the position of the last know granted request
  end
  else begin
    // determine next
    next_grant = 'b0;
    next_index = ... ; // initial priority
    for (i=0; i<4; i=i+1) begin
      if (next_grant=='b0) begin // prevent updates once grant is decided
        if (req[next_index]) begin
          // Set next_grant
        end
        else begin
          // set next_index to next priority
        end
      end
    end
  end
end

always @(posedge clk, negedge rst_n) begin
  if (!rst_n) begin
    grant <= 'b0;
    index <= 'b0;
  end
  else begin
    grant <= next_grant;
    index <= next_index;
  end
end