一些輪詢仲裁器方案的SystemVerilog 代碼
掃描二維碼
隨時隨地手機看文章
前文介紹了一個固定優(yōu)先級arbiter的可綜合SysyemVerilog代碼,你一定注意到了該設(shè)計的一個最大缺點。存在靜態(tài)優(yōu)先級意味著,在某些情況下,低優(yōu)先級的模塊可能永遠無法得到服務(wù)。這被稱為餓死,在某些設(shè)計中可能沒問題,但在某些設(shè)計中,我們可能需要避免這種情況。
在下面的這篇文章中介紹了很多種輪詢仲裁方案。
「數(shù)字芯片設(shè)計【不定期更新文件】」
鏈接:https://pan.quark.cn/s/27331927a18e
避免它的一種方法是輪詢優(yōu)先級。一旦請求模塊得到服務(wù),下一個模塊將獲得最高優(yōu)先級,以循環(huán)方式進行優(yōu)先級的調(diào)整。這就是為什么這個仲裁器被稱為Round Robin輪詢仲裁器,它用于避免設(shè)計中的餓死。
某個模塊的請求必須等待的最大時間取決于此設(shè)計中的請求者數(shù)量。
always_comb begin case (pointer_reg) 2'b00 : if (req[0]) grant = 4'b0001; else if (req[1]) grant = 4'b0010; else if (req[2]) grant = 4'b0100; else if (req[3]) grant = 4'b1000; else grant = 4'b0000; 2'b01 : if (req[1]) grant = 4'b0010; else if (req[2]) grant = 4'b0100; else if (req[3]) grant = 4'b1000; else if (req[0]) grant = 4'b0001; else grant = 4'b0000; 2'b10 : if (req[2]) grant = 4'b0100; else if (req[3]) grant = 4'b1000; else if (req[0]) grant = 4'b0001; else if (req[1]) grant = 4'b0010; else grant = 4'b0000; 2'b11 : if (req[3]) grant = 4'b1000; else if (req[0]) grant = 4'b0001; else if (req[1]) grant = 4'b0010; else if (req[2]) grant = 4'b0100; else grant = 4'b0000; endcase // case(req) end
此代碼適用于具有4位請求的RR仲裁。優(yōu)先級根據(jù)變量pointer_reg進行輪換,每當請求者獲得服務(wù)時,pointer_reg都會發(fā)生變化。例如,如果模塊0被服務(wù),那么最高優(yōu)先級將是模塊1。當模塊1被服務(wù)時,模塊2將獲得最高優(yōu)先級。
我們可以寫出計算pointer_reg值的邏輯,如下所示:
logic [1:0] pointer_req, next_pointer_req; always @(posedge clock) begin if (reset) pointer_req <= '0; else pointer_req <= next_pointer_req; end always_comb begin assign next_pointer_req = 2'b00; casez (gnt) 4'b0001: next_pointer_req = 2'b01; 4'b0010: next_pointer_req = 2'b10; 4'b0100: next_pointer_req = 2'b11; 4'b1000: next_pointer_req = 2'b00; endcase end
就像固定優(yōu)先級仲裁一樣,這種設(shè)計是不可擴展的。輸入請求數(shù)量較多的代碼編寫起來很繁瑣,而且容易出錯。下面介紹其他可擴展且易于參數(shù)化的設(shè)計。
The Rotate + Priority + Rotate Design
以“Rotate + Priority + Rotate”的設(shè)計為例。它使用固定優(yōu)先級仲裁器,并向右或向左移動輸入,以模仿優(yōu)先級的旋轉(zhuǎn)。假設(shè)4'b1011是第一個輸入,這次沒有移位,因為這是第一個輸入。假設(shè)LSB具有最高優(yōu)先級,當我們將其發(fā)送給固定優(yōu)先級仲裁器時,此輸入的輸出將為4'b0001。假設(shè)下一個輸入是4'b0011。通常,這種情況的輸出也是4'b0001,但在RR仲裁的情況下不是。由于這是第二個輸入,我們將其移動1,因此對固定優(yōu)先級仲裁器的輸入現(xiàn)在變?yōu)?'b1001,輸出也變?yōu)?'b0001。但這不是我們的最終輸出,因為在計算輸出grant信號之前,我們將輸入“向左右”移動了1,現(xiàn)在我們必須將其“向左”旋轉(zhuǎn)1才能獲得最終輸出,這樣輸出現(xiàn)在變成4'b0010。這是一個簡單但有效的設(shè)計。決定左右旋轉(zhuǎn)的指針邏輯可以很容易地以我之前提到的方式編碼。這種設(shè)計速度不是很快,因為需要大量的操作來生成grant輸出,但綜合時需要非常小的面積。
The MUXed parallel priority arbiters
從圖表中可以看出,這個設(shè)計相當大。該設(shè)計還是使用固定優(yōu)先級仲裁器,每個輸入請求都有一個固定優(yōu)先級仲裁器。隨著輸入請求者數(shù)量的增加,它只會越來越大。但好的方面是,它非常快。由于所有優(yōu)先級仲裁器的輸出grant已經(jīng)計算好了,我們只是從中選擇一個輸出。讓我們嘗試為4位輸入請求總線編寫此設(shè)計代碼。
module muxed_rr_arb( input logic clock, reset, input logic [3:0] req, output logic [3:0] gnt ); logic [3:0] mux_ip0, mux_ip1, mux_ip2, mux_ip3; //Instantiate fixed priority arbiter and calculate the grant output for shifted priorities fixed_pri_arbiter inst0 (.req(req), .gnt(mux_ip0)); fixed_pri_arbiter inst1 (.req(req>>1), .gnt(mux_ip1)); fixed_pri_arbiter inst2 (.req(req>>2), .gnt(mux_ip2)); fixed_pri_arbiter inst3 (.req(req>>3), .gnt(mux_ip3)); //Select line pointer calculation logic [1:0] pointer_req, next_pointer_req; always @(posedge clock) begin if (reset) pointer_req <= '0; else pointer_req <= next_pointer_req; end always_comb begin assign next_pointer_req = 2'b00; casez (gnt) 4'b0001: next_pointer_req = 2'b01; 4'b0010: next_pointer_req = 2'b10; 4'b0100: next_pointer_req = 2'b11; 4'b1000: next_pointer_req = 2'b00; endcase end //Final output always_comb begin case (pointer_req) 2'b00: gnt = mux_ip0; 2'b01: gnt = mux_ip1; 2'b10: gnt = mux_ip2; 2'b11: gnt = mux_ip3; endcase end endmodule
您可以使用generate for循環(huán)來實例化固定優(yōu)先級仲裁器,輕松地對此設(shè)計進行參數(shù)化。
Two Simple Priority Arbiters with a Mask
此設(shè)計使用兩個固定的優(yōu)先級仲裁。一個用于計算請求輸入的grant輸出,另一個用于計算帶有屏蔽請求輸入的grant輸出。屏蔽請求是通過使用mask變量對輸入請求進行AND來計算的,每次請求服務(wù)時,其值都會發(fā)生變化。mask邏輯如下所示:
always@(/*AUTOSENSE*/pointer_reg) begin case (pointer_reg) // synopsys full_case parallel_case 2'b00: req_mask <= 4'b1111; 2'b01: req_mask <= 4'b1110; 2'b10: req_mask <= 4'b1100; 2'b11: req_mask <= 4'b1000; endcase end
這是一個非常有效的解決方案,在論文中提到的所有設(shè)計中,它提供了最佳性能。
Weighted RR Arbiter
這也是一個輪詢仲裁,但有一點變化。例如,讓我們假設(shè)請求者0的權(quán)重值為3,請求者1的權(quán)重值為2。如果在第一個周期中,輸入為4'b0011,請求者0將被服務(wù)?,F(xiàn)在請求者0已服務(wù),其權(quán)重減少到2。請求者1的權(quán)重值仍然為2。假設(shè)輸入在第二個周期中是相同的,即4'b0011。理想情況下,這次請求者1應(yīng)該根據(jù)循環(huán)計劃獲得服務(wù),但由于請求者0和1的權(quán)重相同,我們假設(shè)LSB具有最高的優(yōu)先級,請求者0將再次獲得服務(wù),其權(quán)重將減少到1?,F(xiàn)在,如果我們在第三個周期中看到相同的輸入,請求者1的權(quán)重值更大,因此請求者1這次將得到服務(wù)。





