verilog实现简单的ecc检验与纠错
以4bit数据为例
编码数据
原理看上一篇总结
PP的值是前面全部数据的奇偶校验值
最终数据以{PP,P2,P1,P0,D3,D2,D1,D0}的顺序传输。
解码数据
获取到数据后,重新计算出检验码,得到新的检验码,并与旧的检验码进行异或,异或得到的4bit数据称命名为syndrome。
- 当syndrome最高位为0时
若syndrome其余位为0,则没有错误。
若非0,则存在两个错误。 当syndrome最高位为1时
数据存在1个错误,错误的位置在H[syndrome[2:0]](除了syndrome最高位的其余位)。//检验数据并纠错,输出正确的数据 module decoder( input [7:0]data_in, output reg [3:0]data_out ); //根据接收的数据重新计算检验值 //选择奇偶检验的数据位 wire [3:0] check_bit2_sel=4'b1011; wire [3:0] check_bit3_sel=4'b1101; wire [3:0] check_bit4_sel=4'b1110; //计算检验位数据 wire [2:0]ecc_data_without_pp_new; assign ecc_data_without_pp_new[0]=^(data_in[3:0] & check_bit2_sel); assign ecc_data_without_pp_new[1]=^(data_in[3:0] & check_bit3_sel); assign ecc_data_without_pp_new[2]=^(data_in[3:0] & check_bit4_sel); reg pp;//全部数据的奇偶检验 always @(ecc_data_without_pp_new) begin pp=^{ecc_data_without_pp_new[2:0],data_in[3:0]}; end wire [3:0]syn;//比较两次检验值差异 assign syn=data_in[7:4]^{pp,ecc_data_without_pp_new}; reg [3:0]where;//错误的位置 always @(syn) begin if(syn[3]==0) begin if(syn[2:0]==3'd0) data_out=data_in[3:0]; else data_out=4'd0; end else case (syn[2:0]) 3'd3:where=4'b0001; 3'd5:where=4'b0010; 3'd6:where=4'b0100; 3'd7:where=4'b1000; default :where=4'b0000; endcase end always @(where) begin data_out=data_in[3:0]^where; end endmodule
//为接收到的数据计算ecc检验值 module encoder( input [3:0]data, output [7:0] out );//选择奇偶检验的数据位 wire [3:0] check_bit2_sel=4'b1011; wire [3:0] check_bit3_sel=4'b1101; wire [3:0] check_bit4_sel=4'b1110; //计算检验位数据 reg pp; wire [2:0]ecc_data_without_pp; assign ecc_data_without_pp[0]=^(data & check_bit2_sel); assign ecc_data_without_pp[1]=^(data & check_bit3_sel); assign ecc_data_without_pp[2]=^(data & check_bit4_sel); always @(ecc_data_without_pp) begin pp=^{ecc_data_without_pp,data}; end assign out={pp,ecc_data_without_pp,data}; endmodule
安装Ubuntu
在电脑实体机上重新安装了ubuntu,在屏蔽核显之后总算不会自动重启了。安装了常用的软件如QQ,clash,vscode等,使用wine装了微信。甚至装了steam后使用proton兼容层可以玩盗版的Windows游戏。