技術コラム

CRCモジュール(Verilog-HDL) テストベンチ

作成者:mou-mou

以前、弊社で作成したVerilog-HDLのCRCモジュールのテストベンチを公開致します。
簡単に数種類のテストを行っているだけで、網羅的なテストを目的としておりません。インタフェースや使い方の確認などにご利用いただければと思います。

【crc_tf.v】


//% @file
//% @brief crc_tf

//% CRC演算テストベンチ

module crc_tf;

	parameter CLK_CYCLE = 10000;	// 100MHz

//	parameter CRC_WIDTH = 7;	// CRCデータ幅
	parameter CRC_WIDTH = 16;	// CRCデータ幅
//	parameter CRC_WIDTH = 64;	// CRCデータ幅

	// CRC初期値 ALL 0
	parameter [CRC_WIDTH-1:0] SEED_VAL = {CRC_WIDTH{1'b0}};	
	// CRC初期値 ALL 1
//	parameter [CRC_WIDTH-1:0] SEED_VAL = {CRC_WIDTH{1'b1}};

	parameter DATA_WIDTH = 8;	// データ幅
//	parameter DATA_WIDTH = 2;	// データ幅
//	parameter DATA_WIDTH = 1;	// データ幅

	// 出力反転無し
	parameter OUTPUT_EXOR = {CRC_WIDTH{1'b0}};
	// 出力反転有り	
//	parameter OUTPUT_EXOR = {CRC_WIDTH{1'b1}};

	parameter [CRC_WIDTH-1:0] POLYNOMIAL =	
		(CRC_WIDTH == 7)?  7'h09 :   	// CRC7 X^7+X^3+1
		(CRC_WIDTH == 16)? 16'h1021 :	// CCITT CRC16 X^16+X^12+X^5+1
//		(CRC_WIDTH == 16)? 16'h8005 :	// CRC16 X^16+X^15+X^2+1
		(CRC_WIDTH == 64)? 64'h42F0E1EBA9EA3693 : // CRC64(ECMA-182)
		'h0;

	// Inputs
	reg CLK;
	reg RESET_N;
	reg IN_CLR;
	reg IN_ENA;
	reg [DATA_WIDTH-1:0] IN_DATA;

	// Outputs
	wire [CRC_WIDTH-1:0] OUT_CRC;

	// Instantiate the Unit Under Test (UUT)
	crc # (
		.DATA_WIDTH(DATA_WIDTH),
		.CRC_WIDTH(CRC_WIDTH),
		.POLYNOMIAL(POLYNOMIAL),
		.SEED_VAL(SEED_VAL),
		.OUTPUT_EXOR(OUTPUT_EXOR)
	) uut (
		.CLK(CLK), 
		.RESET_N(RESET_N), 
		.IN_CLR(IN_CLR), 
		.IN_ENA(IN_ENA), 
		.IN_DATA(IN_DATA), 
		.OUT_CRC(OUT_CRC)
	);

	initial begin
		CLK = 1'b1;		#(CLK_CYCLE / 2);
		forever begin
			CLK = ~CLK;	#(CLK_CYCLE / 2);
		end
	end

	task task_wait;
		input integer wait_time;
		begin
			repeat(wait_time)	@(posedge CLK);
		end
	endtask

	task task_crc7_1byte_test;
		input [7:0] data0;
		input [7:0] data1;
		input [7:0] data2;
		input [7:0] data3;
		input [7:0] data4;
		input integer wait_time;
		input [6:0] crc;
		begin
			@(posedge CLK);
			IN_CLR = 1;
     			task_wait(1);
			IN_CLR = 0;
   			task_wait(wait_time);
			IN_ENA = 1'b1;
			IN_DATA = data0;
			task_wait(1);
			IN_DATA = data1;
			task_wait(1);
			IN_DATA = data2;
			task_wait(1);
			IN_DATA = data3;
			task_wait(1);
			IN_DATA = data4;
			task_wait(1);
			IN_ENA = 1'b0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			IN_DATA = {crc, 1'b0};
 			task_wait(1);
			IN_DATA = 8'h00;
			IN_ENA = 1'b0;
		end
	endtask

	task task_8bit_serial;
		input [7:0] data;
		integer i;
		begin
			for (i = 0; i < 8; i = i + 1) begin
				IN_DATA = data[7-i];
				task_wait(1);
			end
		end
	endtask

	task task_4x2bit_serial;
		input [7:0] data;
		integer i;
		begin
			for (i = 0; i < 4; i = i + 1) begin
				IN_DATA[0] = data[7-i*2-1];
				IN_DATA[1] = data[7-i*2];
				task_wait(1);
			end
		end
	endtask

	task task_7bit_serial;
		input [6:0] data;
		integer i;
		begin
			for (i = 0; i < 7; i = i + 1) begin
				IN_DATA = data[6-i];
				task_wait(1);
			end
		end
	endtask

	task task_crc7_1bit_test;
		input [7:0] data0;
		input [7:0] data1;
		input [7:0] data2;
		input [7:0] data3;
		input [7:0] data4;
		input integer wait_time;
		input [6:0] crc;
		begin
			IN_CLR = 1;
			task_wait(1);
			IN_CLR = 0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			task_8bit_serial(data0);
			task_8bit_serial(data1);
			task_8bit_serial(data2);
			task_8bit_serial(data3);
			task_8bit_serial(data4);
			IN_ENA = 1'b0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			task_7bit_serial(crc);
			IN_DATA = 1'b0;
			IN_ENA = 1'b0;
		end
	endtask

	task task_crc16_test;
		input [7:0] data0;
		input [7:0] data1;
		input [7:0] data2;
		input [7:0] data3;
		input integer wait_time;
		input [15:0] crc;
		begin
			IN_CLR = 1;
			task_wait(1);
			IN_CLR = 0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			IN_DATA = data0;
			task_wait(1);
			IN_DATA = data1;
			task_wait(1);
			IN_DATA = data2;
			task_wait(1);
			IN_DATA = data3;
			task_wait(1);
			IN_ENA = 1'b0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			IN_DATA = crc[15:8];
			task_wait(1);
			IN_DATA = crc[7:0];
			task_wait(1);
			IN_DATA = 8'h00;
			IN_ENA = 1'b0;
		end
	endtask

	task task_crc16_2bit_test;
		input [7:0] data0;
		input [7:0] data1;
		input [7:0] data2;
		input [7:0] data3;
		input integer wait_time;
		input [15:0] crc;
		begin
			IN_CLR = 1;
			task_wait(1);
			IN_CLR = 0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			task_4x2bit_serial(data0);
			task_4x2bit_serial(data1);
			task_4x2bit_serial(data2);
			task_4x2bit_serial(data3);
			IN_ENA = 1'b0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			task_4x2bit_serial(crc[15:8]);
			task_4x2bit_serial(crc[7:0]);
			IN_DATA = 1'b0;
			IN_ENA = 1'b0;
		end
	endtask

	task task_crc64_test;
		input [7:0] data0;
		input [7:0] data1;
		input [7:0] data2;
		input [7:0] data3;
		input integer wait_time;
		input [63:0] crc;
		begin
			IN_CLR = 1;
			task_wait(1);
			IN_CLR = 0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			IN_DATA = data0;
		task_wait(1);
			IN_DATA = data1;
		task_wait(1);
			IN_DATA = data2;
		task_wait(1);
			IN_DATA = data3;
		task_wait(1);
			IN_ENA = 1'b0;
			task_wait(wait_time);
			IN_ENA = 1'b1;
			IN_DATA = crc[63:56];
			task_wait(1);
			IN_DATA = crc[55:48];
			task_wait(1);
			IN_DATA = crc[47:40];
			task_wait(1);
			IN_DATA = crc[39:32];
			task_wait(1);
			IN_DATA = crc[31:24];
			task_wait(1);
			IN_DATA = crc[23:16];
			task_wait(1);
			IN_DATA = crc[15:8];	
			task_wait(1);
			IN_DATA = crc[7:0];	
			task_wait(1);
			IN_DATA = 8'h00;
			IN_ENA = 1'b0;
		end
	endtask

	initial begin
		RESET_N = 0;
		IN_CLR = 0;
		IN_ENA = 0;
		IN_DATA = 0;

		task_wait(100);
		RESET_N = 1;

		task_wait(100);

		if (CRC_WIDTH == 7) begin
			if (DATA_WIDTH == 8) begin
				// SD CMD 0
				task_crc7_1byte_test(
						8'h40, 8'h00, 8'h00, 8'h00, 8'h00, 10, 7'h4A);
				task_wait(100);
				// SD CMD 8
				task_crc7_1byte_test(
						8'h48, 8'h00, 8'h00, 8'h01, 8'hAA, 10, 7'h43);
				task_wait(100);
				// SD CMD 16
				task_crc7_1byte_test(
						8'h50, 8'h00, 8'h00, 8'h02, 8'h00, 10, 7'h0A);
				task_wait(100);
			end
			else if (DATA_WIDTH == 1) begin
				// SD CMD 0
				task_crc7_1bit_test(
						8'h40, 8'h00, 8'h00, 8'h00, 8'h00, 10, 7'h4A);
				task_wait(100);
				// SD CMD 8
				task_crc7_1bit_test(
						8'h48, 8'h00, 8'h00, 8'h01, 8'hAA, 10, 7'h43);
				task_wait(100);
				// SD CMD 16
				task_crc7_1bit_test(
						8'h50, 8'h00, 8'h00, 8'h02, 8'h00, 10, 7'h0A);
				task_wait(100);
			end
		end
		else if (CRC_WIDTH == 16) begin
			if (DATA_WIDTH == 8) begin
				if ((SEED_VAL == 16'h0) && (OUTPUT_EXOR == 16'h0)) begin
					// "1234"
					task_crc16_test(
						8'h31, 8'h32, 8'h33, 8'h34, 2, 16'hD789);
					task_wait(100);
					// "!9qK"
					task_crc16_test(
						8'h21, 8'h39, 8'h71, 8'h4B, 2, 16'hD809);
					task_wait(100);
				end
				else if ((SEED_VAL == 16'hFFFF) && (OUTPUT_EXOR == 16'hFFFF)) begin
					// "1234" CRC = ACB6
					task_crc16_test(
						8'h31, 8'h32, 8'h33, 8'h34, 2, 16'h5349);
					task_wait(100);
					// "!9qK" CRC = A336
					task_crc16_test(
						8'h21, 8'h39, 8'h71, 8'h4B, 2, 16'h5CC9);
					task_wait(100);
				end
			end
			else if (DATA_WIDTH == 2) begin
				if ((SEED_VAL == 16'h0) && (OUTPUT_EXOR == 16'h0)) begin
					// "1234"
					task_crc16_2bit_test(
						8'h31, 8'h32, 8'h33, 8'h34, 2, 16'hD789);
					task_wait(100);
					// "!9qK"
					task_crc16_2bit_test(
						8'h21, 8'h39, 8'h71, 8'h4B, 2, 16'hD809);
					task_wait(100);
				end
			end
		end
		else if (CRC_WIDTH == 64) begin
			task_crc64_test('hDE, 'hAD, 'hBE, 'hEF, 4, 64'h3DF370C78407B980);
			task_wait(100);
		end

		$stop;
	end

endmodule

トラックバックURL

URL:https://rightxlight.co.jp/technical/crc-verilog-hdl-test-bench/trackback/

よく読まれている記事はこちら

ソフトウェアからハードウェアまで、
まずはお気軽にご相談下さい。

お電話はこちら

お電話はこちら 06-6309-7782

受付時間:9:00~18:00(土日祝は除く)

メールフォームからはこちら

お問い合わせお問い合わせ

Copyright (C) Since 2011 RIGHTxLIGHT Co., Ltd. All Rights Reserved.

PAGE TOP