OpenCores
URL https://opencores.org/ocsvn/bch_configurable/bch_configurable/trunk

Subversion Repositories bch_configurable

[/] [bch_configurable/] [trunk/] [src/] [test_correct.v] - Rev 2

Compare with Previous | Blame | View Log

///-----------------------------------------
///introduce:
///bch correct in decoder
///author:jiml
///record:
///2015.3.15    initial
///-----------------------------------------
`timescale 1ns/100ps
module test_correct
#(
parameter C_INPUT_NUM = 128,          //length of input bit 
parameter C_DWIDTH = 16,              //input data width
parameter C_ECCWIDTH = 16             //check data width
)
(
input                     I_clk        ,
input                     I_rst        ,
input [C_DWIDTH-1:0]      I_data       ,  //input data
input                     I_data_sof   ,  //input data frame start
input                     I_data_eof   ,  //input data frame end
input                     I_data_v     ,  //input data available
input [C_ECCWIDTH-1:0]    I_ecc        ,  //check data
input                     I_ecc_v      ,  //check data available
input                     I_ecc_sof    ,  //check data frame start
input                     I_ecc_eof    ,  //check data frame end
output reg [C_DWIDTH-1:0] O_data       ,  //corrected data
output reg                O_data_v     ,  //corrected data available
output reg                O_data_sof   ,  //corrected data frame start
output reg                O_data_eof      //corrected data frame end
);
 
//----------------------------------------
//parameter and variable
//----------------------------------------
localparam C_OVERFLOW_THRESHOLD = C_DWIDTH-C_ECCWIDTH+1;
localparam C_DIF = C_DWIDTH - C_ECCWIDTH;
localparam C_SLR_CNT_WIDTH = GETASIZE(C_DWIDTH)+1;
localparam C_CHIP_NUM = C_INPUT_NUM/C_DWIDTH;
localparam C_CHIP_NUM_WIDTH = GETASIZE(C_CHIP_NUM);
 
reg [2*C_DWIDTH-1:0] S_data_slr = 0;
reg [C_SLR_CNT_WIDTH-1:0] S_slr_cnt = 0;
reg S_ov_id = 0;
reg [C_DWIDTH-1:0] S_data_tran = 0;
reg S_ecc_eof = 0;
reg S_ecc_eof_d = 0;
reg S_ecc_v = 0;
reg [C_ECCWIDTH-1:0] S_ecc = 0;
reg S_data_tran_v = 0;
reg [C_DWIDTH-1:0] S_ecc_ram [2**C_CHIP_NUM_WIDTH-1:0];
reg [C_DWIDTH-1:0] S_data_ram [2**C_CHIP_NUM_WIDTH-1:0];
reg [C_CHIP_NUM_WIDTH-1:0] S_ecc_waddr = 0;
reg [C_CHIP_NUM_WIDTH:0] S_data_waddr = 0;
reg [C_CHIP_NUM_WIDTH-1:0] S_ecc_raddr = 0;
reg S_ecc_r = 0;
reg [C_DWIDTH-1:0] S_ecc_dout;
reg [C_DWIDTH-1:0] S_dataout;
reg S_ecc_r_d = 0;
reg S_data_eof = 0; 
//-------------------------------------------
//function
//-------------------------------------------
//width calculation
function integer GETASIZE;
input integer a;
integer i;
begin
    for(i=1;(2**i)<=a;i=i+1)
      begin
      end
    GETASIZE = i;
end
endfunction
 
//big endian change to little endian
function [C_DWIDTH-1:0] F_data_inv;
input [C_DWIDTH-1:0] S_datain;
integer i;
begin
    for(i=0;i<C_DWIDTH;i=i+1)
		F_data_inv[i] = S_datain[C_DWIDTH-1-i];
end
endfunction
 
//-----------------------------------------
//check data alignment
//-----------------------------------------
always @(posedge I_clk)
begin
    S_ecc_eof <= I_ecc_eof;
	S_ecc_eof_d <= S_ecc_eof;
	S_ecc_v <= I_ecc_v;
	S_ecc <= I_ecc;
end
 
always @(posedge I_clk)
begin
    if(S_ecc_eof)
	begin
		S_slr_cnt <= 'd0;
		S_ov_id <= 1'b0;
	end
	else if(I_ecc_v)
	begin
		if(S_slr_cnt <= C_OVERFLOW_THRESHOLD)
		begin
    		S_slr_cnt <= S_slr_cnt + C_ECCWIDTH;
			S_ov_id <= 1'b0;
		end
		else
		begin
		    S_slr_cnt <= S_slr_cnt - C_DIF;
			S_ov_id <= 1'b1;
		end
	end		
end
 
always @(posedge I_clk)
begin
    if(S_ecc_eof_d)
	    S_data_slr <= 'd0;
	else if(I_ecc_v || S_ecc_v)
	begin
	    if(!S_ov_id)
			S_data_slr <= (I_ecc<<S_slr_cnt) | S_data_slr;
		else
		    S_data_slr <= (S_data_slr>>C_DWIDTH) | (I_ecc<<S_slr_cnt);
	end
end
 
always @(posedge I_clk)
begin
    if(S_ecc_v && S_ov_id)
	    S_data_tran <= F_data_inv(S_data_slr[0+:C_DWIDTH]);
	else if(S_ecc_eof_d)
	    S_data_tran <= F_data_inv(S_data_slr[0+:C_DWIDTH]);
end
 
always @(posedge I_clk)
begin
    S_data_tran_v <= (S_ecc_v && S_ov_id) || S_ecc_eof_d;
end
 
//--------------------------------------------------
//original data save
//--------------------------------------------------
always @(posedge I_clk)
begin
    if(I_data_v)
	    S_data_ram[S_data_waddr[C_CHIP_NUM_WIDTH-1:0]] <= I_data;
	S_dataout <= S_data_ram[S_ecc_raddr];
	if(I_data_eof)
	    S_data_waddr <= 'd0;
	else if(I_data_v && (S_data_waddr<C_CHIP_NUM))
	    S_data_waddr <= S_data_waddr + 'd1;
end
 
always @(posedge I_clk)
begin
    if(S_data_tran_v)
	    S_ecc_ram[S_ecc_waddr] <= S_data_tran;
	S_ecc_dout <= S_ecc_ram[S_ecc_raddr];
	if(I_ecc_sof)
	    S_ecc_waddr <= 'd0;
	else if(S_data_tran_v)
	    S_ecc_waddr <= S_ecc_waddr + 'd1;    
end
 
always @(posedge I_clk)
begin
    if(S_ecc_waddr == C_CHIP_NUM-1 && S_data_tran_v)
	    S_ecc_r <= 1'b1;
	else if(S_ecc_raddr == C_CHIP_NUM-1)
	    S_ecc_r <= 1'b0;
	S_ecc_r_d <= S_ecc_r;
end
 
always @(posedge I_clk)
begin
    if(I_ecc_sof)
	    S_ecc_raddr <= 'd0;
	else if(S_ecc_r)
	    S_ecc_raddr <= S_ecc_raddr + 'd1;
end
 
//---------------------------------------
//correct
//---------------------------------------
always @(posedge I_clk)
begin
    O_data_sof <= S_ecc_raddr == 'd1;
	S_data_eof <= S_ecc_raddr == C_CHIP_NUM-1;
	O_data_eof <= S_data_eof;
end
 
always @(posedge I_clk)
begin
    O_data <= S_dataout ^ S_ecc_dout;
	O_data_v <= S_ecc_r_d;
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.