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

📄 reed_sol.cpp

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