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

以前、弊社で作成した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

タグ


2017年6月2日 | コメント/トラックバック(0)|

カテゴリー:技術情報

このページの先頭へ

イメージ画像