1
0
mirror of https://github.com/pConst/basic_verilog.git synced 2025-02-04 07:12:56 +08:00

415 lines
14 KiB
Coq
Raw Normal View History

2015-12-15 22:44:58 +03:00
// 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 - 04-10-2006
// an 8b10b decoder, based on files from Martin R and IBM paper
module decoder_8b10b (
clk,
rst,
din_ena, // 10b data ready
din_dat, // 10b data input
din_rd, // running disparity input
dout_val, // data out valid
dout_dat, // data out
dout_k, // special code
dout_kerr, // coding mistake detected
dout_rderr, // running disparity mistake detected
dout_rdcomb, // running disparity output (comb)
dout_rdreg // running disparity output (reg)
);
parameter RDERR = 1;
parameter KERR = 1;
// method = 0 is generic for comparison / test
// method = 1 is speed optimized
parameter METHOD = 1;
input clk;
input rst;
input din_ena;
input [9:0] din_dat;
input din_rd;
output dout_val;
output[7:0] dout_dat;
output dout_k;
output dout_kerr;
output dout_rderr;
output dout_rdcomb;
output dout_rdreg;
//reg [9:0] din_dat;
reg dout_val;
reg [7:0] dout_dat;
reg dout_k;
reg dout_kerr;
reg dout_rderr;
reg dout_rdreg;
wire a = din_dat[0];
wire b = din_dat[1];
wire c = din_dat[2];
wire d = din_dat[3];
wire e = din_dat[4];
wire i = din_dat[5];
wire f = din_dat[6];
wire g = din_dat[7];
wire h = din_dat[8];
wire j = din_dat[9];
//classification
wire P04 = (!a & !b & !c & !d);
wire P13 = (!a & !b & !c & d) | (!a & !b & c & !d) | (!a & b & !c & !d) | (a & !b & !c & !d);
wire P22 = (!a & !b & c & d) | (!a & b & c & !d) | (a & b & !c & !d) | (a & !b & c & !d) | (a & !b & !c & d) | (!a & b & !c & d);
wire P31 = (a & b & c & !d) | (a & b & !c & d) | (a & !b & c & d) | (!a & b & c & d);
wire P40 = (a & b & c & d);
////////////////////////////////////////////////
// data outputs
////////////////////////////////////////////////
wire A = (P22 & !b & !c & !(e^i)) ? !a :
(P31 & i) ? !a :
(P13 & d & e & i) ? !a :
(P22 & !a & !c & !(e^i)) ? !a :
(P13 & !e) ? !a :
(a & b & e & i) ? !a :
(!c & !d & !e & !i) ? !a :
a;
wire B = (P22 & b & c & !(e^i)) ? !b :
(P31 & i) ? !b :
(P13 & d & e & i) ? !b :
(P22 & a & c & !(e^i)) ? !b :
(P13 & !e) ? !b :
(a & b & e & i) ? !b :
(!c & !d & !e & !i) ? !b :
b;
wire C = (P22 & b & c & !(e^i)) ? !c :
(P31 & i) ? !c :
(P13 & d & e & i) ? !c :
(P22 & !a & !c & !(e^i)) ? !c :
(P13 & !e) ? !c :
(!a & !b & !e & !i) ? !c :
(!c & !d & !e & !i) ? !c :
c;
wire D = (P22 & !b & !c & !(e^i)) ? !d :
(P31 & i) ? !d :
(P13 & d & e & i) ? !d :
(P22 & a & c & !(e^i)) ? !d :
(P13 & !e) ? !d :
(a & b & e & i) ? !d :
(!c & !d & !e & !i) ? !d :
d;
wire E = (P22 & !b & !c & !(e^i)) ? !e :
(P13 & !i) ? !e :
(P13 & d & e & i) ? !e :
(P22 & !a & !c & !(e^i)) ? !e :
(P13 & !e) ? !e :
(!a & !b & !e & !i) ? !e :
(!c & !d & !e & !i) ? !e :
e;
wire F = (f & h & j) ? !f :
(!c & !d & !e & !i & (h^j)) ? !f :
(!f & !g & h & j) ? !f :
(f & g & j) ? !f :
(!f & !g & !h) ? !f :
(g & h & j) ? !f :
f;
wire G = (!f & !h & !j) ? !g :
(!c & !d & !e & !i & (h^j)) ? !g :
(!f & !g & h & j) ? !g :
(f & g & j) ? !g :
(!f & !g & !h) ? !g :
(!g & !h & !j) ? !g :
g;
wire H = (f & h & j) ? !h :
(!c & !d & !e & !i & (h^j)) ? !h :
(!f & !g & h & j) ? !h :
(f & g & j) ? !h :
(!f & !g & !h) ? !h :
(!g & !h & !j) ? !h :
h;
wire K = (c & d & e & i) |
(!c & !d & !e & !i) |
(P13 & !e & i & g & h & j) |
(P31 & e & !i & !g & !h & !j);
////////////////////////////////////////////////
//running disparity - generate and err check
////////////////////////////////////////////////
wire rd1n = (P04) ? 1 :
(P13 & !(e & i)) ? 1 :
(P22 & !e & !i) ? 1 :
(P13 & d & e & i) ? 1 :
0 /* synthesis keep */;
wire rd1p = (P40) ? 1 :
(P31 & !(!e & !i)) ? 1 :
(P22 & e & i) ? 1 :
(P31 & !d & !e & !i) ? 1 :
0 /* synthesis keep */;
wire rd1e = (P13 & !d & e & i) ? 1 :
(P22 & (e ^ i)) ? 1 :
(P31 & d & !e & !i) ? 1 :
0 /* synthesis keep */;
wire rd1_err = (!din_rd & rd1n) | (din_rd & rd1p);
/////////////////////////////
// factored rd1 generation
/////////////////////////////
wire [63:0] rd1_when_din_rd_0_mask = 64'hffe8e880e8808000;
wire rd1_when_din_rd_0 = rd1_when_din_rd_0_mask[din_dat[5:0]] /* synthesis keep */;
wire [63:0] rd1_when_din_rd_1_mask = 64'hfffefee8fee8e800;
wire rd1_when_din_rd_1 = rd1_when_din_rd_1_mask[din_dat[5:0]] /* synthesis keep */;
wire rd1 = din_rd ? rd1_when_din_rd_1 : rd1_when_din_rd_0;
wire rd2n = (!f & !g & !h) ? 1 :
(!f & !g & !j) ? 1 :
(!f & !h & !j) ? 1 :
(!g & !h & !j) ? 1 :
(!f & !g & h & j) ? 1 :
0 /* synthesis keep */;
wire rd2p = (f & g & h) ? 1 :
(f & g & j) ? 1 :
(f & h & j) ? 1 :
(g & h & j) ? 1 :
(f & g & !h & !j) ? 1 :
0 /* synthesis keep */;
wire rd2e = ((f ^ g) & (h ^ j)) ? 1 :
0;
wire rd2_err = (!rd1 & rd2n) | (rd1 & rd2p);
// these two conditions appear in rd2p and rd2n with the
// opposite associated rdcomb output.
wire dout_rdcomb_special = (!f & !g & h & j) |
( f & g & !h & !j) /* synthesis keep */;
wire dout_rdcomb = (rd2p) ? !dout_rdcomb_special :
(rd2n) ? dout_rdcomb_special :
rd1;
////////////////////////////////////////////////
// K error check - this is by far the most
// complex expression in the decoder.
// It appears to require depth 3. Please let
// me know if you identify a depth 2 mapping.
////////////////////////////////////////////////
wire k_err;
generate
if (METHOD == 0) begin
assign k_err = //5b6b errors
(P04) ? 1 :
(P13 & !e & !i) ? 1 :
(P31 & e & i) ? 1 :
(P40) ? 1 :
//3b4b errors
( f & g & h & j) ? 1 :
(!f & !g & !h & !j) ? 1 :
//any 2nd phase rd error, except if rd1 is even
(rd2_err & !rd1e) ? 1 :
// + some odd ones, dx.7 - specials ...
// d11.7,d13.7,d14.7,d17.7,d18.7,d20.7 use 1000/0111
// k23.7,k27.7,k29.7,k30.7 are legal use 1000/0111
// other x.7 use 0001/1110
// P22 & xxxx01 1110 - ok, d12.7
// P22 & xxxx10 1110 - ok, d28.7
// P22 & 011000 1110 - ok, d0.7
// P22 & 101000 1110 - ok, d15.7
// P22 & 100100 1110 - ok, d16.7
// P22 & 001100 1110 - ok, d24.7
// P22 & 010100 1110 - ok, d31.7
// P22 & 110000 1110 - illegal
// xxxx11 1110 - illegal
( a & b & !c & !d & !e & !i & f & g & h & !j) ? 1 :
( e & i & f & g & h & !j) ? 1 :
// P22 & xxxx01 0001 - ok, d6.7
// P31 & xxxx01 0001 - ok, d1.7
// P31 & xxxx10 0001 - ok, d23.7
// P22 & xxxx10 0001 - ok, d19.7
// P13 & xxxx11 0001 - ok, d7.7
// 110011 0001 - ok, d24.7
// 101011 0001 - ok, d31.7
// 011011 0001 - ok, d16.7
// 100111 0001 - ok, d0.7
// 010111 0001 - ok, d15.7
// 001111 0001 - illegal
// xxxx00 0001 - illegal
(!a & !b & c & d & e & i & !f & !g & !h & j) ? 1 :
( !e & !i & !f & !g & !h & j) ? 1 :
// 110000 0111 - ok, k28.7
// P13 & xxxx01 0111 = ok, kxx.7
// 100011 0111 = ok, d17.7
// 010011 0111 = ok, d18.7
// 001011 0111 = ok, d20.7
// 000111 0111 = illegal (rderr)
// else xxxxxx 0111 - illegal
(!(P22 & !c & !d) & !e & !i & !f & g & h & j) ? 1 :
(!(P13) & !e & i & !f & g & h & j) ? 1 :
(!(P13 & (a | b | c)) & e & i & !f & g & h & j) ? 1 :
( e & !i & !f & g & h & j) ? 1 :
// 001111 1000 - ok, k28.7
// P31 & xxxx10 1000 = ok, kxx.7
// 110100 1000 - ok, d11.7
// 101100 1000 - ok, d13.7
// 011100 1000 - ok, d14.7
// 111000 1000 - illegal (rderr)
// else xxxxxx 1000 - illegal
(!(P22 & c & d) & e & i & f & !g & !h & !j) ? 1 :
(!(P31) & e & !i & f & !g & !h & !j) ? 1 :
(!(P31 & (!a | !b | !c)) & !e & !i & f & !g & !h & !j) ? 1 :
( !e & i & f & !g & !h & !j) ? 1 :
0;
end
else if (METHOD == 1) begin
/////////////////////////////////////
// use the upper and lower portions only
// to identify definite errors
/////////////////////////////////////
wire [63:0] kerr_mask_ai = 64'h6881800180018117;
wire [63:0] kerr_mask_ej = 64'hf20000018000004f;
wire kerr_out_ai = kerr_mask_ai[din_dat[5:0]] /* synthesis keep */;
wire kerr_out_ej = kerr_mask_ej[din_dat[9:4]] /* synthesis keep */;
wire rd2_err_lc = rd2_err /* synthesis keep */;
wire kerr6,kerr7,kerr8,kerr9,kerr_remainder;
stratixii_lcell_comb kerr6_I (
.datab(!din_dat[7]),
.datac(!din_dat[6]),
.datad(!din_dat[8]),
.datae(!din_dat[9]),
.dataa(1'b1),.dataf(1'b1),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(kerr6 ));
defparam kerr6_I .shared_arith = "off";
defparam kerr6_I .extended_lut = "off";
defparam kerr6_I .lut_mask = 64'h0C0000300C000030;
stratixii_lcell_comb kerr7_I (
.dataa(!din_dat[3]),
.datab(!din_dat[7]),
.datac(!din_dat[6]),
.datad(!din_dat[8]),
.datae(!din_dat[9]),
.dataf(1'b1),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(kerr7 ));
defparam kerr7_I .shared_arith = "off";
defparam kerr7_I .extended_lut = "off";
defparam kerr7_I .lut_mask = 64'h0002403000024030;
stratixii_lcell_comb kerr8_I (
.dataa(!din_dat[0]),
.datab(!din_dat[1]),
.datac(!din_dat[2]),
.datad(!din_dat[4]),
.datae(!din_dat[3]),
.dataf(1'b1),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(kerr8 ));
defparam kerr8_I .shared_arith = "off";
defparam kerr8_I .extended_lut = "off";
defparam kerr8_I .lut_mask = 64'h6868960868689608;
stratixii_lcell_comb kerr9_I (
.dataa(!din_dat[0]),
.datab(!din_dat[1]),
.datac(!din_dat[2]),
.datad(!din_dat[4]),
.datae(!din_dat[3]),
.dataf(1'b1),.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(kerr9 ));
defparam kerr9_I .shared_arith = "off";
defparam kerr9_I .extended_lut = "off";
defparam kerr9_I .lut_mask = 64'h1001161E1001161E;
stratixii_lcell_comb kerr_rem_I (
.dataa(!din_dat[5]),
.datab(!kerr6 ),
.datac(!kerr7 ),
.datad(!din_dat[4]),
.datae(!kerr8 ),
.dataf(!kerr9 ),
.datag(1'b1),
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
.combout(kerr_remainder ));
defparam kerr_rem_I .shared_arith = "off";
defparam kerr_rem_I .extended_lut = "off";
defparam kerr_rem_I .lut_mask = 64'h2331223029110325;
assign k_err = kerr_out_ai | kerr_out_ej |
rd2_err_lc & !rd1e |
kerr_remainder;
end
endgenerate
////////////////////////////////////////////////
// output registers
////////////////////////////////////////////////
always @(posedge clk or posedge rst)
begin
if (rst)
begin
dout_k <= 0;
dout_val <= 0;
dout_dat <= 0;
dout_rdreg <= 0;
dout_rderr <= 0;
dout_kerr <= 0;
end
else
begin
dout_val <= 0;
if (din_ena)
begin
dout_k <= K;
dout_val <= din_ena;
dout_dat <= {H,G,F,E,D,C,B,A};
dout_rdreg <= dout_rdcomb;
dout_rderr <= (RDERR) ? (rd1_err | rd2_err) : 0;
dout_kerr <= (KERR) ? k_err : 0;
end
end
end
endmodule