📄 reed_sol.cpp
字号:
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,"// 1 cycle per data symbol syndrome computation\n");
fprintf (stdout,"// on the last cycle skip the mult, just XOR\n");
fprintf (stdout,"module syndrome_round (rx_data,syndrome_in,syndrome_out,skip_mult);\n");
fprintf (stdout,"input [%d:0] rx_data;\n",symbol_size-1);
fprintf (stdout,"input [%d:0] syndrome_in;\n",2*t*symbol_size-1);
fprintf (stdout,"input skip_mult;\n");
fprintf (stdout,"output [%d:0] syndrome_out;\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_in;\n",symbol_size-1,i);
fprintf (stdout," wire [%d:0] syn_%d_mult;\n",symbol_size-1,i);
fprintf (stdout," assign syn_%d_in = rx_data ^ syndrome_in[%d:%d];\n",
i,(i+1)*symbol_size-1,i*symbol_size);
fprintf (stdout," gf_mult_by_%02x sm%d (.i(syn_%d_in),.o(syn_%d_mult));\n",
alpha[i],
i,i,i);
fprintf (stdout," assign syndrome_out [%d:%d] = (skip_mult ? \n",
(i+1)*symbol_size-1,i*symbol_size);
fprintf (stdout," syn_%d_in : syn_%d_mult);\n",i,i);
fprintf (stdout,"\n");
}
fprintf (stdout,"\nendmodule\n\n");
}
///////////////////////////////////////////
void build_syndrome_tb (
int symbol_size,
int data_symbols
)
{
int n = (1 << symbol_size) - 1;
int k = data_symbols;
int t = (n - k) / 2;
int i = 0;
fprintf (stdout,"\n///////////////////////////////////////////\n\n");
fprintf (stdout,"// PROBLEM - the iterative unit isn't exercised well\n");
fprintf (stdout,"module syndrome_tb ();\n");
fprintf (stdout,"reg [%d:0] din;\n",symbol_size-1);
fprintf (stdout,"reg clk,clk_ena,tx_ena,rst,first_din;\n");
fprintf (stdout,"wire [%d:0] parity;\n",symbol_size*2*t-1);
fprintf (stdout,"reg [%d:0] tx_buffer;\n",k*symbol_size-1);
fprintf (stdout,"wire [%d:0] tx_data = {tx_buffer,parity};\n",n*symbol_size-1);
fprintf (stdout,"reg [%d:0] err;\n",n*symbol_size-1);
fprintf (stdout,"wire [%d:0] rx_data = tx_data ^ err;\n",n*symbol_size-1);
fprintf (stdout,"wire [%d:0] syndrome;\n",symbol_size*2*t-1);
fprintf (stdout,"reg [%d:0] syndrome_reg;\n",symbol_size*2*t-1);
fprintf (stdout,"wire [%d:0] next_syndrome_reg;\n\n",symbol_size*2*t-1);
fprintf (stdout,"// iterative encoder\n");
fprintf (stdout,"encoder enc (.clk(clk & tx_ena),.ena(1'b1),.shift(1'b0),.rst(rst),.first_din(first_din),.din(din),.parity(parity));\n\n");
fprintf (stdout,"// flat and iterative syndrome generators\n");
fprintf (stdout,"reg [%d:0] par;\n",symbol_size-1);
fprintf (stdout,"reg sending_data;\n");
fprintf (stdout,"syndrome_flat syn_f (.rx_data(rx_data),.syndrome(syndrome));\n");
fprintf (stdout,"syndrome_round syn_r (.rx_data(sending_data ? din : par),.syndrome_in(syndrome_reg),");
fprintf (stdout," .syndrome_out(next_syndrome_reg),.skip_mult(1'b0));\n\n");
fprintf (stdout,"initial begin\n");
fprintf (stdout," clk = 0;\n");
fprintf (stdout," rst = 0;\n");
fprintf (stdout," tx_ena = 1'b1;\n");
fprintf (stdout," clk_ena = 1'b1;\n");
fprintf (stdout," sending_data = 1'b1;\n");
fprintf (stdout," first_din = 1'b1;\n");
fprintf (stdout," #10 rst = 1;\n");
fprintf (stdout," #10 rst = 0;\n");
fprintf (stdout," @(posedge clk) syndrome_reg <= 0; // cheating\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"always begin\n");
fprintf (stdout," #100 if (clk_ena) clk = ~clk;\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"always @(negedge clk) begin\n");
fprintf (stdout," din <= $random;\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"always @(posedge clk) begin\n");
fprintf (stdout," if (tx_ena) tx_buffer <= (tx_buffer << %d) | din;\n",symbol_size);
fprintf (stdout,"end\n\n");
fprintf (stdout,"always @(posedge clk or posedge rst) begin\n");
fprintf (stdout," if (rst) syndrome_reg <= 0;\n");
fprintf (stdout," else syndrome_reg <= next_syndrome_reg;\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"integer i;\n");
fprintf (stdout,"initial begin\n\n");
fprintf (stdout," // start the TX of a new word\n");
fprintf (stdout," #100\n");
fprintf (stdout," @(negedge clk);\n");
fprintf (stdout," err = 0;\n");
fprintf (stdout," first_din = 1'b1;\n");
fprintf (stdout," @(posedge clk);\n");
fprintf (stdout," @(negedge clk);\n");
fprintf (stdout," first_din = 1'b0;\n");
fprintf (stdout," for (i=0; i<%d; i=i+1) begin\n",k-1);
fprintf (stdout," @(posedge clk);\n");
fprintf (stdout," @(negedge clk);\n");
fprintf (stdout," end\n\n");
fprintf (stdout," // stop the TX, RX gets more cycle of data..\n");
fprintf (stdout," tx_ena = 1'b0;\n");
fprintf (stdout," sending_data = 1'b0;\n");
fprintf (stdout," // give the RX the rest of the parity symbols..\n");
for (i=0; i<2*t;i=i+1)
{
fprintf (stdout," par = parity [%d:%d];\n",
2*t*symbol_size-1-i*symbol_size,
2*t*symbol_size-1-i*symbol_size-(symbol_size-1));
fprintf (stdout," @(posedge clk);\n");
fprintf (stdout," @(negedge clk);\n");
}
fprintf (stdout," clk_ena = 1'b0;\n");
fprintf (stdout,"\n");
fprintf (stdout," // Check the syndromes of the uncorrupted data\n");
fprintf (stdout," $display (\"tx data %%x\",tx_data);\n");
fprintf (stdout," $display (\" pure rx data %%x\",rx_data);\n");
fprintf (stdout," $display (\" flat syndrome %%x\",syndrome);\n");
fprintf (stdout," if (syndrome !== 0) begin\n");
fprintf (stdout," $display (\"Error : correct code has a non-zero syndrome\");\n");
fprintf (stdout," $stop();\n");
fprintf (stdout," end\n");
fprintf (stdout," $display (\" round syndrome %%x\",syndrome_reg);\n");
fprintf (stdout," if (syndrome_reg !== 0) begin\n");
fprintf (stdout," $display (\"Error : correct code has a non-zero syndrome\");\n");
fprintf (stdout," $stop();\n");
fprintf (stdout," end\n");
fprintf (stdout,"\n");
fprintf (stdout," // Corrupt, and make sure it gets detected\n");
fprintf (stdout," #10 err = 1'b1;\n");
fprintf (stdout," for (i=0; i<%d; i=i+1) begin\n",n*symbol_size);
fprintf (stdout," #10\n");
fprintf (stdout," $display (\" corrupted rx data %%x\",rx_data);\n");
fprintf (stdout," $display (\" syndrome %%x\",syndrome);\n");
fprintf (stdout," if (syndrome == 0) begin\n");
fprintf (stdout," $display (\"Error : incorrect code has zero syndrome\");\n");
fprintf (stdout," $stop();\n");
fprintf (stdout," end\n");
fprintf (stdout," err = err << 1;\n");
fprintf (stdout," end\n");
fprintf (stdout," $display (\"PASS\");\n");
fprintf (stdout," $stop();\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"endmodule\n");
}
///////////////////////////////////////////
int log_2 (int n)
{
int lg = 0;
while (n!=0)
{
n >>= 1;
lg++;
}
return (lg);
}
///////////////////////////////////////////
void build_error_loc_poly (
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 i = 0;
int mult_num = 0;
fprintf (stdout,"\n///////////////////////////////////////////\n");
fprintf (stdout,"// Error Location poly computation\n");
fprintf (stdout,"// 1 tick per round version\n");
fprintf (stdout,"///////////////////////////////////////////\n\n");
fprintf (stdout,"// initial ELP_in is 1 at word 0 (meaning 1)\n");
fprintf (stdout,"// initial correction is 1 at word 1 (meaning x)\n");
fprintf (stdout,"// step = 1..2t\n");
fprintf (stdout,"// This is using the Berlekamp method\n");
fprintf (stdout,"module error_loc_poly_round (step,order_in,order_out,elp_in,elp_out,step_syndrome,\n");
fprintf (stdout," correction_in,correction_out);\n");
fprintf (stdout,"input [%d:0] step;\n",log_2(2*t)-1);
fprintf (stdout,"input [%d:0] order_in;\n",log_2(2*t-1)-1);
fprintf (stdout,"output [%d:0] order_out;\n",log_2(2*t-1)-1);
fprintf (stdout,"input [%d:0] elp_in;\n",symbol_size*2*t-1);
fprintf (stdout,"output [%d:0] elp_out;\n",symbol_size*2*t-1);
fprintf (stdout,"input [%d:0] step_syndrome;\n",symbol_size*2*t-1);
fprintf (stdout,"input [%d:0] correction_in;\n",symbol_size*2*t-1);
fprintf (stdout,"output [%d:0] correction_out;\n\n",symbol_size*2*t-1);
fprintf (stdout,"reg [%d:0] order_out;\n",log_2(2*t-1)-1);
fprintf (stdout,"reg [%d:0] correction_out;\n\n",symbol_size*2*t-1);
fprintf (stdout,"wire [%d:0] discrepancy;\n\n",symbol_size-1);
fprintf (stdout,"wire [%d:0] disc_mult;\n",symbol_size*2*t-1);
for (i=0; i<2*t; i=i+1)
{
fprintf (stdout,"gf_mult m%d (.a(elp_in[%d:%d]),.b(step_syndrome[%d:%d]),.o(disc_mult[%d:%d]));\n",
mult_num,
(i+1)*symbol_size-1,i*symbol_size,
(i+1)*symbol_size-1,i*symbol_size,
(i+1)*symbol_size-1,i*symbol_size
);
mult_num++;
}
fprintf (stdout,"\nassign discrepancy = \n");
for (i=0; i<2*t; i=i+1)
{
fprintf (stdout," disc_mult [%d:%d]",
(i+1)*symbol_size-1,i*symbol_size);
if (i != 2*t-1)
{
fprintf (stdout," ^");
}
fprintf (stdout,"\n");
}
fprintf (stdout,";\n\n");
fprintf (stdout,"wire [%d:0] disc_mult_correction;\n",symbol_size*2*t-1);
for (i=0; i<2*t; i=i+1)
{
fprintf (stdout,"gf_mult m%d (.a(discrepancy),"
".b(correction_in[%d:%d]),.o(disc_mult_correction[%d:%d]));\n",
mult_num,
(i+1)*symbol_size-1,i*symbol_size,
(i+1)*symbol_size-1,i*symbol_size
);
mult_num++;
}
fprintf (stdout,"\nassign elp_out = elp_in ^ disc_mult_correction;\n\n");
fprintf (stdout,"// build the elp divided by the discrepancy\n");
fprintf (stdout,"// by inverse then multiply...\n");
fprintf (stdout,"wire [%d:0] inv_discrepancy;\n",symbol_size-1);
fprintf (stdout,"gf_inverse id (.i(discrepancy),.o(inv_discrepancy));\n\n");
fprintf (stdout,"wire [%d:0] elp_div_disc;\n",symbol_size*2*t-1);
for (i=0; i<2*t; i=i+1)
{
fprintf (stdout,"gf_mult d%d (.a(elp_in[%d:%d]),"
".b(inv_discrepancy),.o(elp_div_disc[%d:%d]));\n",
mult_num,
(i+1)*symbol_size-1,i*symbol_size,
(i+1)*symbol_size-1,i*symbol_size
);
mult_num++;
}
fprintf (stdout,"\n");
fprintf (stdout,"// update the order and correction poly\n");
fprintf (stdout,"always @(*) begin\n");
fprintf (stdout," if ((|discrepancy) && ((order_in << 1) < step)) begin\n");
fprintf (stdout," order_out = step - order_in;\n");
fprintf (stdout," correction_out = {elp_div_disc[%d:%d],%d'b0};\n",
symbol_size*2*t-1-symbol_size,
0,
symbol_size);
fprintf (stdout," end\n");
fprintf (stdout," else begin\n");
fprintf (stdout," order_out = order_in;\n");
fprintf (stdout," correction_out = {correction_in[%d:%d],%d'b0} ;\n",
symbol_size*2*t-1-symbol_size,
0,
symbol_size);
fprintf (stdout," end\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"endmodule\n");
}
///////////////////////////////////////////
void build_error_loc_poly_multi_step (
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 i = 0;
int mult_num = 0;
fprintf (stdout,"\n/////////////////////////////////////////////////\n");
fprintf (stdout,"// Error Location poly computation\n");
fprintf (stdout,"// Multiple ticks per round version\n");
fprintf (stdout,"///////////////////////////////////////////////////\n\n");
fprintf (stdout,"// initial ELP_in is 1 at word 0 (meaning 1)\n");
fprintf (stdout,"// initial correction is 1 at word 1 (meaning x)\n");
fprintf (stdout,"// step = 1..2t\n");
fprintf (stdout,"// This is using the Berlekamp method\n");
fprintf (stdout,"module error_loc_poly_round_multi_step (step,order_in,order_out,elp_in,elp_out,step_syndrome,\n");
fprintf (stdout," correction_in,correction_out,clk,rst,sync,elpr_wait);\n");
fprintf (stdout,"input [%d:0] step;\n",log_2(2*t)-1);
fprintf (stdout,"input [%d:0] order_in;\n",log_2(2*t-1)-1);
fprintf (stdout,"output [%d:0] order_out;\n",log_2(2*t-1)-1);
fprintf (stdout,"input [%d:0] elp_in;\n",symbol_size*2*t-1);
fprintf (stdout,"output [%d:0] elp_out;\n",symbol_size*2*t-1);
fprintf (stdout,"input [%d:0] step_syndrome;\n",symbol_size*2*t-1);
fprintf (stdout,"input [%d:0] correction_in;\n",symbol_size*2*t-1);
fprintf (stdout,"output [%d:0] correction_out;\n\n",symbol_size*2*t-1);
fprintf (stdout,"input clk,rst,sync;\n");
fprintf (stdout,"output elpr_wait;\n\n");
fprintf (stdout,"reg [%d:0] order_out;\n",log_2(2*t-1)-1);
fprintf (stdout,"reg [%d:0] correction_out;\n\n",symbol_size*2*t-1);
fprintf (stdout,"wire [%d:0] discrepancy;\n\n",symbol_size-1);
fprintf (stdout,"// state 0 : (upper) discrepancy_reg <= ^ (elp_in * step_syn)\n");
fprintf (stdout,"// state 1 : (lower) discrepancy_reg <= ^ (elp_in * step_syn)\n");
fprintf (stdout,"// state 2 : (upper) disc_cor_reg <= (dicrepancy_reg * correction)\n");
fprintf (stdout,"// state 3 : (lower) disc_cor_reg <= (dicrepancy_reg * correction)\n");
fprintf (stdout,"// state 4 : (upper) elp_div_disc_reg <= elp_in * inverse discrepancy\n");
fprintf (stdout,"// state 5 : (lower) elp_div_disc_reg <= elp_in * inverse discrepancy\n");
fprintf (stdout,"// state 6 : settling time\n");
fprintf (stdout,"reg [6:0] wait_state;\n\n");
fprintf (stdout,"always @(posedge clk or posedge rst) begin\n");
fprintf (stdout," if (rst) wait_state <= 7'b1;\n");
fprintf (stdout," else begin\n");
fprintf (stdout," if (sync) wait_state <= 7'b000001;\n");
fprintf (stdout," else wait_state <= {wait_state[5:0],wait_state[6]};\n");
fprintf (stdout," end\n");
fprintf (stdout,"end\n\n");
fprintf (stdout,"assign elpr_wait = !wait_state[6];\n\n");
fprintf (stdout,"wire [%d:0] mult_in_a, mult_in_b, mult_o, disc_inv_repeat;\n",symbol_size*t-1);
fprintf (stdout,"wire [%d:0] disc_inv_mux;\n",symbol_size-1);
fprintf (stdout,"assign disc_inv_repeat = {%d{disc_inv_mux}};\n\n",t);
fprintf (stdout,"// multi purpose Galois mult (half size)\n");
//printf (stdout,"assign mult_in_a = ((wait_state[0] || wait_state[1] || wait_state[4] || wait_state[5]) ? elp_in : correction_in);\n");
//printf (stdout,"assign mult_in_b = ((wait_state[0] || wait_state[1]) ? step_syndrome : disc_inv_repeat);\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -