📄 bms_std_dsc_half.tdf
字号:
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
-- Revision Control Information
--
-- $Workfile: bms_std_dsc_half.tdf $
-- $Archive: P:/RS_std/units/Dec_dsc/ahdl/bms_std_dsc_half.tdv $
--
-- $Revision: 1.1 $
-- $Date: 19 Aug 1999 14:40:38 $
-- $Author : Alejandro Diaz-Manero
--
-- Project : RS_std
--
-- Description :
--
-- Copyright 1999 (c) Altera Corporation
-- All rights reserved
--
-------------------------------------------------------------------------
-------------------------------------------------------------------------
FUNCTION lpm_add_sub (cin, dataa[LPM_WIDTH-1..0], datab[LPM_WIDTH-1..0],
add_sub, clock, aclr)
RETURNS (result[LPM_WIDTH-1..0], cout, overflow);
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 lpm_compare (dataa[LPM_WIDTH-1..0], datab[LPM_WIDTH-1..0], clock, aclr)
RETURNS (alb, aeb, agb, ageb, aneb, aleb);
FUNCTION gfmul (a[m..1], b[m..1])
RETURNS (c[m..1]);
FUNCTION gfdiv (a[m..1], d[m..1])
RETURNS (c[m..1]);
PARAMETERS
(
m = 8, -- GF size (2^m)
irrpol = 285, -- field polynomial
check = 16, -- number of check symbols (= # of syndromes)
inv_file = "inv_8_285.hex"
);
constant wide = ceil(log2(check+1));
constant errs = floor(check DIV 2);
constant nummult = ceil(errs DIV 2);
constant odd = nummult > floor(errs DIV 2) ? 1:0;
subdesign bms_std_dsc_half
(
sysclk, reset, go, syn[check..1][m..1] : INPUT;
bdout[errs..1][m..1], omegaout[errs..1][m..1], numerr[wide..1], done : OUTPUT;
)
VARIABLE
synreg[check..1][m..1], bd[errs..1][m..1], bdprev[errs..1][m..1], bdtemp[errs..1][m..1] : dffe;
one[m..1] : node;
onereg : dffe;
onenode[m..1] : node;
deltaleft[errs..1][m..1], deltaright[errs..1][m..1] : node;
bdleft[errs..1][m..1], bdright[errs..1][m..1] : node;
mulleft[nummult..1][m..1], mulright[nummult..1][m..1], deltamult[m..1] : dffe;
mulout[nummult..1][m..1] : node;
mulsum[nummult..1][m..1], addvec[errs..1][m..1] : node;
deltazero[m..1] : node;
predelta[m..1], delta[m..1], deltaprev[m..1] : dffe;
mcount, omegacount : lpm_counter WITH (LPM_WIDTH = wide);
sub_llnum_mloop : lpm_add_sub WITH (LPM_WIDTH = wide, LPM_DIRECTION = "SUB");
add_one_llnuma : lpm_add_sub WITH (LPM_WIDTH = wide, LPM_DIRECTION = "ADD");
cmp : lpm_compare WITH (LPM_WIDTH = (wide+1));
llnuma[wide..1], zero[wide..1] : node;
llnum[wide..1] : dffe;
mloop[wide..1], omegaloop[wide..1] : node;
mchk[wide..1], mcmp[wide..1], omegachk[wide..1], omegacmp[wide..1] : node;
tlm : node;
omega[errs..1][m..1] : dffe;
omsel[errs..1] : dffe;
omegaleft[errs..1][m..1], omegaright[errs..1][m..1] : node;
loadsyn, loadbdleft, loadbdright, loadbdprev, loadbdtemp : node; -- 1 - 5
multmux : node; -- 6
shiftsynleft, shiftsynright, shiftbd, shiftbdprev : node; -- 7 - 10
deltacalc, newdelta, olddelta : node; -- 11 - 13
incm : node; -- 14
incomega, initomega, calcomega, loadomegaleft, loadomegaright : node; -- 15 - 19
massdone : node; -- 20
mx : MACHINE OF BITS (mst[20..1])
WITH STATES
(s0 = B"00000000000000000000",
s1 = B"00000000000000000001", -- load syndromes
s2 = B"00000000111000000000", -- calc new delta = Sm + (series)B(j)*S(m-j), shift BDprev
s2a = B"00000000110000100000", -- 1 pipe stage to top of gfmuls
s2b = B"00000000110000100000", -- 1 pipe stage to top of gfmuls
s3 = B"00000000000000000000", -- if new delta <> 0, calc new BD
s4 = B"00000000000000010000", -- TD = BD, BD = BD - deltamult*(D^i)*BDprev
s5 = B"00000000000000100010", -- load first half BD
s5a = B"00000000000000100100", -- load second half BD, check 2L <= m?
s6 = B"00000001000000001000", -- L = m+1-L, i=1, BDprev = BDtemp, olddelta = delta
s8 = B"00000010000001000000", -- inc mloop, shift synregs left
-- calc omega
s10 = B"00011000000000000000", -- initialize omegaleft
s11 = B"00111000000010100000", -- initialize omegaright, shift synregs right
s12 = B"01010100000000000000", -- calc omegaleft, load omegaright, inc
s13 = B"00110000000110100000", -- calc omegaright, load omegaleft, synshift, bdshift
s14 = B"00000000000100000000", -- last bdshift
s99 = B"10000000000000000000");
BEGIN
mcmp[] = check;
omegacmp[] = errs-1;
one[] = 1;
zero[] = 0;
--*********************
--*** STATE MACHINE ***
--*********************
mx.clk = sysclk;
mx.reset = reset;
CASE mx IS
WHEN s0 =>
IF (go == VCC) THEN
mx = s1;
ELSE
mx = s0;
END IF;
WHEN s1 =>
mx = s2;
WHEN s2 =>
IF (mchk[wide] == VCC) THEN
mx = s2a;
ELSE
mx = s10;
END IF;
WHEN s2a =>
mx = s2b;
WHEN s2b =>
mx = s3;
WHEN s3 =>
IF (deltazero[m] == VCC) THEN
mx = s4;
ELSE
mx = s8;
END IF;
WHEN s4 =>
mx = s5;
WHEN s5 =>
mx = s5a;
WHEN s5a =>
IF (tlm == VCC) THEN
mx = s6;
ELSE
mx = s8;
END IF;
WHEN s6 =>
mx = s8;
WHEN s8 =>
mx = s2;
WHEN s10 =>
mx = s11;
WHEN s11 =>
mx = s12;
WHEN s12 =>
IF (omegachk[wide] == VCC) THEN
mx = s13;
ELSE
mx = s14;
END IF;
WHEN s13 =>
mx = s12;
WHEN s14 =>
mx = s99;
WHEN s99 =>
mx = s99;
END CASE;
loadsyn = mst[1];
loadbdleft = mst[2];
loadbdright = mst[3];
loadbdprev = mst[4];
loadbdtemp = mst[5];
multmux = mst[6];
shiftsynleft = mst[7];
shiftsynright = mst[8];
shiftbd = mst[9];
shiftbdprev = mst[10];
deltacalc = mst[11];
newdelta = mst[12];
olddelta = mst[13];
incm = mst[14];
incomega = mst[15];
initomega = mst[16];
calcomega = mst[17];
loadomegaleft = mst[18];
loadomegaright = mst[19];
massdone = mst[20];
--************************
--*** SYNDROME SECTION ***
--************************
synreg[1][] = (syn[1][] & !shiftsynleft) #
(synreg[2][] & shiftsynleft);
FOR k IN 2 TO errs GENERATE
synreg[k][] = (syn[k][] & !shiftsynleft & !shiftsynright) #
(synreg[k+1][] & shiftsynleft) #
(synreg[k-1][] & shiftsynright);
END GENERATE;
FOR k IN (errs+1) TO (check-1) GENERATE
synreg[k][] = (syn[k][] & !shiftsynleft) #
(synreg[k+1][] & shiftsynleft);
END GENERATE;
synreg[check][] = (syn[check][] & !shiftsynleft) # (synreg[1][] & shiftsynleft);
synreg[][].clk = sysclk;
synreg[1][].ena = loadsyn # shiftsynleft;
FOR k IN 2 TO errs GENERATE
synreg[k][].ena = loadsyn # shiftsynleft # shiftsynright;
END GENERATE;
FOR k IN (errs+1) TO check GENERATE
synreg[k][].ena = loadsyn # shiftsynleft;
END GENERATE;
--******************
--*** BD SECTION ***
--******************
-- load onereg with zero after first shift
--onereg[] = (one[] & !shiftbdprev);
onereg = loadsyn # loadbdprev;
onereg.ena = shiftbdprev # loadsyn # loadbdprev;
onereg.clk = sysclk;
onenode[1] = onereg;
onenode[m..2] = 0;
FOR k IN 1 TO (errs-1) GENERATE
bd[k][] = (addvec[k][] & !shiftbd) # (bd[k+1][] & shiftbd);
END GENERATE;
bd[errs][] = (addvec[errs][] & !shiftbd) # (bd[1][] & shiftbd);
bd[][].clk = sysclk;
bd[][].clrn = !reset;
FOR k IN 1 TO nummult GENERATE
bd[k][].ena = loadbdleft # shiftbd;
END GENERATE;
FOR k IN 1 TO (errs-nummult) GENERATE
bd[k+nummult][].ena = loadbdright # shiftbd;
END GENERATE;
bdprev[1][] = (bdtemp[1][] & !shiftbdprev) # (onenode[] & shiftbdprev);
FOR k IN 2 TO errs GENERATE
bdprev[k][] = (bdtemp[k][] & !shiftbdprev) # (bdprev[k-1][] & shiftbdprev);
END GENERATE;
bdprev[][].clk = sysclk;
bdprev[][].ena = loadbdprev # shiftbdprev;
bdprev[][].clrn = !reset;
bdtemp[][] = bd[][];
bdtemp[][].clk = sysclk;
bdtemp[][].ena = loadbdtemp;
bdtemp[][].clrn = !reset;
--********************
--*** CORE SECTION ***
--********************
--*** calculate new delta ***
FOR k IN 1 to errs GENERATE
deltaleft[k][] = synreg[check+1-k][];
deltaright[k][] = bd[k][];
END GENERATE;
-- calculate new bd vector
bdleft[][] = bdprev[][];
FOR k IN 1 TO errs GENERATE
bdright[k][] = deltamult[];
END GENERATE;
FOR k IN 1 TO nummult GENERATE
addvec[k][m..1] = bd[k][m..1] $ mulout[k][m..1]; -- GFAdd
END GENERATE;
IF (odd == 0) GENERATE
FOR k IN 1 TO nummult GENERATE
addvec[k+nummult][m..1] = bd[k+nummult][m..1] $ mulout[k][m..1]; -- GFadd
END GENERATE;
ELSE GENERATE
FOR k IN 1 TO (nummult-1) GENERATE
addvec[k+nummult][m..1] = bd[k+nummult][m..1] $ mulout[k][m..1]; -- GFadd
END GENERATE;
END GENERATE;
-- calculate omega
FOR k IN 1 TO errs GENERATE
omegaleft[k][] = synreg[k][];
END GENERATE;
FOR k IN 1 TO errs GENERATE
omegaright[k][] = (bd[1][] & !initomega) # (one[] & initomega);
END GENERATE;
-- multiply
IF (odd == 0) GENERATE
FOR k IN 1 TO nummult GENERATE
mulleft[k][] = ( !multmux & ((deltaleft[k][] & deltacalc) #
((bdleft[k][] & !deltacalc & !calcomega) # (omegaleft[k][] & !deltacalc & calcomega))) ) #
( multmux & ((deltaleft[k+nummult][] & deltacalc) #
((bdleft[k+nummult][] & !deltacalc & !calcomega) # (omegaleft[k+nummult][] & !deltacalc & calcomega))) );
mulright[k][] = ( !multmux & ((deltaright[k][] & deltacalc) #
((bdright[k][] & !deltacalc & !calcomega) # (omegaright[k][] & !deltacalc & calcomega))) ) #
( multmux & ((deltaright[k+nummult][] & deltacalc) #
((bdright[k+nummult][] & !deltacalc & !calcomega) # (omegaright[k+nummult][] & !deltacalc & calcomega))) );
END GENERATE;
ELSE GENERATE
FOR k IN 1 TO (nummult-1) GENERATE
mulleft[k][] = ( !multmux & ((deltaleft[k][] & deltacalc) #
((bdleft[k][] & !deltacalc & !calcomega) # (omegaleft[k][] & !deltacalc & calcomega))) ) #
( multmux & ((deltaleft[k+nummult][] & deltacalc) #
((bdleft[k+nummult][] & !deltacalc & !calcomega) # (omegaleft[k+nummult][] & !deltacalc & calcomega))) );
mulright[k][] = ( !multmux & ((deltaright[k][] & deltacalc) #
((bdright[k][] & !deltacalc & !calcomega) # (omegaright[k][] & !deltacalc & calcomega))) ) #
( multmux & ((deltaright[k+nummult][] & deltacalc) #
((bdright[k+nummult][] & !deltacalc & !calcomega) # (omegaright[k+nummult][] & !deltacalc & calcomega))) );
END GENERATE;
mulleft[nummult][] = ( !multmux & ((deltaleft[nummult][] & deltacalc) #
((bdleft[nummult][] & !deltacalc & !calcomega) # (omegaleft[nummult][] & !deltacalc & calcomega))) );
mulright[nummult][] = ( !multmux & ((deltaright[nummult][] & deltacalc) #
((bdright[nummult][] & !deltacalc & !calcomega) # (omegaright[nummult][] & !deltacalc & calcomega))) );
END GENERATE;
mulleft[][].clk = sysclk;
mulright[][].clk = sysclk;
FOR k IN 1 TO nummult GENERATE
mulout[k][] = gfmul (mulleft[k][], mulright[k][])
WITH (m = m, irrpol = irrpol);
END GENERATE;
-- calculate new delta
mulsum[1][] = mulout[1][];
IF (nummult>1) GENERATE
FOR k IN 2 TO nummult GENERATE
mulsum[k][m..1] = mulout[k][m..1] $ mulsum[k-1][m..1]; -- GFadd
END GENERATE;
END GENERATE;
predelta[m..1] = mulsum[nummult][m..1] $ synreg[1][m..1]; -- GFadd
predelta[].clk = sysclk;
delta[m..1] = mulsum[nummult][m..1] $ predelta[m..1]; -- GFadd
delta[].clk = sysclk;
delta[].ena = newdelta;
delta[].clrn = !reset;
deltaprev[] = delta[];
deltaprev[].clk = sysclk;
deltaprev[].ena = olddelta;
deltaprev[m..2].clrn = !reset;
deltaprev[1].prn = !reset;
deltamult[] = gfdiv (delta[], deltaprev[])
WITH (m=m, irrpol=irrpol, inv_file = inv_file);
deltamult[].clk = sysclk;
deltazero[1] = delta[1];
FOR k IN 2 TO m GENERATE
deltazero[k] = delta[k] # deltazero[k-1];
END GENERATE;
--****************
--*** COUNTERS ***
--****************
mloop[] = mcount.q[];
mcount.clock = sysclk;
mcount.cnt_en = incm;
mcount.aclr = reset;
mchk[1] = mloop[1] $ mcmp[1];
FOR k IN 2 TO wide GENERATE
mchk[k] = mchk[k-1] # (mloop[k] $ mcmp[k]);
END GENERATE;
-- L = M+1-L
sub_llnum_mloop.cin = VCC;
sub_llnum_mloop.dataa[] = mloop[];
sub_llnum_mloop.datab[] = llnum[];
llnuma[] = sub_llnum_mloop.result[];
add_one_llnuma.cin = VCC;
add_one_llnuma.dataa[] = llnuma[];
add_one_llnuma.datab[] = zero[];
llnum[] = add_one_llnuma.result[];
-- (llnuma[],,) = lpm_add_sub ( VCC, mloop[], llnum[],,,)
-- WITH (LPM_WIDTH = wide, LPM_DIRECTION = "SUB");
-- (llnum[],,) = lpm_add_sub ( VCC, llnuma[], zero[],,,)
-- WITH (LPM_WIDTH = wide);
llnum[].clk = sysclk;
llnum[].ena = loadbdprev;
llnum[].clrn = !reset;
-- 2L <= m?
-- (,,,,,tlm) = lpm_compare ( (llnum[],0), (0,mloop[]),,)
-- WITH (LPM_WIDTH = (wide+1));
cmp.dataa[] = (llnum[],0);
cmp.datab[] = (0,mloop[]);
tlm = cmp.aleb;
omegaloop[] = omegacount.q[];
omegacount.clock = sysclk;
omegacount.cnt_en = incomega;
omegacount.aclr = reset;
omegachk[1] = omegaloop[1] $ omegacmp[1];
FOR k IN 2 TO wide GENERATE
omegachk[k] = omegachk[k-1] # (omegaloop[k] $ omegacmp[k]);
END GENERATE;
--*************
--*** OMEGA ***
--*************
omsel[].clk = sysclk;
omsel[].clrn = !reset;
omsel[].ena = incomega;
omsel[1] = VCC;
FOR k IN 2 TO errs GENERATE
omsel[K] = omsel[K-1];
end generate;
FOR k IN 1 TO nummult-odd GENERATE
omega[k][m..1] = omega[k][m..1] $ mulout[k][m..1]; -- GFadd
omega[k+nummult][m..1] = omega[k+nummult][m..1] $ mulout[k][m..1]; -- GFadd
omega[k][].ena = !omsel[k] & loadomegaleft;
omega[k+nummult][].ena = !omsel[k+nummult] & loadomegaright;
END GENERATE;
IF (odd == 1) GENERATE
omega[nummult][m..1] = omega[nummult][m..1] $ mulout[nummult][m..1]; -- GFadd
omega[nummult][].ena = !omsel[nummult] & loadomegaleft;
END GENERATE;
omega[][].clk = sysclk;
omega[][].clrn = !reset;
--***************
--*** OUTPUTS ***
--***************
bdout[][] = bd[][];
omegaout[][] = omega[][];
numerr[] = llnum[];
done = massdone;
END;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -