⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecc_8bit_tb.v

📁 本電子檔為 verilog cookbook,包含了通訊,影像,DSP等重要常用之verilog編碼,可作為工程師與初學者的參考手冊
💻 V
字号:
// Copyright 2007 Altera Corporation. All rights reserved.  
// Altera products are protected under numerous U.S. and foreign patents, 
// maskwork rights, copyrights and other intellectual property laws.  
//
// This reference design file, and your use thereof, is subject to and governed
// by the terms and conditions of the applicable Altera Reference Design 
// License Agreement (either as signed by you or found at www.altera.com).  By
// using this reference design file, you indicate your acceptance of such terms
// and conditions between you and Altera Corporation.  In the event that you do
// not agree with such terms and conditions, you may not use the reference 
// design file and please promptly destroy any copies you have made.
//
// This reference design file is being provided on an "as-is" basis and as an 
// accommodation and therefore all warranties, representations or guarantees of 
// any kind (whether express, implied or statutory) including, without 
// limitation, warranties of merchantability, non-infringement, or fitness for
// a particular purpose, are specifically disclaimed.  By making this reference
// design file available, Altera expressly does not recommend, suggest or 
// require that this reference design file be used in combination with any 
// other product not provided by Altera.
/////////////////////////////////////////////////////////////////////////////

// baeckler - 07-20-2006

module ecc_8bit_tb ();

// this should be the sum of encode and 
// decode registers
parameter TOTAL_LATENCY = 2;

reg [7:0] data_in,next_data_in;
wire [12:0] code_out;
reg [12:0] error_sig,next_error_sig;
wire [12:0] damaged_code;
wire [7:0] recovered_data;
wire no_err,err_corrected,err_fatal;

reg clk,rst;

///////////////////////
// encoder unit
///////////////////////
ecc_encode_8bit enc
(
	.d(data_in),
	.c(code_out)
);

///////////////////////
// insert optional error 
///////////////////////
reg [2:0] num_errors, next_num_errors;
assign damaged_code = code_out ^ error_sig;

///////////////////////
// decoder unit 
///////////////////////
ecc_decode_8bit dec 
(
	.clk(clk),
	.rst(rst),
	.c(damaged_code),
	.d(recovered_data),
	.no_err(no_err),
	.err_corrected(err_corrected),
	.err_fatal(err_fatal)
);
defparam dec .MIDDLE_REG = 1;
defparam dec .OUTPUT_REG = 1;


////////////////////////
// main control 
////////////////////////
reg fail;
reg [TOTAL_LATENCY:0] flushing;

initial begin
	clk = 0;
	rst = 0;
	num_errors = 0;
	error_sig = 0;
	data_in = 8'b0;
	fail = 0;

	#10 rst = 1;
	#10 rst = 0;

	// wait for the pipe to fill
	#10
	if (!flushing[TOTAL_LATENCY]) begin
		@(posedge flushing[TOTAL_LATENCY]);
	end
	fail = 0;

	#10000000 if (!fail) $display ("PASS"); 
	else $display ("FAIL");
	$stop();
end

integer n = 0;
reg [6:0] which_bit;

////////////////////////
// new random stimulus
////////////////////////
always @(negedge clk or posedge rst) begin
	next_data_in = {$random,$random};
	
	// create an error signal with a few randomly
	// placed 1's.
	next_num_errors = $random;
	next_num_errors = next_num_errors % 5;

	next_error_sig = 13'b0;
	for (n=0; n<next_num_errors; n=n+1)
	begin
		which_bit = $random;
		which_bit = which_bit % 13;
		while (next_error_sig[which_bit]) 
		begin
			which_bit = (which_bit + 1) % 13;	
		end
		next_error_sig[which_bit] = 1'b1;
	end
end

always @(posedge clk or posedge rst) begin
	if (rst) begin
		num_errors <= 0;
		error_sig <= 0;
		data_in <= 0;
	end
	else begin
		num_errors <= next_num_errors;
		data_in <= next_data_in;
		error_sig <= next_error_sig;
	end
end

///////////////////////
// latency matching 
///////////////////////
reg [12:0] delayed_data [TOTAL_LATENCY:0];
reg [2:0] delayed_num_errors [TOTAL_LATENCY:0];
integer i ;

always @(posedge clk or posedge rst) begin
	if (rst) begin
		flushing <= 1'b1;
	end
	else begin
		flushing <= flushing | (flushing << 1'b1);
		for (i=TOTAL_LATENCY; i>0; i=i-1) begin
			delayed_data[i] <= delayed_data[i-1];
			delayed_num_errors[i] <= delayed_num_errors[i-1];
		end
	end
end

always @(*) begin
	delayed_num_errors[0] = num_errors;
	delayed_data[0] = data_in;
end

///////////////////////////////
// capture and check results 
///////////////////////////////

integer wrong_bits = 0;
reg [12:0] recovered_error;

integer stats_3bit_pass = 0;
integer stats_3bit_one = 0;
integer stats_3bit_two = 0;

integer stats_4bit_pass = 0;
integer stats_4bit_one = 0;
integer stats_4bit_two = 0;

integer z;

always @(posedge clk or posedge rst) begin
	#20
		
	// count the number of wrong bits in the 
	// recovered data.
	wrong_bits = 0;
	recovered_error = delayed_data[TOTAL_LATENCY] ^ recovered_data;
	for (z=0;z<13;z=z+1)
	begin
		if (recovered_error[z]) wrong_bits = wrong_bits + 1;
	end

	#1
			
	if (delayed_num_errors[TOTAL_LATENCY] == 0) begin
		if (wrong_bits !== 0) fail = 1;
		if ({no_err,err_corrected,err_fatal} !== 3'b100) fail = 1;
	end
	else if (delayed_num_errors[TOTAL_LATENCY] == 1) begin
		// 1 bit errors need to be flagged and repaired
		if (wrong_bits !== 0) begin
			$display ("Single bit error was not corrected");
			fail = 1;
		end
		if ({no_err,err_corrected,err_fatal} !== 3'b010) begin
			$display ("Single bit error was not flagged");
			fail = 1;
		end
	end
	else if (delayed_num_errors[TOTAL_LATENCY] == 2) begin
		// 2 bit errors need to be detected
		// and not made any worse
		if (wrong_bits > 2) fail = 1;
		if ({no_err,err_corrected,err_fatal} !== 3'b001) fail = 1;
	end	
	else if (delayed_num_errors[TOTAL_LATENCY] == 3) begin
		// 3 bit errors need to be detected as parity error
		// they will be mistakenly corrected as 1 bit errors
		if ({no_err,err_corrected,err_fatal} == 3'b100) 
			stats_3bit_pass = stats_3bit_pass + 1;
		else if ({no_err,err_corrected,err_fatal} == 3'b010) 
			stats_3bit_one = stats_3bit_one + 1;
		else if ({no_err,err_corrected,err_fatal} == 3'b001) 
			stats_3bit_two = stats_3bit_two + 1;				
	end
	else begin
		// 4 + bit errors
		if ({no_err,err_corrected,err_fatal} == 3'b100) 
			stats_4bit_pass = stats_4bit_pass + 1;
		else if ({no_err,err_corrected,err_fatal} == 3'b010) 
			stats_4bit_one = stats_4bit_one + 1;
		else if ({no_err,err_corrected,err_fatal} == 3'b001) 
			stats_4bit_two = stats_4bit_two + 1;				
	end

	// early exit for failure
	if (fail) begin
		#100 $display ("Mismatch at time %d",$time);
		$stop();
	end
end

always begin
	#100 clk = ~clk;
end

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -