OpenCores
URL https://opencores.org/ocsvn/pid_controller/pid_controller/trunk

Subversion Repositories pid_controller

[/] [pid_controller/] [trunk/] [bench/] [PID_tb.v] - Rev 8

Go to most recent revision | Compare with Previous | Blame | View Log

/*PID controller testbench
Author: Zhu Xu
Email: m99a1@yahoo.cn
*/
 
 
module	PID_tb;
reg	clk=0;
reg	rst=1;
 
always #1 clk=~clk;
 
initial begin
	#10 rst=0;
end
 
//scoreboard
reg	[15:0]kp=0;
reg	[15:0]ki=0;
reg	[15:0]kd=0;
reg	[15:0]sp=0;
reg	[15:0]pv=0;
reg	[15:0]kpd;
reg	[15:0]err[0:1];
reg	[31:0]sigma=0;
reg	[31:0]un=0;
reg	[31:0]a=0;
reg	[31:0]p=0;
reg	[4:0]of=0;
reg	[31:0]s=0;
initial begin
	err[0]=0;
	err[1]=0;
end
 
wire	[31:0]value_sb[0:10];
assign	value_sb[0]={{16{kp[15]}},kp};
assign	value_sb[1]={{16{ki[15]}},ki};
assign	value_sb[2]={{16{kd[15]}},kd};
assign	value_sb[3]={{16{sp[15]}},sp};
assign	value_sb[4]={{16{pv[15]}},pv};
assign	value_sb[5]={{16{kpd[15]}},kpd};
assign	value_sb[6]={{16{err[0][15]}},err[0]};
assign	value_sb[7]={{16{err[1][15]}},err[1]};
assign	value_sb[8]=un;
assign	value_sb[9]=sigma;
assign	value_sb[10]={27'b0,of};
 
function of_check_16bit;
	input 	[15:0]a,b;
	begin
		s=a+b;
		of_check_16bit=(a[15]&b[15]&(~s[15]))|((~a[15])&(~b[15])&s[15]);
	end
endfunction
 
function of_check_32bit;
	input	[31:0]a,b;
	begin
		s=a+b;
		of_check_32bit=(a[31]&b[31]&(~s[31]))|((~a[31])&(~b[31])&s[31]);	
	end	
endfunction	
 
task	update_sb;
	input	[15:0]adr;
	input	[15:0]data;
	begin
		case(adr[15:2])
			0:begin
				kp=data;
				kpd=kp+kd;
				of[0]=of_check_16bit(kp,kd);
			end
			1:begin
				ki=data;
			end
			2:begin
				kd=data;
				kpd=kp+kd;
				of[0]=of_check_16bit(kp,kd);
			end
			3:begin
				sp=data;
			end
			4:begin
				pv=data;
				err[1]=(~err[0])+1;
				of[2]=of[1];
				err[0]=sp+(~pv)+1;
				of[1]=of_check_16bit(sp,((~pv)+1));
				p={{16{err[0][15]}},err[0]}*{{16{ki[15]}},ki};
				of[4]=of[4]|of_check_32bit(sigma,p);
				sigma=sigma+p;
				p={{16{err[0][15]}},err[0]}*{{16{kpd[15]}},kpd};
				of[3]=of[4]|of_check_32bit(sigma,p);
				a=sigma+p;
				p={{16{err[1][15]}},err[1]}*{{16{kd[15]}},kd};
				of[3]=of[3]|of_check_32bit(a,p);
				un=a+p;
			end						
		endcase
	end
endtask
 
//wishbone master
wire	[3:0]TAG_s2m;
wire	[3:0]TAG_m2s;
wire	ACK_s2m;
wire	[31:0]ADR_m2s;
wire	CYC_m2s;
wire	[31:0]DAT_s2m;
wire	[31:0]DAT_m2s;
wire	ERR_s2m,RTY_s2m,STB_m2s,WE_m2s;
wire	[3:0]SEL_m2s;
 
wb_master	wb_master_0(
clk,
rst,
TAG_s2m,
TAG_m2s,
ACK_s2m,
ADR_m2s,
CYC_m2s,
DAT_s2m,
DAT_m2s,
ERR_s2m,
RTY_s2m,
SEL_m2s,
STB_m2s,
WE_m2s
);
 
 
reg	[31:0]rdata;
task	check_sb;
	input	[31:0]adr;
	begin
		wb_master_0.rd(adr,rdata);
		if(adr<=10*4)begin
			if(rdata==value_sb[adr[15:2]])begin
				$display("%8dns	read correct value from address=%8h	data=%8h",$time,adr,rdata);
			end
			else begin
				$display("%8dns	read incorrect value from address=%8h	rdata=%8h	scoreboard=%8h",$time,adr,rdata,value_sb[adr[15:2]]);
			end
		end
		else begin
			if(rdata==0)begin
				$display("%8dns	read correct value from address=%8h	data=%8h",$time,adr,rdata);
			end
			else begin
				$display("%8dns	read incorrect value from address=%8h	rdata=%8h	scoreboard=0",$time,adr,rdata);
			end
		end
 
	end
endtask
 
 
 
//instantiation of PID
wire	[31:0]o_un;
wire	valid;
 
PID	PID_0(
clk,
rst,
CYC_m2s,
STB_m2s,
WE_m2s,
ADR_m2s[15:0],
DAT_m2s,
ACK_s2m,
DAT_s2m,
o_un,
valid
);
 
 
//test procedure
reg	signed[31:0]rdata_1=0;
initial begin
	while(rst)begin
		@(posedge clk);
	end
	wb_master_0.wr(0*4,32'h80,4'b1111);
	update_sb(0*4,16'h80);
	wb_master_0.wr(1*4,32'h5,4'b1111);
	update_sb(1*4,16'h5);
	wb_master_0.wr(2*4,32'h5,4'b1111);
	update_sb(2*4,16'h5);
	wb_master_0.wr(3*4,32'hf87,4'b1111);
	update_sb(3*4,16'hf87);
	wb_master_0.wr(4*4,32'h0,4'b1111);
	update_sb(4*4,0);
	repeat(1000)begin
		wb_master_0.rd(8*4,rdata_1);
		check_sb(8*4);
		rdata_1=rdata_1>>>8;
		wb_master_0.wr(4*4,rdata_1,4'b1111);
		update_sb(4*4,rdata_1[15:0]);
 
	end
	#10 $finish;
end
 
 
 
 
 
 
endmodule

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.