📄 lpm_ad~1.tdf
字号:
IF RWIDTH > 1 GENERATE
FOR I IN 1 TO RWIDTH-1 GENERATE
datab0_ff[0][I].d[] = datab_node[(I+1)*SUB_WIDTH0-1..I*SUB_WIDTH0];
END GENERATE;
END GENERATE;
FOR I IN 0 TO LWIDTH-1 GENERATE
datab1_ff[0][I].d[] = datab_node[(I+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..
I*SUB_WIDTH1+RWIDTH*SUB_WIDTH0];
END GENERATE;
ELSE GENERATE
IF LWIDTH > 1 GENERATE
FOR I IN 1 TO LWIDTH-1 GENERATE
datab1_ff[0][I].d[] = datab_node[(I+1)*SUB_WIDTH1-1..I*SUB_WIDTH1];
END GENERATE;
END GENERATE;
END GENERATE;
-- some adder connections
IF RWIDTH > 0 GENERATE
-- The nonhomogeneous adder case. Note that with RWIDTH > 0,
-- INT_LATENCY must have been > 1.
-- longer (right hand side) adder(s) connection(s)
-- the upper right-most adder is connected to the input nodes
adder0[0].dataa[] = dataa[SUB_WIDTH0-1..0];
adder0[0].datab[] = datab_node[SUB_WIDTH0-1..0];
adder0[0].cin = cin_node;
carry_ff[0].d[] = adder0[0].cout;
-- if more than one right-side adder, make the input and carry connections
IF RWIDTH > 1 GENERATE
FOR I IN 1 TO RWIDTH-1 GENERATE
adder0[I].dataa[] = dataa_ff[I-1].q[(I+1)*SUB_WIDTH0-1..I*SUB_WIDTH0];
adder0[I].datab[] = datab0_ff[I-1][I].q[];
adder0[I].cin = carry_ff[I-1].q[];
carry_ff[I].d[] = adder0[I].cout;
END GENERATE;
END GENERATE;
-- first left-hand-side adder connections
adder1[0].dataa[] = dataa_ff[RWIDTH-1].q[SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..RWIDTH*SUB_WIDTH0];
adder1[0].datab[] = datab1_ff[RWIDTH-1][0].q[];
adder1[0].cin = carry_ff[RWIDTH-1].q[];
carry_ff[RWIDTH].d[] = adder1[0].cout;
ELSE GENERATE
-- case with homogeneous adders
adder1[0].dataa[] = dataa[SUB_WIDTH1-1..0];
adder1[0].datab[] = datab_node[SUB_WIDTH1-1..0];
adder1[0].cin = cin_node;
carry_ff[0].d[] = adder1[0].cout;
END GENERATE;
-- more connections if more than 1 left-hand-side adders exist
IF LWIDTH > 1 GENERATE
FOR I IN 1 TO LWIDTH-1 GENERATE
adder1[I].dataa[] = dataa_ff[I+RWIDTH-1].q[(I+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..
I*SUB_WIDTH1+RWIDTH*SUB_WIDTH0];
adder1[I].datab[] = datab1_ff[I+RWIDTH-1][I].q[];
END GENERATE;
adder1[LWIDTH-1..1].cin = carry_ff[INT_LATENCY-2..RWIDTH].q[];
carry_ff[INT_LATENCY-1..(RWIDTH+1)].d[] = adder1[LWIDTH-1..1].cout;
END GENERATE;
IF USED(cout) # USED(overflow) GENERATE
cout_node = carry_ff[INT_LATENCY-1].q[];
ELSE GENERATE
cout_node = GND;
END GENERATE;
ELSE GENERATE
----------------------------------------------
-- FLEX cases --
----------------------------------------------
-- clock connections
IF RWIDTH > 0 GENERATE
datab0_ff[INT_LATENCY-2..0][].(clk, clrn) = (clock, !aclr);
IF USED(clken) GENERATE
datab0_ff[INT_LATENCY-2..0][].ena = clken;
END GENERATE;
END GENERATE;
datab1_ff[INT_LATENCY-2..0][].(clk, clrn) = (clock, !aclr);
IF USED(clken) GENERATE
datab1_ff[INT_LATENCY-2..0][].ena = clken;
END GENERATE;
IF LPM_REPRESENTATION == "SIGNED" GENERATE
sign_ff[INT_LATENCY-2..0].(clk, clrn) = (clock, !aclr);
IF USED(clken) GENERATE
sign_ff[INT_LATENCY-2..0].ena = clken;
END GENERATE;
END GENERATE;
-- datab input connections
IF RWIDTH > 0 GENERATE
IF RWIDTH > 1 GENERATE
FOR I IN 1 TO RWIDTH-1 GENERATE
adder0_0[I].dataa[SUB_WIDTH0-1..0] = dataa[(I+1)*SUB_WIDTH0-1..I*SUB_WIDTH0];
adder0_0[I].datab[SUB_WIDTH0-1..0] = datab_node[(I+1)*SUB_WIDTH0-1..I*SUB_WIDTH0];
datab0_ff[0][I].d[] = adder0_0[I].result[];
END GENERATE;
END GENERATE;
FOR I IN 0 TO LWIDTH-1 GENERATE
adder1_0[I].dataa[SUB_WIDTH1-1..0] = dataa[(I+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..
I*SUB_WIDTH1+RWIDTH*SUB_WIDTH0];
adder1_0[I].datab[SUB_WIDTH1-1..0] = datab_node[(I+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..
I*SUB_WIDTH1+RWIDTH*SUB_WIDTH0];
datab1_ff[0][I].d[] = adder1_0[I].result[];
END GENERATE;
ELSE GENERATE
IF LWIDTH > 1 GENERATE
FOR I IN 1 TO LWIDTH-1 GENERATE
adder1_0[I].dataa[SUB_WIDTH1-1..0] = dataa[(I+1)*SUB_WIDTH1-1..I*SUB_WIDTH1];
adder1_0[I].datab[SUB_WIDTH1-1..0] = datab_node[(I+1)*SUB_WIDTH1-1..I*SUB_WIDTH1];
datab1_ff[0][I].d[] = adder1_0[I].result[];
END GENERATE;
END GENERATE;
END GENERATE;
-- some adder connections
IF RWIDTH > 0 GENERATE
-- The nonhomogeneous adder case. Note that with RWIDTH > 0,
-- INT_LATENCY must have been > 1.
-- longer (right hand side) adder(s) connection(s)
-- the upper right-most adder is connected to the input nodes
adder0[0].dataa[SUB_WIDTH0-1..0] = dataa[SUB_WIDTH0-1..0];
adder0[0].datab[SUB_WIDTH0-1..0] = datab_node[SUB_WIDTH0-1..0];
adder0[0].cin = cin_node;
-- if more than one right-side adder, make the input and carry connections
IF RWIDTH > 1 GENERATE
FOR I IN 1 TO RWIDTH-1 GENERATE
adder0[I].dataa[0] = datab0_ff[I-1][I-1].q[SUB_WIDTH0];
adder0[I].datab[] = datab0_ff[I-1][I].q[];
END GENERATE;
END GENERATE;
-- first left-hand-side adder connections
adder1[0].dataa[0] = datab0_ff[RWIDTH-1][RWIDTH-1].q[SUB_WIDTH0];
adder1[0].datab[] = datab1_ff[RWIDTH-1][0].q[];
ELSE GENERATE
-- case with homogeneous adders
adder1[0].dataa[SUB_WIDTH1-1..0] = dataa[SUB_WIDTH1-1..0];
adder1[0].datab[SUB_WIDTH1-1..0] = datab_node[SUB_WIDTH1-1..0];
adder1[0].cin = cin_node;
END GENERATE;
-- more connections if more than 1 left-hand-side adders exist
IF LWIDTH > 1 GENERATE
FOR I IN 1 TO LWIDTH-1 GENERATE
adder1[I].dataa[0] = datab1_ff[I+RWIDTH-1][I-1].q[SUB_WIDTH1];
adder1[I].datab[] = datab1_ff[I+RWIDTH-1][I].q[];
END GENERATE;
END GENERATE;
IF LPM_REPRESENTATION == "SIGNED" GENERATE
sign_ff[0].d[] = (dataa[LPM_WIDTH-1], datab_node[LPM_WIDTH-1]);
IF INT_LATENCY > 2 GENERATE
FOR I IN 1 TO INT_LATENCY-2 GENERATE
sign_ff[I].d[] = sign_ff[I-1].q[];
END GENERATE;
END GENERATE;
END GENERATE;
IF USED(cout) # USED(overflow) GENERATE
cout_node = datab1_ff[INT_LATENCY-1][LWIDTH-1].q[SUB_WIDTH1];
ELSE GENERATE
cout_node = GND;
END GENERATE;
END GENERATE;
--------------------------
-- datab_ff connections --
--------------------------
IF RWIDTH > 0 GENERATE
-- first quadrant connections
FOR I IN 0 TO RWIDTH-1 GENERATE
datab0_ff[I][I].d[] = adder0[I].result[];
END GENERATE;
IF RWIDTH > 1 GENERATE
IF RWIDTH > 2 GENERATE
FOR I IN 1 TO RWIDTH-2 GENERATE
datab0_ff[I][RWIDTH-1..(I+1)].d[] = datab0_ff[I-1][RWIDTH-1..(I+1)].q[];
END GENERATE;
END GENERATE;
FOR I IN 1 TO RWIDTH-1 GENERATE
datab0_ff[I][I-1..0].d[] = datab0_ff[I-1][I-1..0].q[];
END GENERATE;
END GENERATE;
-- fourth quadrant connections
FOR I IN RWIDTH TO INT_LATENCY-1 GENERATE
datab0_ff[I][RWIDTH-1..0].d[] = datab0_ff[I-1][RWIDTH-1..0].q[];
END GENERATE;
-- second quadrant connections
IF RWIDTH > 1 GENERATE
FOR I IN 1 TO RWIDTH-1 GENERATE
datab1_ff[I][LWIDTH-1..0].d[] = datab1_ff[I-1][LWIDTH-1..0].q[];
END GENERATE;
END GENERATE;
-- datab1_ff interface between second and third quadrants
IF LWIDTH >1 GENERATE
datab1_ff[RWIDTH][LWIDTH-1..1].d[] = datab1_ff[RWIDTH-1][LWIDTH-1..1].q[];
END GENERATE;
END GENERATE;
-- third quadrant connections
FOR I IN 0 TO LWIDTH-1 GENERATE
datab1_ff[I+RWIDTH][I].d[] = adder1[I].result[];
END GENERATE;
IF LWIDTH > 1 GENERATE
FOR I IN 1 TO LWIDTH-1 GENERATE
datab1_ff[I+RWIDTH][I-1..0].d[] = datab1_ff[I+RWIDTH-1][I-1..0].q[];
END GENERATE;
IF LWIDTH > 2 GENERATE
FOR I IN 1 TO LWIDTH-2 GENERATE
datab1_ff[I+RWIDTH][LWIDTH-1..I+1].d[] = datab1_ff[I+RWIDTH-1][LWIDTH-1..I+1].q[];
END GENERATE;
END GENERATE;
END GENERATE;
-- connections of last row to output nodes
-- right section
IF RWIDTH > 0 GENERATE
FOR J IN 0 TO RWIDTH-1 GENERATE
result_node[(J+1)*SUB_WIDTH0-1..J*SUB_WIDTH0] =
datab0_ff[INT_LATENCY-1][J].q[SUB_WIDTH0-1..0];
END GENERATE;
END GENERATE;
-- left section
FOR J IN 0 TO LWIDTH-1 GENERATE
result_node[(J+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..J*SUB_WIDTH1+RWIDTH*SUB_WIDTH0] =
datab1_ff[INT_LATENCY-1][J].q[SUB_WIDTH1-1..0];
END GENERATE;
-- overflow detection
IF LPM_REPRESENTATION == "SIGNED" GENERATE
IF !(FAMILY_FLEX() == 1) GENERATE
oflow_ext_latency_ffs.data[] = (datab1_ff[INT_LATENCY-2][LWIDTH-1].q[SUB_WIDTH1-1] !$
dataa_ff[INT_LATENCY-2].q[LPM_WIDTH-1]) &
(dataa_ff[INT_LATENCY-2].q[LPM_WIDTH-1] $
adder1[LWIDTH-1].result[SUB_WIDTH1-1]);
ELSE GENERATE
oflow_ext_latency_ffs.data[] = !(sign_ff[INT_LATENCY-2].q[0] $ sign_ff[INT_LATENCY-2].q[1])
& (sign_ff[INT_LATENCY-2].q[0] $ adder1[LWIDTH-1].result[SUB_WIDTH1-1]);
END GENERATE;
ELSE GENERATE
IF LPM_DIRECTION == "SUB" GENERATE
oflow_ext_latency_ffs.data[] = !cout_node;
ELSE GENERATE
oflow_ext_latency_ffs.data[] = !add_sub_ff[INT_LATENCY-2].q[0] $ cout_node;
END GENERATE;
END GENERATE;
ELSE GENERATE
----------------------------------
-- non-pipelined adder cases --
----------------------------------
IF ((FAMILY_FLEX() == 1) &
(CARRY_CHAIN != "IGNORE" # (CARRY_CHAIN == "IGNORE" & SPEED_MAX_FACTOR <= 5))) #
(!(FAMILY_FLEX() == 1) &
(STYLE == "NORMAL" & SPEED_MAX_FACTOR <= 5)) GENERATE
-------------------------------------------------
-- connections for a non-look-ahead type adder --
-------------------------------------------------
adder.dataa[] = dataa[];
adder.datab[] = datab_node[];
adder.cin = cin_node;
result_node[] = adder.result[];
IF (USED(cout) # USED (overflow)) GENERATE
cout_node = adder.cout;
ELSE GENERATE
cout_node = GND;
END GENERATE;
ELSE GENERATE
---------------------------------------------
-- connections for a look-ahead type adder --
---------------------------------------------
IF BLOCKS > 1 GENERATE
FOR I IN 0 TO BLOCKS-2 GENERATE
adder[I].dataa[] = dataa[(I+1)*8-1..I*8];
adder[I].datab[] = datab_node[(I+1)*8-1..I*8];
adder[I].cin = look_aheader.cout[I];
result_node[(I+1)*8-1..I*8] = adder[I].result[];
END GENERATE;
END GENERATE;
adder[BLOCKS-1].dataa[LPM_WIDTH-(BLOCKS-1)*8-1..0] = dataa[LPM_WIDTH-1..(BLOCKS-1)*8];
adder[BLOCKS-1].datab[LPM_WIDTH-(BLOCKS-1)*8-1..0] = datab_node[LPM_WIDTH-1..(BLOCKS-1)*8];
adder[BLOCKS-1].cin = look_aheader.cout[BLOCKS-1];
result_node[LPM_WIDTH-1..(BLOCKS-1)*8] = adder[BLOCKS-1].result[LPM_WIDTH-(BLOCKS-1)*8-1..0];
look_aheader.cin = cin_node;
look_aheader.bg_in[] = adder[].bg_out;
look_aheader.bp_in[] = adder[].bp_out;
IF USED(cout) # USED(overflow) GENERATE
IF LPM_WIDTH MOD 8 == 0 GENERATE
cout_node = adder[BLOCKS-1].cout;
ELSE GENERATE
cout_node = adder[BLOCKS-1].result[LPM_WIDTH MOD 8];
END GENERATE;
ELSE GENERATE
cout_node = GND;
END GENERATE;
END GENERATE;
-- overflow detection
IF (LPM_REPRESENTATION == "SIGNED") GENERATE
-- SIGNED overflow: TRUE when MSB(a) & MSB(b) are same but MSB(result) is different.
IF (LPM_DIRECTION == "SUB") GENERATE -- Special case (can't tell from add_sub pin)
oflow_ext_latency_ffs.data[] = !(dataa[LPM_WIDTH-1] !$ datab[LPM_WIDTH-1]) &
(dataa[LPM_WIDTH-1] $ result_node[LPM_WIDTH-1]);
ELSE GENERATE
oflow_ext_latency_ffs.data[]= !(dataa[LPM_WIDTH-1] $ (datab[LPM_WIDTH-1] $ !add_sub)) &
(dataa[LPM_WIDTH-1] $ result_node[LPM_WIDTH-1]);
END GENERATE;
ELSE GENERATE
-- UNSIGNED overflow calc: TRUE when carry out during add or underflow during sub
IF (LPM_DIRECTION == "SUB") GENERATE -- Special case (can't tell from add_sub pin)
oflow_ext_latency_ffs.data[]= !cout_node;
ELSE GENERATE
oflow_ext_latency_ffs.data[]= !add_sub $ cout_node;
END GENERATE;
END GENERATE;
END GENERATE;
-- external latency connections
result_ext_latency_ffs.data[] = result_node[];
result[] = result_ext_latency_ffs.result[];
carry_ext_latency_ffs.data[] = cout_node;
cout = carry_ext_latency_ffs.result[];
overflow = oflow_ext_latency_ffs.result[];
IF EXT_LATENCY > 0 GENERATE
result_ext_latency_ffs.(clock, aclr) = (clock, aclr);
carry_ext_latency_ffs.(clock, aclr) = (clock, aclr);
oflow_ext_latency_ffs.(clock, aclr) = (clock, aclr);
IF USED(clken) GENERATE
result_ext_latency_ffs.clken = clken;
carry_ext_latency_ffs.clken = clken;
oflow_ext_latency_ffs.clken = clken;
END GENERATE;
END GENERATE;
END;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -