`timescale 1ns/1ps
module pid_tb;

	parameter CLK_PERIOD = 10;

	reg	                  clk;
	reg	                  nRst;
	reg   signed   [31:0]   target; 
	reg   signed   [31:0]   process;
   reg   signed   [31:0]   Kp;
   reg   signed   [31:0]   Ki;
   reg   signed   [31:0]   Kd;
   wire  signed   [31:0]   drive;


   integer           seed;
   reg      [31:0]   rand;
   reg      [31:0]   tune;

	pid pid(
		`ifdef POST_SYNTHESIS
		   
		`else
			.clk	   (clk     ),
			.nRst	   (nRst    ),
			.target	(target  ),
			.process	(process ),
			.Kp	   (Kp      ),
			.Ki	   (Ki      ),
			.Kd	   (Kd      ),
			.drive	(drive   )	
		`endif
	);

	initial begin
		while(1) begin
			#(CLK_PERIOD/2) clk = 0;
			#(CLK_PERIOD/2) clk = 1;
		end
	end

	initial begin
		`ifdef POST_SYNTHESIS
			$dumpfile("pid_syn.vcd");
			$dumpvars(0,pid_tb);
		`else
			$dumpfile("pid.vcd");
			$dumpvars(0,pid_tb);
		`endif
		$display("                  TIME    nRst");		$monitor("%tps       %d",$time,nRst);
	end

   task pidTest;
      input [31:0]   p;
      input [31:0]   i;
      input [31:0]   d;
      begin
         Kp = p;
         Ki = i;
         Kd = d;
         seed = $time;
         repeat(1000) begin
            #1    rand = $random(seed);
                  rand = rand >> 30;
                  process = (process/1.1) + (drive/100) + rand;
         end
      end
   endtask

	initial begin
      #500  nRst		= 1'b1;
      #500  nRst     = 1'b0;
      #500  nRst     = 1'b1;
            target   = 32'd10000; 
            
            // Sweep the I only
            tune   = 32'd0;
            repeat(21) begin
                        process = 32'd0;
               #1000    pidTest(tune,0,0);
                        tune = tune + 32'd1;
            end

            // Sweep I with P fixed
            tune   = 32'd0;
            repeat(10) begin
                        process = 32'd0;
               #1000    pidTest(32'd7,tune,0);
                        tune = tune + 32'd1;
            end


            $finish;
	end

endmodule