下面这个是以输入信号作为状态机的转移条件,写得比较冗余:
//
// 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 |