奇偶校驗是一種簡單、實現代價小的檢錯方式,常用在數據傳輸過程中。對于一組并行傳輸的數據(通常為8比特),可以計算岀它們的奇偶校驗位并與其一起傳輸。接收端根據接收的數據重新計算其奇偶校驗位并與接收的值進行比較,如果二者不匹配,那么可以確定數據傳輸過程中岀現了錯誤;如果二者匹配,可以確定傳輸過程中沒有出錯或者出現了偶數個錯誤(出現這種情況的概率極低)。
需要指出當出現偶數個錯誤時,奇偶校驗是無法檢測此時電路出現傳輸錯誤。例如,發送的數據為8’b1010_1011此時計算出的偶校驗值是1。如果在傳輸中后兩位從11跳變為00,那么此時接收到的數據為8’b10100100,接收的偶校驗值仍然為1。對接收的數據進行偶校驗計算,得到的結果仍然為1,這與收到的校驗值是相同的,接收電路無法檢測出接收數據中岀現的錯誤。
奇偶校驗位有兩種類型:偶校驗位與奇校驗位。
以偶校驗位來說,如果一組給定數據位中1的個數是奇數,補一個bit為1,使得總的1的個數是偶數。例:0000001, 補一個bit為1, 00000011。
以奇校驗位來說,如果給定一組數據位中1的個數是奇數,補一個bit為0,使得總的1的個數是奇數。例:0000001, 補一個bit為0, 00000010。
簡單理解奇偶校驗:
奇校驗:原始碼流+校驗位 總共有奇數個1
偶校驗:原始碼流+校驗位 總共有偶數個1
二、XOR法
2.1 XOR法
題目:采用XOR法試寫一個發送端奇偶校驗器,在發送端會輸入一段8bit的數據,可以選擇切換奇數校驗或者偶數校驗,并且將校驗值附在末位輸出。
2.2 verilog代碼
//使用XOR法設計奇偶校驗器
module parity_checker01(
? ? input? ? ? ? ? ?clk,
? ? input? ? ? ? ? ?rst_n,
? ? input ?? ? ? ? ?parity_odd,//是否為奇校驗:奇數校驗為1,偶數校驗位0
? ? input? ?[7:0]? ?data_in,//輸入的八位數據
? ? output? [8:0]? ?data_out,//輸出的九位數據
? ? output? reg? ? ?even_bit,//偶數校驗碼
? ? output? reg? ? ?odd_bit//計數校驗碼
? ? );
?//使用按位異或確定偶數校驗碼和奇數校驗碼? ?
always@(posedge clk or negedge rst_n) begin
? ? if(!rst_n) begin
? ? even_bit <= 1'b0;
? ? odd_bit? <= 1'b0;
? ? end
? ? else begin
? ? even_bit <= ^data_in;? ?//偶校驗條件下計算出來的校驗位
? ? odd_bit? <= ~(^data_in);//奇校驗條件下計算出來的校驗位
? ? end
end
?//組合邏輯完成輸入數據與校驗碼的拼接
assign data_out = parity_odd ? {data_in[7:0],odd_bit}?
? ? ? ? ? ?: {data_in[7:0],even_bit};
endmodule
2.3 Testbench
`timescale 1ns / 1ps//仿真時間單位1ns 仿真時間精度1ps
module parity_checker01_tb();
//信號申明
regclk;
regrst_n;
reg? ? ? ? ?parity_odd;
reg? [7:0] data_in;
wire [8:0]? data_out;
wire? ? even_bit;
wire? ? ?odd_bit;
//模塊實例化(將申明的信號連接起來即可)
parity_checker01 u_parity_checker01(
? ? .clk? ? ? ? ? (clk),
? ? .rst_n? ? ? ? (rst_n),
? ? .parity_odd? (parity_odd),
? ? .data_in? ? ? (data_in),
? ? .data_out? ? ?(data_out),
? ? .even_bit? ? ?(even_bit),
? ? .odd_bit? ? ? (odd_bit)
? ? );
//生成時鐘信號
always #5 clk = ~clk;
//生成復位信號
//為時鐘信號和復位信號等賦初值
initial begin
? ? clk? ? ? ? = 1;
? ? rst_n? ? ? = 1;
? ? data_in? ? = 0;
? ? parity_odd = 1;
? ? #5? rst_n <= 0;
? ? #5? rst_n <= 1;
? ? data_in = 8'h01;
? ? #20
? ? data_in = 8'hb7;
? ? #20
? ? data_in = 8'h32;
? ? #20
? ? data_in = 8'he9;
? ? #20
? ? data_in = 8'hd3;
end
endmodule
2.4 仿真結果
三、計數器法
3.1 計數器法
題目:采用計數器法試寫一個發送端奇偶校驗器,在發送端會輸入一段8bit的數據,可以選擇切換奇數校驗或者偶數校驗,并且將校驗值附在末位輸出。
3.2 verilog代碼
//使用計數器法設計奇偶校驗器
module parity_checker02(
? ? input? ? ? ? ? ?clk,
? ? input? ? ? ? ? ?rst_n,
? ? input ?? ? ? ? ?parity_odd,//是否為奇校驗:奇數校驗為1,偶數校驗位0
? ? input? ?[7:0]? ?data_in,//輸入的八位數據
? ? output? [8:0]? ?data_out,//輸出的九位數據
? ? output? reg? ? ?even_bit,//偶數校驗碼
? ? output? reg? ? ?odd_bit//奇數校驗碼
? ? );
//定義一個三位寬的計數器
reg[2:0] cnt;
//計數器模塊
//輸入數據data_in逢1逐位計數
integer i;
always @(*) begin
? ? cnt = 3'd0;
? ? for (i=0;i<8;i=i+1) begin
? ? ? ? if(data_in[i]==1'b1) begin
? ? ? ? ? ? cnt = cnt + 1;
? ? ? ? end
? ? end
end
//計數器校驗模塊
//使用時序邏輯對計數器中的1校驗奇數or偶數
//計數器最低位為奇數,則整體為奇數,反之為偶數
always@(posedge clk or negedge rst_n) begin
? ? if(!rst_n) begin
even_bit <= 1'b0;
? ? odd_bit? <= 1'b0;
? ? end
? ? else if(cnt[0] == 1'b1) begin//通過計數器最低位判斷是否為偶數
even_bit <= 1'b1;??
odd_bit? <= 1'b0;
? ? end
? ? else begin
even_bit <= 1'b0;
odd_bit? <= 1'b1;
? ? end
end
//組合邏輯完成輸入數據與校驗碼的拼接
assign data_out = parity_odd ? {data_in[7:0],odd_bit}?
? ? ? ? ? ?: {data_in[7:0],even_bit};
endmodule
3.3 Testbench
`timescale 1ns / 1ps//仿真時間單位1ns 仿真時間精度1ps
module parity_checker02_tb();
//信號申明
regclk;
regrst_n;
reg? ? ? ? ?parity_odd;
reg? [7:0] data_in;
wire [8:0]? data_out;
wire? ? even_bit;
wire? ? ?odd_bit;
//模塊實例化(將申明的信號連接起來即可)
parity_checker02 u_parity_checker02(
? ? .clk? ? ? ? ? (clk),
? ? .rst_n? ? ? ? (rst_n),
? ? .parity_odd? (parity_odd),
? ? .data_in? ? ? (data_in),
? ? .data_out? ? ?(data_out),
? ? .even_bit? ? ?(even_bit),
? ? .odd_bit? ? ? (odd_bit)
? ? );
//生成時鐘信號
always #5 clk = ~clk;
//生成復位信號
//為時鐘信號和復位信號等賦初值
initial begin
? ? clk? ? ? ? = 1;
? ? rst_n? ? ? = 1;
? ? data_in? ? = 0;
? ? parity_odd = 1;
? ? #5? rst_n <= 0;
? ? #5? rst_n <= 1;
? ? data_in = 8'h01;
? ? #10
? ? data_in = 8'hb7;
? ? #10
? ? data_in = 8'h32;
? ? #10
? ? data_in = 8'he9;
? ? #10
? ? data_in = 8'hd3;
end
endmodule
仿真結果
四、總結
奇偶校驗器設計主要思路是通過弄清一組數據中“1”和“0”的數目。若是奇校驗則原始碼流+校驗位總共有奇數個“1”;若是偶校驗則原始碼流+校驗位總共有偶數個“1”。設計方法主要有XOR法和計數器法。XOR法最簡單,只需要對數據使用按位異或,輸出為“0”代表數據中“1”位偶數個;計數器法最直觀,計數器中數值的奇偶性表示對應數據中“1”個數的奇偶。
Tips:判斷計數器是奇數還是偶數主要有判斷data_out[0]和取余數兩種方法,前者綜合后耗損的資源太多不推薦前者。
?
審核編輯:劉清
評論
查看更多