keep_hierarchy約束在三模冗餘中的應用

節選自《FPGA之道》

keep_hierarchy是一個綜合和實現方面的約束。Xilinx的綜合工具XST更傾向於平化HDL代碼的層級結構,即將一級級的模塊調用機制轉換爲一個沒有子模塊的超大模塊,這樣做的好處是能夠進行更好地設計優化工作,因爲平化操作去除了原有實體或模塊之間的邊界限制。
不過有些時候,XST的這種平化工作是我們所不希望的,這時keep_hierarchy語法便派上了用場。使用keep_hierarchy約束能夠使綜合工具保留指定部分的層級關係,這樣一來,在後續的實現階段也將保留這種層級關係。與此同時,也可以生成用於仿真的具有層級關係的網表。下圖就很形象地說明了使用keep_hierarchy約束和不使用keep_hierarchy約束在綜合及實現後的區別。

下面列舉出在HDL中嵌人keep_hierarchy約束的語法:

--VHDL syntax
--第一步,先要聲明keep_hierarchy約束;
attribute keep_hierarchy:string;
--第二步,爲keep_hierarchy語法指定約束線網名稱和屬性取值;
attribute keep_hierarchy of <architecture_name>:architecture is "{TRUE | FALSE | SOFT}";
//Verilog syntax
(*KEEP_HIERARCHY=“{TRUE | FALSE | SOFT}”*)
//上述約束會作用於緊隨其後調用的模塊

從上述語法可以看出,keep_hierarchy約束具有三種屬性值,其中false自然是不保留層級關係,而true和soft的區別就是,true會將這種約束傳遞給後續的實現環節,而soft則僅僅是在綜合環節保留層級關係。
下面給出一個利用keep_hierarchy實現三模冗餘D的示例:

三模冗餘是航空、航天系統中經常用到的一種技術。簡要來說,由於空間中的射線等原因,會有一定機率引起電子產品尤其是基於SRAM的FPGA發生一種稱做“單粒子翻轉”的效應。“單粒子翻轉”即1變成0、0變成1,這樣將會導致系統運行出錯。因此,爲了提高系統的穩定性和可靠性,人們想了很多種方法來應對空間中較爲惡劣的工作環境,其中一種就是三模冗餘,即通過3倍的冗餘,結合3中取2的少數服從多數仲裁機制,來提高FPGA設計的抗干擾能力。

--VHDL example
--file lock.vhd
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY lock IS
    PORT (
        clk : IN STD_LOGIC;
        rst : IN STD_LOGIC;
        din : IN STD_LOGIC;
        dout : OUT STD_LOGIC
    );
END lock;
ARCHITECTURE Behavioral OF lock IS
BEGIN
    PROCESS (clk)
    BEGIN
        IF (clk'event AND clk = '1') THEN
            IF (rst = '1') THEN
                dout <= '0';
            ELSE
                dout <= din;
            END IF;
        END IF;
    END PROCESS;
END Behavioral;

--file mode3.vhd
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY mode3 IS
    PORT (
        clk : IN STD_LOGIC;
        rst : IN STD_LOGIC;
        din : IN STD_LOGIC;
        dout : OUT STD_LOGIC
    );
END mode3;
ARCHITECTURE Behavioral OF mode3 IS
    SIGNAL a, b, c : STD_LOGIC;
    COMPONENT lock
        PORT (
            clk : IN STD_LOGIC;
            rst : IN STD_LOGIC;
            din : IN STD_LOGIC;
            dout : OUT STD_LOGIC
        );
    END COMPONENT;
    ATTRIBUTE keep_hierarchy : STRING;
    ATTRIBUTE keep_hierarchy OF m0 : ARCHITECTURE IS "TRUE";
    ATTRIBUTE keep_hierarchy OF m1 : ARCHITECTURE IS "TRUE";
    ATTRIBUTE keep_hierarchy OF m2 : ARCHITECTURE IS "TRUE";
BEGIN
    m0 : lock
    PORT MAP(
        clk => clk,
        rst => rst,
        din => din,
        dout => a
    );
    m1 : lock
    PORT MAP(
        clk => clk,
        rst => rst,
        din => din,
        dout => b
    );
    m2 : lock
    PORT MAP(
        clk => clk,
        rst => rst,
        din => din,
        dout => c
    );
    -- ATTRIBUTE keep_hierarchy : STRING;
    -- ATTRIBUTE keep_hierarchy OF m0 : ARCHITECTURE IS "TRUE";
    -- ATTRIBUTE keep_hierarchy OF m1 : ARCHITECTURE IS "TRUE";
    -- ATTRIBUTE keep_hierarchy OF m2 : ARCHITECTURE IS "TRUE";
    PROCESS (clk)
    BEGIN
        IF (clk'event AND clk = '1') THEN
            IF (rst = '1') THEN
                dout <= '0';
            ELSE
                IF (b /= c) THEN
                    dout <= a;
                ELSE
                    dout <= b;
                END IF;
            END IF;
        END IF;
    END PROCESS;
END Behavioral;

採用上例這種keep_hierarchy的約束添加方式,就可以成功確保在FPGA中實現了三個功能一模一樣的模塊。否則,由於這三個模塊在功能上面完全等價,編譯器便會優化掉其中的兩個,而最終只保留一個模塊,但是這樣就無法實現“三模冗餘”的保護功能了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章