mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-02-04 07:12:56 +08:00
336 lines
9.0 KiB
Coq
336 lines
9.0 KiB
Coq
|
// 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 - 08-25-2006
|
||
|
|
||
|
//////////////////////////////////////////
|
||
|
// 16 bit to 22 bit ECC encoder
|
||
|
//////////////////////////////////////////
|
||
|
|
||
|
module ecc_encode_16bit (d,c);
|
||
|
|
||
|
input [15:0] d;
|
||
|
output [21:0] c;
|
||
|
wire [21:0] c;
|
||
|
|
||
|
wire [1:0] help_c0;
|
||
|
xor6 help_c0_0 (help_c0[0],d[0],d[1],d[3],d[4],d[6],d[8]);
|
||
|
xor6 help_c0_1 (help_c0[1],d[10],d[11],d[13],d[15],1'b0,1'b0);
|
||
|
assign c[0] = ^help_c0;
|
||
|
|
||
|
wire [1:0] help_c1;
|
||
|
xor6 help_c1_0 (help_c1[0],d[0],d[2],d[3],d[5],d[6],d[9]);
|
||
|
xor6 help_c1_1 (help_c1[1],d[10],d[12],d[13],1'b0,1'b0,1'b0);
|
||
|
assign c[1] = ^help_c1;
|
||
|
|
||
|
assign c[2] = d[0];
|
||
|
wire [1:0] help_c3;
|
||
|
xor6 help_c3_0 (help_c3[0],d[1],d[2],d[3],d[7],d[8],d[9]);
|
||
|
xor6 help_c3_1 (help_c3[1],d[10],d[14],d[15],1'b0,1'b0,1'b0);
|
||
|
assign c[3] = ^help_c3;
|
||
|
|
||
|
assign c[4] = d[1];
|
||
|
assign c[5] = d[2];
|
||
|
assign c[6] = d[3];
|
||
|
wire [1:0] help_c7;
|
||
|
xor6 help_c7_0 (help_c7[0],d[4],d[5],d[6],d[7],d[8],d[9]);
|
||
|
assign help_c7[1] = d[10];
|
||
|
assign c[7] = ^help_c7;
|
||
|
|
||
|
assign c[8] = d[4];
|
||
|
assign c[9] = d[5];
|
||
|
assign c[10] = d[6];
|
||
|
assign c[11] = d[7];
|
||
|
assign c[12] = d[8];
|
||
|
assign c[13] = d[9];
|
||
|
assign c[14] = d[10];
|
||
|
assign c[15] = d[11] ^ d[12] ^ d[13] ^ d[14] ^ d[15];
|
||
|
assign c[16] = d[11];
|
||
|
assign c[17] = d[12];
|
||
|
assign c[18] = d[13];
|
||
|
assign c[19] = d[14];
|
||
|
assign c[20] = d[15];
|
||
|
wire [1:0] help_c21;
|
||
|
xor6 help_c21_0 (help_c21[0],d[0],d[1],d[2],d[4],d[5],d[7]);
|
||
|
xor6 help_c21_1 (help_c21[1],d[10],d[11],d[12],d[14],1'b0,1'b0);
|
||
|
assign c[21] = ^help_c21;
|
||
|
|
||
|
endmodule
|
||
|
|
||
|
//////////////////////////////////////////
|
||
|
// compute a syndrome from the code word
|
||
|
//////////////////////////////////////////
|
||
|
|
||
|
module ecc_syndrome_16bit (clk,rst,c,s);
|
||
|
|
||
|
// optional register on the outputs
|
||
|
// of bits 0..6 and back one level in bit 7
|
||
|
parameter REGISTER = 0;
|
||
|
|
||
|
input clk,rst;
|
||
|
input [21:0] c;
|
||
|
output [5:0] s;
|
||
|
reg [5:0] s;
|
||
|
|
||
|
// 11 terms
|
||
|
wire [1:0] help_s0;
|
||
|
xor6 help_s0_0 (help_s0[0],c[0],c[2],c[4],c[6],c[8],c[10]);
|
||
|
xor6 help_s0_1 (help_s0[1],c[12],c[14],c[16],c[18],c[20],1'b0);
|
||
|
generate
|
||
|
if (REGISTER) begin
|
||
|
always @(posedge clk or posedge rst) begin
|
||
|
if (rst) s[0] <= 0;
|
||
|
else s[0] <= ^help_s0;
|
||
|
end
|
||
|
end else begin
|
||
|
always @(help_s0) begin
|
||
|
s[0] = ^help_s0;
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
// 10 terms
|
||
|
wire [1:0] help_s1;
|
||
|
xor6 help_s1_0 (help_s1[0],c[1],c[2],c[5],c[6],c[9],c[10]);
|
||
|
xor6 help_s1_1 (help_s1[1],c[13],c[14],c[17],c[18],1'b0,1'b0);
|
||
|
generate
|
||
|
if (REGISTER) begin
|
||
|
always @(posedge clk or posedge rst) begin
|
||
|
if (rst) s[1] <= 0;
|
||
|
else s[1] <= ^help_s1;
|
||
|
end
|
||
|
end else begin
|
||
|
always @(help_s1) begin
|
||
|
s[1] = ^help_s1;
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
// 10 terms
|
||
|
wire [1:0] help_s2;
|
||
|
xor6 help_s2_0 (help_s2[0],c[3],c[4],c[5],c[6],c[11],c[12]);
|
||
|
xor6 help_s2_1 (help_s2[1],c[13],c[14],c[19],c[20],1'b0,1'b0);
|
||
|
generate
|
||
|
if (REGISTER) begin
|
||
|
always @(posedge clk or posedge rst) begin
|
||
|
if (rst) s[2] <= 0;
|
||
|
else s[2] <= ^help_s2;
|
||
|
end
|
||
|
end else begin
|
||
|
always @(help_s2) begin
|
||
|
s[2] = ^help_s2;
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
// 8 terms
|
||
|
wire [1:0] help_s3;
|
||
|
xor6 help_s3_0 (help_s3[0],c[7],c[8],c[9],c[10],c[11],c[12]);
|
||
|
xor6 help_s3_1 (help_s3[1],c[13],c[14],1'b0,1'b0,1'b0,1'b0);
|
||
|
generate
|
||
|
if (REGISTER) begin
|
||
|
always @(posedge clk or posedge rst) begin
|
||
|
if (rst) s[3] <= 0;
|
||
|
else s[3] <= ^help_s3;
|
||
|
end
|
||
|
end else begin
|
||
|
always @(help_s3) begin
|
||
|
s[3] = ^help_s3;
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
// 6 terms
|
||
|
wire [0:0] help_s4;
|
||
|
xor6 help_s4_0 (help_s4[0],c[15],c[16],c[17],c[18],c[19],c[20]);
|
||
|
generate
|
||
|
if (REGISTER) begin
|
||
|
always @(posedge clk or posedge rst) begin
|
||
|
if (rst) s[4] <= 0;
|
||
|
else s[4] <= ^help_s4;
|
||
|
end
|
||
|
end else begin
|
||
|
always @(help_s4) begin
|
||
|
s[4] = ^help_s4;
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
// 22 terms
|
||
|
wire [3:0] help_s5;
|
||
|
xor6 help_s5_0 (help_s5[0],c[0],c[1],c[2],c[3],c[4],c[5]);
|
||
|
xor6 help_s5_1 (help_s5[1],c[6],c[7],c[8],c[9],c[10],c[11]);
|
||
|
xor6 help_s5_2 (help_s5[2],c[12],c[13],c[14],c[15],c[16],c[17]);
|
||
|
xor6 help_s5_3 (help_s5[3],c[18],c[19],c[20],c[21],1'b0,1'b0);
|
||
|
generate
|
||
|
if (REGISTER) begin
|
||
|
always @(posedge clk or posedge rst) begin
|
||
|
if (rst) s[5] <= 0;
|
||
|
else s[5] <= ^help_s5;
|
||
|
end
|
||
|
end else begin
|
||
|
always @(help_s5) begin
|
||
|
s[5] = ^help_s5;
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
endmodule
|
||
|
|
||
|
//////////////////////////////////////////
|
||
|
// From the syndrome compute the correction
|
||
|
// needed to fix the data, or set fatal = 1
|
||
|
// and no correction if there are too many.
|
||
|
//////////////////////////////////////////
|
||
|
module ecc_correction_16bit (s,e,fatal);
|
||
|
|
||
|
input [5:0] s;
|
||
|
output [15:0] e;
|
||
|
output fatal;
|
||
|
wire [15:0] e;
|
||
|
|
||
|
// decode the syndrome
|
||
|
reg [63:0] d;
|
||
|
wire [63:0] dw /* synthesis keep */;
|
||
|
always @(s) begin
|
||
|
d = 64'b0;
|
||
|
d[{!s[5],s[4:0]}] = 1'b1;
|
||
|
end
|
||
|
assign dw = d;
|
||
|
|
||
|
// Identify uncorrectable errors
|
||
|
wire fatal = (|s[4:0]) & !s[5] /* synthesis keep */;
|
||
|
assign e = {
|
||
|
dw[21],dw[20],dw[19],dw[18],
|
||
|
dw[17],dw[15],dw[14],dw[13],
|
||
|
dw[12],dw[11],dw[10],dw[9],
|
||
|
dw[7],dw[6],dw[5],dw[3]
|
||
|
};
|
||
|
|
||
|
|
||
|
endmodule
|
||
|
|
||
|
//////////////////////////////////////////
|
||
|
// select the (uncorrected) data bits out
|
||
|
// of the code word.
|
||
|
//////////////////////////////////////////
|
||
|
|
||
|
module ecc_raw_data_16bit (clk,rst,c,d);
|
||
|
parameter REGISTER = 0;
|
||
|
input clk,rst;
|
||
|
input [21:0] c;
|
||
|
output [15:0] d;
|
||
|
reg [15:0] d;
|
||
|
|
||
|
wire [15:0] d_int;
|
||
|
|
||
|
// pull out the pure data bits
|
||
|
assign d_int = {
|
||
|
c[20],c[19],c[18],c[17],c[16],c[14],c[13],c[12],
|
||
|
c[11],c[10],c[9],c[8],c[6],c[5],c[4],c[2]
|
||
|
};
|
||
|
|
||
|
// conditional output register
|
||
|
generate
|
||
|
if (REGISTER) begin
|
||
|
always @(posedge clk or posedge rst) begin
|
||
|
if (rst) d <= 0;
|
||
|
else d <= d_int;
|
||
|
end
|
||
|
end else begin
|
||
|
always @(d_int) begin
|
||
|
d <= d_int;
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
endmodule
|
||
|
|
||
|
//////////////////////////////////////////
|
||
|
// 22 bit to 16 bit ECC decoder
|
||
|
//////////////////////////////////////////
|
||
|
|
||
|
module ecc_decode_16bit (clk,rst,c,d,no_err,err_corrected,err_fatal);
|
||
|
|
||
|
// optional pipeline registers at the halfway
|
||
|
// point and on the outputs
|
||
|
parameter MIDDLE_REG = 0;
|
||
|
parameter OUTPUT_REG = 0;
|
||
|
|
||
|
input clk,rst;
|
||
|
input [21:0] c;
|
||
|
output [15:0] d;
|
||
|
output no_err, err_corrected, err_fatal;
|
||
|
|
||
|
reg [15:0] d;
|
||
|
reg no_err, err_corrected, err_fatal;
|
||
|
|
||
|
// Pull the raw (uncorrected) data from the codeword
|
||
|
wire [15:0] raw_bits;
|
||
|
ecc_raw_data_16bit raw (.clk(clk),.rst(rst),.c(c),.d(raw_bits));
|
||
|
|
||
|
defparam raw .REGISTER = MIDDLE_REG;
|
||
|
// Build syndrome, which will be 0 for correct
|
||
|
// correct codewords, otherwise a pointer to the
|
||
|
// error.
|
||
|
wire [5:0] syndrome;
|
||
|
ecc_syndrome_16bit syn (.clk(clk),.rst(rst),.c(c),.s(syndrome));
|
||
|
defparam syn .REGISTER = MIDDLE_REG;
|
||
|
|
||
|
// Use the the syndrome to find a correction, or 0 for no correction
|
||
|
wire [15:0] err_flip;
|
||
|
wire fatal;
|
||
|
ecc_correction_16bit cor (.s(syndrome),.e(err_flip),.fatal(fatal));
|
||
|
|
||
|
// Classify error types and correct data as appropriate
|
||
|
// If there is a multibit error take care not to make
|
||
|
// the data worse.
|
||
|
generate
|
||
|
if (OUTPUT_REG) begin
|
||
|
always @(posedge clk or posedge rst) begin
|
||
|
if (rst) begin
|
||
|
no_err <= 1'b0;
|
||
|
err_corrected <= 1'b0;
|
||
|
err_fatal <= 1'b0;
|
||
|
d <= 1'b0;
|
||
|
end else begin
|
||
|
no_err <= ~| syndrome;
|
||
|
err_corrected <= syndrome[5];
|
||
|
err_fatal <= fatal;
|
||
|
|
||
|
d <= err_flip ^ raw_bits;
|
||
|
end
|
||
|
end
|
||
|
end else begin
|
||
|
always @(*) begin
|
||
|
no_err = ~| syndrome;
|
||
|
err_corrected = syndrome[5];
|
||
|
err_fatal = fatal;
|
||
|
|
||
|
d = err_flip ^ raw_bits;
|
||
|
end
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
endmodule
|
||
|
|