一个简单的总线轮询仲裁器Verilog代码
2012-06-02
标签: 总线仲裁

下面这个是以输入信号作为状态机的转移条件,写得比较冗余:

//

// 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’b00A获得总线

// grant[1:0]=2’b01B获得总线

// grant[1:0]=2’b10C获得总线

// 总线轮询算法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

inputclk_i;

inputen_i;

inputsig_a_i;

inputsig_b_i;

inputsig_c_i;

output[1:0] grant_o;

// register definition

reg[1:0] grant_o;

reg[1:0] ls;

// parameter definition

parameters_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’b00A获得总线

// grant[1:0]=2’b01B获得总线

// grant[1:0]=2’b10C获得总线

// 总线轮询算法:

// 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

inputclk_i;

inputen_i;

inputsig_a_i;

inputsig_b_i;

inputsig_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

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号