vivadoでの簡単testbenchテストコードの作成-ZYNQ 7021学習


まずテストコードの役割を理解することが重要です.テストコードとは、コードシミュレーションによってテスト環境を生成し、自分で作成したモジュールコードが正しいかどうかをテストすることです.これは、コードを記述する過程で、テスト信号を生成する制御信号を制御するための制御信号など、いくつかの制御信号がどのように生成されるかを決定することを指導することができ、1つのinitialモジュールでこの値を変更することができ、テスト信号の制御信号は、クロックの下で生成されるべきである.
1、テストコードモジュールをsim_と命名するcrc_to_ramは、入力信号を必要としません.
module sim_crc_to_ram;

2、変数タイプを定義するには、一般的に入力信号をregタイプと定義する.出力信号をwireタイプとして定義する.
	reg 	     clk_60M;
	reg 	     reset;
	reg 	     flag_din;
	reg 	     din;
	wire        clk_5k;
	wire        data_sys, data_inter;

3.モジュールを例示し、入出力信号と2で定義された変数を関連付ける.
crc_to_ram  uut (
                    .clk_60M(clk_60M),
                    .reset(reset),
                    .start(flag_din),
                    .din(din),
                    
                    .clk_5k(clk_5k),
                    .data_sys(data_sys),
                    .data_inter(data_inter)
               );

4、クロックモジュールを生成する.必要に応じて1つ以上のクロックを生成します.一般に1つのシステムクロックを生成すればよく、他のクロックはこのクロック分周によって生成すればよい.次のコードは、遅延8 ns以降のclk_を示します.60 M信号は逆、すなわち周期16 nsの方波信号をとる.
always #8 clk_60M = ~clk_60M; 

5、クロック制御とreset信号の制御は一般的にinitialモジュールに置かれ、具体的な必要に応じてreset信号を編集する.クロック信号の初期化に注意してください.そうしないと、正常なクロック信号は生成されません(初期化しないとclkはデフォルトでx状態になり、~x状態がxのままで、クロック駆動は発生しません).
    reg	    data_ready;
    integer counti;                
    
    initial begin
            // Initialize Inputs
            clk_60M = 0;
            reset = 0;
            flag_din = 0;
            din = 0;
            
            counti = 0;
            $readmemb("C:/src.txt", mem);
            // Wait 100 ns for global reset to finish
            data_ready = 0;
            #100;
            reset = 1;
            #100;  
            data_ready = 1;  
            // Add stimulus here        
//          #(1600 * 10 * 1000);        // 4 frame 100k
            #(1600 * 1 * 1000);            // 4 frame 1M
//           #(400 * 1000);                // 1 frame 1MHz
            data_ready = 0;
        end 

6、ファイルの初期化操作
基本的なファイル操作には読み取りと書き込みが含まれています.以下は入力信号を生成するコードに他のマーク信号が付いていて、少し煩雑で、自分で書くときにforサイクルを採用すればいいです.
parameter 	        read_idle 	= 2'b00,
			read_begin	= 2'b01,
			read_end 	= 2'b10;

reg	[1 : 0]	state_read;
always@(posedge clk_5k or negedge reset)
begin
	if(!reset)
		state_read	<= read_idle;
	else
	begin
		case (state_read)
			read_idle:
			begin
				if(data_ready == 1'b1)
				begin
					counti		<= 0;
					state_read 	<= read_begin;		
				end
				else
					state_read 	<= read_idle;
			end
			
			read_begin:
			begin
				if (counti <= 1023)		// 1 frames
				begin
					din			<= mem[counti];
					counti		<= counti + 1;
					state_read 	<= read_begin; 
					
					if ((counti == 0) || (counti == 1024) || (counti == 2048) || (counti == 3072))	
						flag_din<= 1'b1;
					else
						flag_din<= 1'b0;
				end	
				else
					state_read	<= read_end;
			end
			
			read_end:
			begin
				state_read	<= read_idle;
		    end
				
			default: 
			begin
				state_read 	<= read_idle;	
			end
		endcase 
	end
end	

書き込み操作にはファイルハンドルが必要です.また、シミュレーションが終了する前にファイル操作を閉じることに注意してください.デフォルトのパスは.sim\sim_1behav(後は.simsim_1impltimingに倣う).
integer fid;
fid = $fopen("resut.txt");
.........
$fclose(fid);

7、制御信号と出力結果のプログラミングは、具体的な例に従って制御信号をプログラミングし、その出力結果を収集し、複数のinitialモジュールに分けて行う.強いタイミング観念を形成し、各initialモジュール構造をできるだけ単一にするには、alwaysブロックでクロックclkに従ってテキストファイルにデータを書き込むこともできます.一般的にファイル書き込み操作を呼び出してシミュレーション結果を保存し、fidはファイルオペレータであり、直接次の文を使用して出力を完了すればよい.
......
$fdisplay(fid,"%b",data_out);
......

8、testbenchプログラムの実行を終了するには$stopまたは$finishでプログラムの実行を終了し、別のinitialを開始する.たとえば
  initial
        begin
             #(1000000*CYCLE);
             $ stop;
        end