📄 chn_eras_str.tdf
字号:
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
-- Revision Control Information
--
-- $Workfile: chn_eras_str.tdf $
-- $Archive: P:/RS_eras/units/Dec_str/ahdl/chn_eras_str.tdv $
--
-- $Revision: 1.2 $
-- $Date: 05 Aug 1999 18:25:20 $
-- $Author : Alejandro Diaz-Manero
--
-- Project : RS_eras
--
-- Description : Chien search and Forney's algorithm for streaming RS
-- decoder supporting erasures.
--
-- Copyright 1999 (c) Altera Corporation
-- All rights reserved
--
-------------------------------------------------------------------------
-------------------------------------------------------------------------
FUNCTION lpm_counter (data[LPM_WIDTH-1..0], clock, clk_en, cnt_en, updown, aclr,
aset, aconst, aload, sclr, sset, sconst, sload)
RETURNS (q[LPM_WIDTH-1..0], eq[15..0]);
FUNCTION gfmul (a[m..1], b[m..1])
RETURNS (c[m..1]);
FUNCTION gfdiv (a[m..1], d[m..1])
RETURNS (c[m..1]);
FUNCTION select1 (selin[inwidth..1]) -- 0=1
RETURNS (selout[outwidth..1]);
PARAMETERS
(
n = 15, -- length of code
m = 4, -- GF size (2^m)
irrpol = 19, -- field polynomial
check = 4, -- number of check symbols (= # of syndromes)
genstart = 2, -- 1st root of generator polynomial
negroot0 = 1, negroot1 = 2, negroot2 = 3, negroot3 = 4, negroot4 = 5, negroot5 = 6,
negroot6 = 7, negroot7 = 8, negroot8 = 9, negroot9 = 10, negroot10 = 11, negroot11 = 12,
negroot12 = 13, negroot13 = 14, negroot14 = 15, negroot15 = 9, negroot16 = 10,
negroot17 = 7, negroot18 = 8, negroot19 = 4, negroot20 = 3, negroot21 = 2, negroot22 = 3,
negroot23 = 4, negroot24 = 5, negroot25 = 6, negroot26 = 7, negroot27 = 8, negroot28 = 9,
negroot29 = 10, negroot30 = 1, negroot31 = 2, negroot32 = 3, negroot33 = 4, negroot34 = 5,
negroot35 = 6, negroot36 = 7, negroot37 = 8, negroot38 = 9, negroot39 = 10, negroot40 = 1,
negroot41 = 2, negroot42 = 3, negroot43 = 4, negroot44 = 5, negroot45 = 6, negroot46 = 7,
negroot47 = 8, negroot48 = 9, negroot49 = 10, negroot50 = 10, rootpower_seed = 9,
inv_file = "inv_4_19.hex"
);
constant size = ceil(log2(n+1));
constant drv = ceil(check DIV 2);
constant even = floor(check DIV 2);
constant wide = ceil(log2(check+1));
subdesign chn_eras_str
(
sysclk, reset : INPUT;
bd[check..1][m..1] : INPUT;
omega[check..1][m..1] : INPUT;
errloc[check..1][size..1] : OUTPUT;
errvec[check..1][m..1] : OUTPUT;
numroots[m..1] : OUTPUT;
gofinal : OUTPUT;
)
VARIABLE
-- search variables
reg[check..1][m..1] : dffe;
locreg[check..1][size..1] : dffe;
deladd[size..1], deldrv[m..1] : dffe;
mulout[check..1][m..1], alpha[check..1][m..1] : node;
evadder[even..1][m..1], drvadder[drv..1][m..1], halfadd[m..1], one[m..1] : node;
rootcnt[m..1], dftadd[m..1] : node;
cmpcnt[m..1], cntchk[m..1], poly[m..1], polyzero[m..1] : node;
load[check..1] : node;
lcnta, lcntb : lpm_counter WITH (LPM_WIDTH = m);
-- eval variables
omreg[(check-1)..1][m..1], vecreg[check..1][m..1] : dffe;
delom[m..1] : dffe;
omegamul[(check-1)..1][m..1] : node;
omadder[(check-1)..1][m..1] : node;
divfield[m..1] : dffe;
vecfield[m..1] : node;
IF (genstart > 0) GENERATE
rootreg[m..1], delroot[2..1][m..1] : dffe;
rootmul[m..1], rootpower[m..1] : node;
END GENERATE;
init, counten, loadloc, loadvec, gofinal : node;
ss : MACHINE OF BITS (state[5..1])
WITH STATES (s0 = B"00000",
-- search
s1 = B"00001", -- initialize search registers
s2 = B"00010", -- check next root
-- store
s3 = B"00100", -- store location
s4 = B"01000", -- store vector, inc counter
s99 = B"10000");
BEGIN
-- ****************
-- *** machine ***
-- ****************
init = state[1];
counten = state[2];
loadloc = state[3];
loadvec = state[4];
gofinal = state[5];
ss.clk = sysclk;
ss.reset = GND;
CASE ss IS
WHEN s0 =>
IF (reset == VCC) THEN
ss = s0;
ELSE
ss = s1;
END IF;
-- search
WHEN s1 => -- initialize search
IF (reset == VCC) THEN
ss = s0;
ELSE
ss = s2;
END IF;
WHEN s2 =>
IF (reset == VCC) THEN
ss = s0;
ELSIF (cntchk[m] == GND) THEN
ss = s99;
ELSIF (polyzero[m] == GND) THEN
ss = s3;
ELSE
ss = s2;
END IF;
WHEN s3 =>
IF (reset == VCC) THEN
ss = s0;
ELSE
ss = s4;
END IF;
WHEN s4 =>
IF (reset == VCC) THEN
ss = s0;
ELSIF (cntchk[m] == GND) THEN
ss = s99;
ELSE
ss = s2;
END IF;
WHEN s99 =>
IF (reset == VCC) THEN
ss = s0;
ELSE
ss = s99;
END IF;
WHEN others =>
ss = s0;
END CASE;
-- ***********************
-- *** do chien search ***
-- ***********************
cmpcnt[] = n;
rootcnt[] = lcnta.q[];
lcnta.clock = sysclk;
lcnta.cnt_en = counten;
lcnta.sclr = reset;
cntchk[1] = rootcnt[1] $ cmpcnt[1];
FOR k IN 2 TO m GENERATE
cntchk[k] = cntchk[k-1] # (rootcnt[k] $ cmpcnt[k]);
END GENERATE;
dftadd[] = lcntb.q[];
lcntb.clock = sysclk;
lcntb.cnt_en = loadvec;
lcntb.sclr = reset;
load[] = select1(dftadd[]) WITH (inwidth = m, outwidth = check);
locreg[][].clk = sysclk;
FOR k IN 1 TO check GENERATE
locreg[k][] = (deladd[size..1]) & !reset;
locreg[k][].ena = (load[k] & loadloc) # reset;
END GENERATE;
-- reset not needed, deladd[] = rootcnt[] by the time its latched
deladd[] = rootcnt[size..1]; -- delay location address to line up with root
deladd[].clk = sysclk;
-- reset not needed, initialized by state machine
reg[][].clk = sysclk;
FOR k IN 1 TO check GENERATE
reg[k][] = ((mulout[k][] & !init) # (bd[k][] & init));
reg[k][].ena = init # counten;
mulout[k][] = gfmul( reg[k][], alpha[k][]) WITH (m=m, irrpol = irrpol);
END GENERATE;
alpha[1][] = negroot1; -- a^-1
IF (check >= 2) GENERATE
alpha[2][] = negroot2; -- a^-2
END GENERATE;
IF (check >= 3) GENERATE
alpha[3][] = negroot3; -- a^-3
END GENERATE;
IF (check >= 4) GENERATE
alpha[4][] = negroot4; -- a^-4
END GENERATE;
IF (check >= 5) GENERATE
alpha[5][] = negroot5;
END GENERATE;
IF (check >= 6) GENERATE
alpha[6][] = negroot6;
END GENERATE;
IF (check >= 7) GENERATE
alpha[7][] = negroot7;
END GENERATE;
IF (check >= 8) GENERATE
alpha[8][] = negroot8;
END GENERATE;
IF (check >= 9) GENERATE
alpha[9][] = negroot9;
END GENERATE;
IF (check >= 10) GENERATE
alpha[10][] = negroot10;
END GENERATE;
IF (check >= 11) GENERATE
alpha[11][] = negroot11;
END GENERATE;
IF (check >= 12) GENERATE
alpha[12][] = negroot12;
END GENERATE;
IF (check >= 13) GENERATE
alpha[13][] = negroot13;
END GENERATE;
IF (check >= 14) GENERATE
alpha[14][] = negroot14;
END GENERATE;
IF (check >= 15) GENERATE
alpha[15][] = negroot15;
END GENERATE;
IF (check >= 16) GENERATE
alpha[16][] = negroot16;
END GENERATE;
IF (check >= 17) GENERATE
alpha[17][] = negroot17;
END GENERATE;
IF (check >= 18) GENERATE
alpha[18][] = negroot18;
END GENERATE;
IF (check >= 19) GENERATE
alpha[19][] = negroot19;
END GENERATE;
IF (check >= 20) GENERATE
alpha[20][] = negroot20;
END GENERATE;
IF (check >= 21) GENERATE
alpha[21][] = negroot21;
END GENERATE;
IF (check >= 22) GENERATE
alpha[22][] = negroot22;
END GENERATE;
IF (check >= 23) GENERATE
alpha[23][] = negroot23;
END GENERATE;
IF (check >= 24) GENERATE
alpha[24][] = negroot24;
END GENERATE;
IF (check >= 25) GENERATE
alpha[25][] = negroot25;
END GENERATE;
IF (check >= 26) GENERATE
alpha[26][] = negroot26;
END GENERATE;
IF (check >= 27) GENERATE
alpha[27][] = negroot27;
END GENERATE;
IF (check >= 28) GENERATE
alpha[28][] = negroot28;
END GENERATE;
IF (check >= 29) GENERATE
alpha[29][] = negroot29;
END GENERATE;
IF (check >= 30) GENERATE
alpha[30][] = negroot30;
END GENERATE;
IF (check >= 31) GENERATE
alpha[31][] = negroot31;
END GENERATE;
IF (check >= 32) GENERATE
alpha[32][] = negroot32;
END GENERATE;
IF (check >= 33) GENERATE
alpha[33][] = negroot33;
END GENERATE;
IF (check >= 34) GENERATE
alpha[34][] = negroot34;
END GENERATE;
IF (check >= 35) GENERATE
alpha[35][] = negroot35;
END GENERATE;
IF (check >= 36) GENERATE
alpha[36][] = negroot36;
END GENERATE;
IF (check >= 37) GENERATE
alpha[37][] = negroot37;
END GENERATE;
IF (check >= 38) GENERATE
alpha[38][] = negroot38;
END GENERATE;
IF (check >= 39) GENERATE
alpha[39][] = negroot39;
END GENERATE;
IF (check >= 40) GENERATE
alpha[40][] = negroot40;
END GENERATE;
IF (check >= 41) GENERATE
alpha[41][] = negroot41;
END GENERATE;
IF (check >= 42) GENERATE
alpha[42][] = negroot42;
END GENERATE;
IF (check >= 43) GENERATE
alpha[43][] = negroot43;
END GENERATE;
IF (check >= 44) GENERATE
alpha[44][] = negroot44;
END GENERATE;
IF (check >= 45) GENERATE
alpha[45][] = negroot45;
END GENERATE;
IF (check >= 46) GENERATE
alpha[46][] = negroot46;
END GENERATE;
IF (check >= 47) GENERATE
alpha[47][] = negroot47;
END GENERATE;
IF (check >= 48) GENERATE
alpha[48][] = negroot48;
END GENERATE;
IF (check >= 49) GENERATE
alpha[49][] = negroot49;
END GENERATE;
IF (check >= 50) GENERATE
alpha[50][] = negroot50;
END GENERATE;
-- add all even regs together
evadder[1][m..1] = reg[2][m..1];
IF (even >= 2) GENERATE
FOR j IN 2 TO even GENERATE
evadder[J][m..1] = evadder[J-1][m..1] $ reg[2*J][m..1]; -- GFadd
END GENERATE;
END GENERATE;
-- do derivative (odd terms)
FOR k IN 1 TO m GENERATE
drvadder[1][K] = reg[1][k];
IF (drv >= 2) GENERATE
FOR j IN 2 TO drv GENERATE
drvadder[J][K] = drvadder[J-1][K] $ reg[2*J-1][k]; -- GFadd
END GENERATE;
END GENERATE;
END GENERATE;
-- reset not needed, deldrv[] is valid by the time root found
deldrv[] = drvadder[drv][];
deldrv[].clk = sysclk;
one[]=1;
halfadd[] = evadder[even][] $ drvadder[drv][]; -- gfadd
poly[] = halfadd[] $ one[]; -- gfadd
polyzero[1] = poly[1];
FOR k IN 2 TO m GENERATE
polyzero[k] = polyzero[k-1] # poly[k];
END GENERATE;
-- *****************
-- *** omega(x) ***
-- *****************
-- reset not needed, initialized by state machine
omreg[][].clk = sysclk;
FOR k IN 1 TO (check-1) GENERATE
omreg[k][] = ((omegamul[k][] & !init) # (omega[k+1][] & init));
omreg[k][].ena = init # counten;
omegamul[k][] = gfmul( omreg[k][], alpha[k][]) WITH (m=m, irrpol = irrpol);
END GENERATE;
-- add all omega terms together
omadder[1][m..1] = omreg[1][m..1];
IF (check > 2) GENERATE
FOR j IN 2 TO (check-1) GENERATE
omadder[J][m..1] = omadder[J-1][m..1] $ omreg[j][m..1]; -- GFadd
END GENERATE;
END GENERATE;
-- reset not needed, delom[] valid by the time root found
delom[] = omadder[check-1][] $ omega[1][]; -- gfadd
delom[].clk = sysclk;
-- ***********************
-- *** evaluate error ***
-- ***********************
divfield[] = gfdiv(delom[],deldrv[]) WITH (m=m, irrpol = irrpol, inv_file = inv_file);
divfield[].clk = sysclk;
IF (genstart == 0) GENERATE
vecfield[] = divfield[];
END GENERATE;
-- reset not needed, initializes after reset of sm
IF (genstart > 0 ) GENERATE
-- calculate next root
rootreg[].clk = sysclk;
rootreg[].ena = init # counten;
-- load 1 into rootreg on startup
rootreg[m..2] = (rootmul[m..2] & !init);
rootreg[1] = (rootmul[1] & !init) # init;
rootpower[] = rootpower_seed;
rootmul[] = gfmul(rootpower[],rootreg[]) WITH (m=m, irrpol = irrpol);
delroot[1][] = rootreg[] & !reset;
delroot[2][] = delroot[1][] & !reset;
delroot[][].clk = sysclk;
vecfield[] = gfmul(divfield[], delroot[2][]) WITH (m=m, irrpol = irrpol);
END GENERATE;
FOR k IN 1 TO check GENERATE
vecreg[k][] = vecfield[] & !reset;
vecreg[k][].ena = (load[k] & loadvec) # reset;
END GENERATE;
vecreg[][].clk = sysclk;
-- ****************
-- *** outputs ***
-- ****************
errvec[][] = vecreg[][];
errloc[][] = locreg[][];
numroots[] = dftadd[];
END;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -