题目要求:
对输入的32位数据进行奇偶校验,根据sel输出校验结果(1输出奇校验,0输出偶校验)
知识储备:
什么是奇偶校验
奇偶校验:是用来判断传输的一组二进制数据中**"1"的个数**是奇数还是偶数。
- 若检测到的 1 的个数是奇数个,就称为奇校验
- 若检测到的 1 的个数是偶数个,就称为偶校验
例如:
给定数据 e = 4’b1001,那么其含有 1 的个数是偶数,为偶校验
给定数据 e = 4’b1101,那么其含有 1 的个数是奇数,为奇校验
采用单目运算符来进行奇偶验证
其中e表示一位的0或1,d表示数据,假设为4’b1001;
e = ^ d ; 异或运算来进行奇偶校验。
e = &d ; 与运算可检查是否全为1(是否含0)
e = | d ; 或运算可检查是否全为0(是否含1)
这里主要分析异或运算,e = ^ d ;
如果一个二进制数,每一位进行异或运算,其结果为1,则说明含有奇数个1,可作为奇校验。反之,结果为0,说明有偶数个1,可作为偶校验。——因此可将异或运算作为奇偶校验的判断标准。
题目中给出信号示意图和波形示意图如下:
通过信号示意图可看出,对数据d进行奇偶校验,通过sel选择,输出check信号是输出奇校验还是偶校验。
通过波形图可看到,数据bus = 0,且数据0中含有偶数个1,那么其奇偶校验的结果就是0。但是此时的check却为1,sel为低电平,这就说明sel == 0的时候,check接收的结果与真实数据计算出来的奇偶结果相反,当sel为1的时候,结果却相同。
因此整个的Verilog代码编写主要分为两个部分:
一:使用异或运算来判断奇偶结果
二:通过sel来决定check输出上一步的结果(根据sel高低电平判断check结果是直接输出,还是进行取反输出)
代码如下:
`timescale 1ns/1ns
module odd_sel(
input [31:0] bus, //相当于信号示意图中的d
input sel,
output check
);
//*************code***********//
//先采用异或单目运算符来确定数据d中含有1的个数的奇数还是偶数
reg check_tmp;
always @ (*)begin
check_tmp = ^bus;
end
reg check_tmp1;
always @ (*)begin
if(sel)
check_tmp1 = check_tmp;
else
check_tmp1 = ~check_tmp;
end
assign check = check_tmp1;
//*************code***********//
endmodule
FPGA进行奇偶校验的方法二
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
tb仿真文件:
`timescale 1ns/1ns
module tb_odd_even1();
reg clk ;
reg in ;
reg reset ;
wire odd ;
wire even ;
odd_even1 u1(
.clk (clk),
.reset (reset),
.in (in),
.odd (odd),
.even (even)
);
initial begin
clk = 1'b1;
reset <= 1'b1; //初始高复位
#20
reset <= 1'b0;
end
always #10 clk = ~clk;
always #20 in <= {$random}%2; //每20ns随机生成0或1
endmodule