📄 reed_sol.cpp
字号:
{
signal_use[j] = 0;
}
for (j=0;j<symbol_size*symbol_size;j++)
{
if (helper_bin[helper_bins_used][j])
{
signal_use [j%symbol_size] = 1;
signal_use [j/symbol_size+symbol_size] = 1;
}
if (helper_bin[h][j])
{
signal_use [j%symbol_size] = 1;
signal_use [j/symbol_size+symbol_size] = 1;
}
}
// count total signal use on the merge candidate
q = 0;
for (j=0;j<symbol_size*2;j++)
{
if (signal_use[j]) q++;
}
if (q <= lut_size)
{
// accept the merge - add some terms to helper H
for (j=0;j<symbol_size*symbol_size;j++)
{
if (helper_bin[helper_bins_used][j])
{
helper_bin[h][j] = true;
}
}
resolved = true;
}
else
{
// these two helpers won't fit together
}
}
// if unable to merge then take a new helper slot
if (!resolved)
{
helper_bins_used++;
}
}
// spit out the helpers
for (h=0; h<helper_bins_used; h++)
{
fprintf (stdout," wire o%d_helper%d = ",i,h);
first = true;
for (j=0;j<symbol_size*symbol_size;j++)
{
if (helper_bin[h][j])
{
if (!first) fprintf (stdout," ^");
first = false;
fprintf (stdout,"\n");
fprintf (stdout," and_terms[%d] /* B[%d] A[%d] */",
j,j/symbol_size,j%symbol_size);
}
}
fprintf (stdout," /* synthesis keep */;\n\n");
}
// output is the xor of the helpers
fprintf (stdout," assign o[%d] = \n",i);
for (h=0; h<helper_bins_used; h++)
{
if (h != 0) fprintf (stdout," ^\n");
fprintf (stdout," o%d_helper%d",i,h);
}
fprintf (stdout,";\n\n");
}
fprintf (stdout," end\n");
fprintf (stdout,"endgenerate\n");
fprintf (stdout,"endmodule\n\n");
}
///////////////////////////////////////////
void build_gf_inverse (
int symbol_size,
int mod_poly
)
{
int n = (1 << symbol_size) - 1;
int alpha [MAX_SIZE];
int i,j;
// build up the values of alpha^(i) mod poly
alpha[0] = 1;
for (i=1; i<=n; i++)
{
alpha[i] = gf_mult (symbol_size,alpha[i-1],2,mod_poly);
}
fprintf (stdout,"\n///////////////////////////////////////////\n\n");
fprintf (stdout,"module gf_inverse (i,o);\n");
fprintf (stdout,"input [%d:0] i;\n",symbol_size-1);
fprintf (stdout,"output [%d:0] o;\n",symbol_size-1);
fprintf (stdout,"reg [%d:0] o /* synthesis keep */;\n",symbol_size-1);
fprintf (stdout," always @(i) begin\n");
fprintf (stdout," case (i)\n");
fprintf (stdout," %d'h0: o=%d'h0;\n",symbol_size,symbol_size);
for (i=0; i<n; i++)
{
fprintf (stdout," %d'h%x: o=%d'h%x;\n",symbol_size,
alpha[i],symbol_size,alpha[(n-i)%n]);
}
fprintf (stdout," endcase\n");
fprintf (stdout," end\n");
fprintf (stdout,"endmodule\n\n");
}
///////////////////////////////////////////
void build_gf_divide (
int symbol_size
)
{
fprintf (stdout,"\n///////////////////////////////////////////\n\n");
fprintf (stdout,"module gf_divide (n,d,o);\n");
fprintf (stdout,"input [%d:0] n;\n",symbol_size-1);
fprintf (stdout,"input [%d:0] d;\n",symbol_size-1);
fprintf (stdout,"output [%d:0] o;\n",symbol_size-1);
fprintf (stdout,"wire [%d:0] o;\n\n",symbol_size-1);
fprintf (stdout,"wire [%d:0] d_inv;\n",symbol_size-1);
fprintf (stdout,"gf_inverse divi (.i(d),.o(d_inv));\n");
fprintf (stdout,"gf_mult divm (.a(n),.b(d_inv),.o(o));\n\n");
fprintf (stdout,"endmodule\n\n");
}
///////////////////////////////////////////
void build_gf_math_tb (
int symbol_size
)
{
fprintf (stdout,"\n//////////////////////////////////////////\n");
fprintf (stdout,"// GF mult / div correctness testbench \n");
fprintf (stdout,"//////////////////////////////////////////\n\n");
fprintf (stdout,"module gf_math_tb();\n");
fprintf (stdout,"reg fail = 1'b0;\n");
fprintf (stdout,"reg [%d:0] a,b;\n",symbol_size-1);
fprintf (stdout,"wire [%d:0] om0,om1,om2,om3,om4,om5,om6,oi0,oi1;\n\n",symbol_size-1);
fprintf (stdout,"// multipliers - (all equivalent)\n");
fprintf (stdout,"gf_mult m0 (.a(a),.b(b),.o(om0));\n");
fprintf (stdout,"gf_mult m1 (.a(a),.b(b),.o(om1));\n");
fprintf (stdout,"gf_mult m2 (.a(b),.b(a),.o(om2));\n");
fprintf (stdout,"gf_mult m3 (.a(b),.b(a),.o(om3));\n");
fprintf (stdout,"gf_mult m6 (.a(a),.b(b),.o(om6));\n");
fprintf (stdout,"defparam m0 .METHOD = 0;\n");
fprintf (stdout,"defparam m1 .METHOD = 1;\n");
fprintf (stdout,"defparam m2 .METHOD = 0;\n");
fprintf (stdout,"defparam m3 .METHOD = 1;\n");
fprintf (stdout,"defparam m6 .METHOD = 2;\n\n");
fprintf (stdout,"// mult. inverse\n");
fprintf (stdout,"gf_inverse i0 (.i(a),.o(oi0));\n");
fprintf (stdout,"gf_inverse i1 (.i(b),.o(oi1));\n\n");
fprintf (stdout,"// pseudo divide\n");
fprintf (stdout,"gf_mult m4 (.a(om0),.b(oi0),.o(om4));\n");
fprintf (stdout,"defparam m4 .METHOD = 0;\n");
fprintf (stdout,"gf_mult m5 (.a(om0),.b(oi1),.o(om5));\n");
fprintf (stdout,"defparam m5 .METHOD = 0;\n\n");
fprintf (stdout,"// verify\n");
fprintf (stdout,"always begin\n");
fprintf (stdout," #10\n");
fprintf (stdout," a = $random;\n");
fprintf (stdout," b = $random;\n");
fprintf (stdout," #10\n");
fprintf (stdout," if (om0 !== om1) fail = 1;\n");
fprintf (stdout," if (om0 !== om2) fail = 1;\n");
fprintf (stdout," if (om0 !== om3) fail = 1;\n");
fprintf (stdout," if (om0 !== om6) fail = 1;\n");
fprintf (stdout," if (om4 !== b && a !== 0) fail = 1;\n");
fprintf (stdout," if (om5 !== a && b !== 0) fail = 1;\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"initial begin\n");
fprintf (stdout," #1000000 if (!fail) begin\n");
fprintf (stdout," $display (\"PASS\");\n");
fprintf (stdout," $stop();\n");
fprintf (stdout," end\n");
fprintf (stdout," else begin\n");
fprintf (stdout," $display (\"FAIL\");\n");
fprintf (stdout," $stop();\n");
fprintf (stdout," end\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"endmodule\n\n");
}
///////////////////////////////////////////
void build_encoder (
int symbol_size,
int data_symbols,
int mod_poly
)
{
int n = (1 << symbol_size) - 1;
int k = data_symbols;
int t = (n - k) / 2;
int alpha [MAX_SIZE];
int g [MAX_SIZE];
int i,j;
int const b = 0;
bool found = false;
fprintf (stdout,"// Reed Solomon\n");
fprintf (stdout,"// N = %d (symbols per code word)\n",n);
fprintf (stdout,"// K = %d (data symbols)\n",k);
fprintf (stdout,"// t = %d (# of errors corrected)\n",t);
fprintf (stdout,"// 2t = %d (# of check symbols)\n",2*t);
fprintf (stdout,"// m = %d (bits per symbol)\n\n",symbol_size);
// build up the values of alpha^(i) mod poly
alpha[0] = 1;
for (i=1; i<=n; i++)
{
alpha[i] = gf_mult (symbol_size,alpha[i-1],2,mod_poly);
}
fprintf (stdout,"\n");
for (i=0; i<=n; i++)
{
fprintf (stdout,"// alpha ^ %d = %02x\n",i,alpha[i]);
}
// build up the generator poly - product of alphas 1..2*t
for (i=0; i<(n-k+1); i++)
{
g[i] = 0;
}
g[0] = 1;
for (i=1; i<(n-k+1); i++)
{
for (j=n-k; j>0; j--)
{
g[j] = gf_mult (symbol_size,g[j],alpha[i-1+b],mod_poly) ^
g[j-1];
}
g[0] = gf_mult (symbol_size,g[0],alpha[i-1+b],mod_poly);
}
fprintf (stdout,"\n");
for (i=0; i<(n-k+1); i++)
{
fprintf (stdout,"// gen_poly [%d] = %02x\n",i,g[i]);
}
fprintf (stdout,"\n");
// build a full rack of GF constant multipliers
for (i=1; i<=n; i++)
{
build_gf_const_mult (symbol_size,i,mod_poly);
}
fprintf (stdout,"\n///////////////////////////////////////////\n\n");
// main encoder
fprintf (stdout,"// first din zeros the accumulator on the first data symbol\n");
fprintf (stdout,"// shift is for reading out the parity register, overrides\n");
fprintf (stdout,"// the first_din signal\n");
fprintf (stdout,"module encoder (clk,rst,shift,ena,first_din,din,parity);\n");
fprintf (stdout,"input clk,rst,shift,ena,first_din;\n");
fprintf (stdout,"input [%d:0] din;\n",symbol_size-1);
fprintf (stdout,"output [%d:0] parity;\n",t*2*symbol_size-1);
fprintf (stdout,"reg [%d:0] parity;\n\n",t*2*symbol_size-1);
fprintf (stdout," wire [%d:0] feedback;\n",symbol_size-1);
fprintf (stdout," assign feedback = din ^ (first_din ? %d'b0 : parity[%d:%d]);\n\n",
symbol_size,
t*2*symbol_size-1,
t*2*symbol_size-symbol_size);
fprintf (stdout," wire [%d:0] gen_fn;\n",t*2*symbol_size-1);
for (i=0; i<(n-k); i++)
{
fprintf (stdout," gf_mult_by_%02x m%d (.i(feedback),.o(gen_fn[%d:%d]));\n"
,g[i],i,(i+1)*symbol_size-1,i*symbol_size);
}
fprintf (stdout,"\n");
fprintf (stdout," always @(posedge clk or posedge rst) begin\n");
fprintf (stdout," if (rst) begin\n");
fprintf (stdout," parity <= 0;\n");
fprintf (stdout," end\n");
fprintf (stdout," else if (ena) begin\n");
fprintf (stdout," parity <= ((!shift & first_din) ? %d'b0 : (parity << %d)) ^\n",
t*2*symbol_size,symbol_size);
fprintf (stdout," (shift ? %d'b0 : gen_fn);\n",
t*2*symbol_size,symbol_size);
fprintf (stdout," end\n");
fprintf (stdout," end\n");
fprintf (stdout,"endmodule\n\n");
}
///////////////////////////////////////////
void build_syndrome_flat (
int symbol_size,
int data_symbols,
int mod_poly
)
{
int n = (1 << symbol_size) - 1;
int k = data_symbols;
int t = (n - k) / 2;
int alpha [MAX_SIZE];
int const b = 0;
int i,j;
int mult_num = 0;
fprintf (stdout,"\n///////////////////////////////////////////\n\n");
// build up the values of alpha^(i) mod poly
alpha[0] = 1;
for (i=1; i<=n; i++)
{
alpha[i] = gf_mult (symbol_size,alpha[i-1],2,mod_poly);
}
fprintf (stdout,"// No latency syndrome computation\n");
fprintf (stdout,"module syndrome_flat (rx_data,syndrome);\n");
fprintf (stdout,"input [%d:0] rx_data;\n",n * symbol_size-1);
fprintf (stdout,"output [%d:0] syndrome;\n",2*t*symbol_size-1);
fprintf (stdout,"wire [%d:0] syndrome;\n\n",2*t*symbol_size-1);
for (i=0; i<2*t; i=i+1)
{
fprintf (stdout,"\n// syndrome %d\n",i);
fprintf (stdout," wire [%d:0] syn_%d_tmp;\n",n*symbol_size-1,i);
for (j=0; j<n; j=j+1)
{
fprintf (stdout," gf_mult_by_%02x m%d (.i(rx_data[%d:%d]),.o(syn_%d_tmp[%d:%d]));\n"
,alpha[((i+b)*j)%n],
mult_num,
(j+1)*symbol_size-1,j*symbol_size,
i,
(j+1)*symbol_size-1,j*symbol_size);
mult_num++;
}
fprintf (stdout," assign syndrome[%d:%d] =",(i+1)*symbol_size-1,i*symbol_size);
for (j=0; j<n; j=j+1)
{
if ((j % 3) == 0) fprintf (stdout,"\n ");
fprintf (stdout,"syn_%d_tmp[%d:%d]",i,(j+1)*symbol_size-1,j*symbol_size);
if (j != n-1) fprintf (stdout," ^ ");
}
fprintf (stdout,";\n");
}
fprintf (stdout,"\nendmodule\n\n");
}
///////////////////////////////////////////
void build_syndrome_round (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -