计算平均数

思路:

先载入数据到4个寄存器,再逐个累加,累加后载入数据到除法器中进行除法运算。

1、计算平均数模块

`timescale 1ns/1ps


module Ave(Clk,Rst_n,s,Data,ER,w0,w1,Done,R,Q);

parameter n = 8;
input Clk,Rst_n,s,ER,w0,w1;
input [n-1:0] Data;
output [n-1:0] R,Q;
output Done;
reg [7:0] data0,data1,data2,data3;
reg y0,y1,y2,y3;

wire LC ,EC,Ssel,ES;
reg [n-1:0] sum;
wire S_d,LA,EB;
wire div_done;
reg [1:0] cnt;

parameter S1=3'b000,S2=3'b001,S3=3'b010,S4=3'b011,S5=3'b100;
reg [2:0] state,next_state;

always@(*) begin
if(ER)
case({w1,w0})
	2'b00:{y0,y1,y2,y3} = 4'b1000;
	2'b01:{y0,y1,y2,y3} = 4'b0100;
	2'b10:{y0,y1,y2,y3} = 4'b0010;
	2'b11:{y0,y1,y2,y3} = 4'b0001;
	default:{y0,y1,y2,y3} = 4'b0000;
endcase
else
	{y0,y1,y2,y3} = 4'b0000;
end


always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
	data0 <= 0;
else if(y0)	
	data0 <= Data;
end

always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
	data1 <= 0;
else if(y1)	
	data1 <= Data;
end


always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
	data2 <= 0;
else if(y2)	
	data2 <= Data;
end


always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
	data3 <= 0;
else if(y3)	
	data3 <= Data;
end

always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
	cnt <= 2'd3;
else if(LC)
	cnt <= 2'd3;
else if (EC)
	cnt <= cnt - 1'b1;
end

always@(posedge Clk or negedge Rst_n) begin
if(~Rst_n) 
	sum <= 0;
else if(ES)
	if(Ssel) 
	case(cnt)
		2'b00:sum <= sum + data0;
		2'b01:sum <= sum + data1;
		2'b10:sum <= sum + data2;
		2'b11:sum <= sum + data3;
	default:;
	endcase
	else 
		sum <=0;
else
	sum <= 0;
end

always@(*) begin
case(state)
	S1:
		if(s) next_state =S2;
	S2:
		if(~|cnt) next_state =S3;
	S3:
		next_state = S4;
	S4:
		next_state = div_done?S5:S4;
	S5:
		next_state=s?S5:S1;
default: next_state =  S1;
endcase
end

always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
	state <= S1;
else
	state <= next_state; 

end

Div div0(.Clk(Clk),.Rst_n(Rst_n),.s(S_d),.DataA(sum),.DataB(8'd4),.LA(LA),.EB(EB),.R(R),.Q(Q),.Done(div_done));

assign Done = state==S5;
assign Ssel = state==S2;
assign ES = state==S2;
assign LC = state==S1&s;
assign EC = state==S2;
assign S_d = state==S4;
assign LA = state==S3;
assign EB = state==S3;



endmodule

2、测试代码

`timescale 1ns/1ps
`define clk_period 20

module tb_Div();

reg clk,rst_n,s,la;
reg [7:0] a;
reg [1:0] c;
//#wire [15:0] p;
wire done;

wire [7:0] q,r;

Ave adiv0(.Clk(clk),.Rst_n(rst_n),.Data(a),.ER(la),.s(s),.Q(q),.R(r),.Done(done),.w1(c[1]),.w0(c[0]));

initial clk = 1'b1;
always #(`clk_period /2) clk = ~clk;

initial begin 
rst_n = 0 ; la=0;
s = 0 ;
a = 8'd0; 
# (5*`clk_period/2) rst_n =1; 

# 20;a=8'd20;la=1;c=2'b00;
# 20;a=8'd21;c=2'b01;
# 20;a=8'd22;c=2'b10;
# 20;a=8'd25;c=2'b11;
# 20 ;la=0;s=1;
#(20*`clk_period);
s=0;
#200;


# 20; a=8'd00;la=1;c=2'b00;
# 20; a=8'd01;c=2'b01;
# 20; a=8'd22;c=2'b10;
# 20; a=8'd25;c=2'b11;
# 20 ;la=0;s=1;
#(20*`clk_period);
s=0;


# 20;a=8'd00;la=1;c=2'b00;
# 20;a=8'd01;c=2'b01;
# 20;a=8'd02;c=2'b10;
# 20;a=8'd01;c=2'b11;
# 20 ;la=0;s=1;
#(20*`clk_period);
s=0;


# 20;a=8'd20;la=1;c=2'b00;
# 20;a=8'd121;c=2'b01;
# 20;a=8'd22;c=2'b10;
# 20;a=8'd26;c=2'b11;
# 20 ;la=0;s=1;
#(20*`clk_period);
s=0;



end


initial
begin
  $fsdbDumpfile("avediv.fsdb");
  $fsdbDumpvars;
  $fsdbDumpon;
end

initial #5000 $finish;

endmodule

你可能感兴趣的:(fpga开发)