Verilgo实现的FPGA奇偶校验

1、奇偶校验

奇偶校验(Parity Check)是一种校验代码传输正确性的方法。根据被传输的一组二进制数位中“1”的个数是奇数或偶数来进行校验。采用奇数的称为奇校验,反之,称为偶校验。采用何种校验是事先规定好的。通常专门设置一个奇偶校验位,用它使这组代码中“1”的个数为奇数或偶数。若用奇校验,则当接收端收到这组代码时,校验“1”的个数是否为奇数,从而确定传输代码的正确性。

举例,要输出一组8-bit数据,为“11101000”,该组数据共有4个“1”。若使用奇校验,则校验位应为1,传输数据实际为8-bit数据+1-bit奇校验位,即“111010001”;若使用偶校验,则校验位应为0,传输数据实际为8-bit数据+1-bit偶校验位,即“111010000”。

2、输入数据的校验方法

根据输入串行数据码流,“实时”生成所输入数据的校验位。

2.1、举例

欲串行接收数据“11101000”(传输低位在前,高位在后),则数据线上的数据应为“0-0-0-1-0-1-1-1”

        奇校验应为“x-1-1-1-0-0-1-0-1”(采用时序逻辑输出,会落后一个时钟周期)

        偶校验应为“x-0-0-0-1-1-0-1-0”(采用时序逻辑输出,会落后一个时钟周期)

        校验位刚好落后数据一个时钟周期,方便拼接。

时序图如下:

  

输出信号odd根据输入信号变化,假如输入数据只输入4-bit,0001,则奇校验位0,偶校验位1,可以看到在输入信号的下一个周期,odd、even的输出符合预期,其他数据相同,这里不赘述。

        奇校验实现方式:校验位默认为高电平,每检测到1,则状态翻转

        偶校验实现方式:校验位默认为低电平,每检测到1,则状态翻转

2.2、verilog实现

        根据上述,编写如下代码:

module odd_even1(
    input		clk		,
    input		in		,	//串行输入
    input		reset	,   //同步复位,高电平有效
	output	reg	odd		,	//奇校验位
    output	reg	even		//偶校验位
);

always@(posedge clk)begin
	if(reset)begin
		odd <= 1'b1;
		even <= 1'b0;
	end
	else if(in)begin
		odd <= ~odd;
		even <= ~even;	
	end
	else begin
		odd <= odd;
		even <= even;
	end
end

endmodule

2.3、testbench仿真

编写仿真对上述模块进行测试,激励输入随机生成0或1.

`timescale 1ns/1ns	//时间单位/精度

//------------<模块及端口声明>----------------------------------------
module tb_odd_even1();

reg		clk		;
reg		in		;		
reg		reset	;

wire	odd		;
wire	even   	;
//------------<例化被测试模块>----------------------------------------
odd_even1	odd_even1_inst(
	.clk	(clk),
	.reset	(reset),
	.in		(in),

	.odd	(odd),
	.even	(even)
);

//------------<设置初始测试条件>----------------------------------------
initial begin
	clk = 1'b1;					//初始时钟为1
	reset <= 1'b1;				//初始复位
	#20
	reset <= 1'b0;		
	
end
//------------<设置时钟>----------------------------------------------
always #10 clk = ~clk;		//系统时钟周期20ns

always #20 in <= {$random}%2;	//每20ns随机生成0或1

endmodule

2.4、仿真结果

仿真结果如下:

假设两黄线中间刚好传输了一次8-bit数据,则传输的数据应为1011_1111 (低位在前),那么这组数据的奇校验位应是:0 ;偶校验位应是:1 ;上图中蓝色字体标注与理论一直,而输入数据的第九位为1,则可视为一次偶校验。

通过比对数据码流上的第九位(校验位)与输出的奇偶校验结果,就可以判断这次数据接收是否成功。

3、输出数据的校验方法

除了对接收数据的正确性做奇偶校验外,同时也需要对输出给的外部数据提供一个奇偶校验结果,方便外部模块比对数据是否传输正常。

3.1、举例

仅对输出数据为8-bit的情况做示例,其他位宽原理一致。

欲串行发送数据“11101000”:

        奇校验结果应为“1”,实际应传输“111010001”:

        偶校验结果应为“0”,实际应传输“111010000”:

 实现方法:

        根据异或的定义:相异为1,相同为0。可推出:偶数个1异或的结果为0,奇数个1异或的结果为1。所以:

                偶校验:将输入数据按位异或

                奇校验:将输入数据按位异或再取反(与偶校验相反)

3.2、verilog实现

        根据上述,编写如下代码:

module odd_even2(
    input			clk		,
    input	[7:0]	in		,	//并行输入
    input			reset	,   //同步复位,高电平有效
	output	reg		odd		,	//奇校验位
    output	reg		even		//偶校验位
);

always@(posedge clk)begin
	if(reset)begin
		odd <= 1'b0;
		even <= 1'b0;
	end
	else begin
		odd <= ~(^in);
		even <= ^in;
	end
end

endmodule

3.3、testbench仿真

编写仿真对上述模块进行测试,激励输入随机生成8-bit数据:

`timescale 1ns/1ns	//时间单位/精度

//------------<模块及端口声明>----------------------------------------
module tb_odd_even2();

reg			clk		;
reg	[7:0]	in		;		
reg			reset	;

wire		odd		;
wire		even   	;
//------------<例化被测试模块>----------------------------------------
odd_even2	odd_even2_inst(
	.clk	(clk),
	.reset	(reset),
	.in		(in),

	.odd	(odd),
	.even	(even)
);

//------------<设置初始测试条件>----------------------------------------
initial begin
	clk = 1'b1;					//初始时钟为0
	reset <= 1'b1;				//初始复位
	#20
	reset <= 1'b0;		
	
end
//------------<设置时钟>----------------------------------------------
always #10 clk = ~clk;		//系统时钟周期20ns

always #20 in <= {$random}%256;	//每20ns随机生成8-bit数据

endmodule

3.4、仿真结果

仿真结果如下:

  • 由于使用的时序逻辑,所以校验位的输出会落后输入数据一个时钟周期
  • 输入数据“00100100”,奇校验位应为:1   偶校验位应为:0  ,仿真结果与分析一致。其他数据不分析了,都时满足要求的

4、总结

  • 奇偶校验属于是一种比较简单的校验方式,效率比较低(如果传输过程中偶数个位同时错误,则无法校验出来),但是对于一般要求不严格的场合还是应用的较多,需要熟练掌握
  • 需要工程的同学可以评论留下邮箱

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤独的单刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值