Verilog实现简单的总线轮训仲裁器

从小父亲就教育我,要做一个对社会有用的人! 

//下面这个是以输入信号作为状态机的转移条件,写得比较冗余:
//
// Verilog Module demo1_lib.bus_arbitor.arch_name
//
///
// 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.如果同时有多个信号请求,考虑上一个请求信号,(ab ba) (bc cb) (ac ca) (abc acb bca)
// 							如果上一个请求信号是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) begin
		if(!en_i) begin		// bus disable when negtive en_i
			grant_o 	<= 2'b11;
			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	;  	// A 
				end
				
				s_a:	begin			// deal with A 
					grant_o <= 2'b00;
					ls 		<= s_a;
				end
				
				s_b:	begin			// deal with B 
					grant_o <= 2'b01;
					ls 		<= s_b;
				end
				
				s_c:	begin			// deal with C 
					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)                                  6
					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)                                  7
					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
	end
endmodule

你可能感兴趣的:(汽车芯片IC验证,fpga开发)