一個簡單的匯流排輪詢仲裁器Verilog代碼

admin @ 2014-03-26 , reply:0

下面這個是以輸入信號作為狀態機的轉移條件,寫得比較冗餘:
//
// Verilog Module demo1_lib.bus_arbitor.arch_name
//
// Created:
//          by - Newhand
//          in - Shanghai ZhangJiang
//          at - 20:39:41 2003-12-03
// using Mentor Graphics HDL Designer(TM)
//
///////////////////////////////////////////////////////////
// Discription:
// Bus Polling Arbitor (BPA)
// 匯流排上掛3個信號A,B,C,仲裁信號grant[1:0]。
// grant[1:0]=2’b00   A獲得匯流排
// grant[1:0]=2’b01   B獲得匯流排
// grant[1:0]=2’b10   C獲得匯流排
// 匯流排輪詢演算法a.如果當前只有一個信號請求,則處理.
// b.如果沒有請求,那麼A獲得匯流排.
// c.如果同時有多個信號請求,考慮上一個請求信號,
// 如果上一個請求信號是A,那麼輪詢的是BCA,
// 如果上一個請求信號是B,那麼輪詢的是CAB,
// 如果上一個請求信號是C,那麼輪詢的是ABC
//////////////////////////////////////////////////////////

`resetall
`timescale 1ns/10ps
module bus_arbitor(clk_i, en_i, sig_a_i, sig_b_i, sig_c_i, grant_o);

// I/O definition
input      clk_i;
input      en_i;
input      sig_a_i;
input      sig_b_i;
input      sig_c_i;
output   [1:0] grant_o;

// register definition
reg   [1:0] grant_o;
reg  [1:0] ls;

// parameter definition
parameter   s_null = 'd0,
           s_a    = 'd1,
           s_b    = 'd2,
           s_c    = 'd3,
           s_ab   = 'd4,
           s_bc   = 'd5,
           s_ac   = 'd6,
           s_abc  = 'd7;

//module part and FSM
always @(posedge clk_i or negedge en_i)
if(!en_i)// bus disable when negtive en_i
begin
grant_o <= 2'b11;
//cs <= s_null;
ls <= s_null;
end
else
begin
case({sig_a_i, sig_b_i, sig_c_i})// bus enable with FSM
  s_null:
     begin
        grant_o <= 2'b00;
        ls <= s_a;
     end
  s_a:
     begin
        grant_o <= 2'b00;
        ls <= s_a;
     end
  s_b:
     begin
        grant_o <= 2'b01;
        ls <= s_b;
     end
  s_c:
     begin
        grant_o <= 2'b10;
        ls <= s_c;
     end
  s_ab:
     case(ls)// feedback MUX configured
        s_a: begin grant_o <= 2'b01; ls <= s_b; end
        s_b: begin grant_o <= 2'b00; ls <= s_a; end
        s_c: begin grant_o <= 2'b00; ls <= s_a; end
     endcase
  s_bc:
     case(ls)
        s_a: begin grant_o <= 2'b01; ls <= s_b; end
        s_b: begin grant_o <= 2'b10; ls <= s_c; end
        s_c: begin grant_o <= 2'b01; ls <= s_b; end
     endcase
  s_ac:
     case(ls)
        s_a: begin grant_o <= 2'b10; ls <= s_c; end
        s_b: begin grant_o <= 2'b10; ls <= s_c; end
        s_c: begin grant_o <= 2'b00; ls <= s_a; end
     endcase
  s_abc:
     case(ls)
        s_a: begin grant_o <= 2'b01; ls <= s_b; end
        s_b: begin grant_o <= 2'b10; ls <= s_c; end
        s_c: begin grant_o <= 2'b00; ls <= s_a; end
     endcase
  default:
  begin grant_o <= 2'b00; ls <= s_a; end
           
endcase
end
endmodule
下面這個是根據輸出信號來作為狀態機的轉移條件的,綜合后發現面積更小,但由於沒驗證,懷疑后模擬可能會出現毛刺。

//
// Verilog Module demo1_lib.bus_arbitor.arch_name
//
// Created:
//          by - Newhand
//          in - Shanghai
//          at - 20:39:41 2003-12-03
// using Mentor Graphics HDL Designer(TM)
//
///////////////////////////////////////////////////////////
// Discription:
// Bus Polling Arbitor (BPA)
// 匯流排上掛3個信號A,B,C,仲裁信號grant[1:0]。
// grant[1:0]=2’b00   A獲得匯流排
// grant[1:0]=2’b01   B獲得匯流排
// grant[1:0]=2’b10   C獲得匯流排
// 匯流排輪詢演算法:
// a.如果當前只有一個信號請求,則處理.
// b.如果沒有請求,那麼A獲得匯流排.
// c.如果同時有多個信號請求,考慮上一個請求信號,
// 如果上一個請求信號是A,那麼輪詢的是BCA,
// 如果上一個請求信號是B,那麼輪詢的是CAB,
// 如果上一個請求信號是C,那麼輪詢的是ABC.
//////////////////////////////////////////////////////////

`resetall
`timescale 1ns/10ps
module bus_arbitor1(clk_i, en_i, sig_a_i, sig_b_i, sig_c_i, grant_o);

// I/O definition
input      clk_i;
input      en_i;
input      sig_a_i;
input      sig_b_i;
input      sig_c_i;
output   [1:0] grant_o;

// register definition
reg[1:0] grant_o;

// wire definition
wire[2:0] sig_abc = {sig_c_i, sig_b_i, sig_a_i};

//module part
always @(posedge clk_i or negedge en_i)
if(!en_i)
grant_o <= 2'b11;
else
begin
grant_o <= 2'b00;
case(grant_o)
2'b00: //a
case(sig_abc)
3'b000: grant_o <= 2'b00;
3'b001: grant_o <= 2'b00;
3'b010: grant_o <= 2'b01;
3'b100: grant_o <= 2'b10;
3'b011: grant_o <= 2'b01;
3'b101: grant_o <= 2'b10;
3'b110: grant_o <= 2'b01;
3'b111: grant_o <= 2'b01;
default: grant_o <= 2'b00;
endcase
2'b01: //b
case(sig_abc)
3'b000: grant_o <= 2'b00;
3'b001: grant_o <= 2'b00;
3'b010: grant_o <= 2'b01;
3'b100: grant_o <= 2'b10;
3'b011: grant_o <= 2'b00;
3'b101: grant_o <= 2'b10;
3'b110: grant_o <= 2'b10;
3'b111: grant_o <= 2'b10;
default: grant_o <= 2'b01;
endcase
2'b10: //c
case(sig_abc)
3'b000: grant_o <= 2'b00;
3'b001: grant_o <= 2'b00;
3'b010: grant_o <= 2'b01;
3'b100: grant_o <= 2'b10;
3'b011: grant_o <= 2'b00;
3'b101: grant_o <= 2'b00;
3'b110: grant_o <= 2'b01;
3'b111: grant_o <= 2'b00;
default: grant_o <= 2'b10;
endcase
default:
grant_o <= 2'b00;
endcase
end

endmodule





[admin via 研發互助社區 ] 一個簡單的匯流排輪詢仲裁器Verilog代碼已經有1454次圍觀

http://cocdig.com/docs/show-post-43472.html