⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reed_sol.cpp

📁 本電子檔為 verilog cookbook,包含了通訊,影像,DSP等重要常用之verilog編碼,可作為工程師與初學者的參考手冊
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				{
					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 + -