雙向電路設計經驗

admin @ 2014-03-26 , reply:0

概述
在工程應用中,雙向電路是設計者不得不面對的問題.在實際應用中,數據匯流排往往是雙向的.如何正確處理數據匯流排是進行時序邏輯電路設計的基礎.在程序設計過程中,關鍵技術在於:實體部分必須對埠屬性進行申明,……

在工程應用中,雙向電路是設計者不得不面對的問題.在實際應用中,數據匯流排往往是雙向的.如何正確處理數據匯流排是進行時序邏輯電路設計的基礎.在程序設計過程中,關鍵技術在於:實體部分必須對埠屬性進行申明,埠屬性必須為inout類型,在構造體需要對輸出信號進行有條件的高阻控制.在雙向電路的處理問題上,常用的處理方式有兩種,在介紹雙向電路的處理方式之前,先看看雙向電路的基本格式:

ENTITY bidir_pin IS
(
bidir : INOUT std_logic;
oe, clk, from_core : IN std_logic;
to_core : OUT std_logic;
……
END bidir_pin;

ARCHITECTURE behavior OF bidir_pin IS
BEGIN
bidir <= from_core WHEN oe=‘1’ ELSE “ZZZZ”;
to_core <= bidir;
_
_
_
END behavior;

  該程序揭示了雙向電路的處理技巧,首先在實體部分bidir屬於雙向信號,在埠定義時,埠屬性為inout類型,即把bidir信號作為輸入三態輸出. 語句“bidir <= from_core WHEN oe=‘1’ ELSE “ZZZZ”;”表示bidir信號三態輸出,語句”to_core <= bidir;”把bidir信號作為輸入信號.
 由此可見,雙向電路在程序設計中,didir輸入當著普通的in類型,而在輸出時,需要加一定的控制條件,三態輸出.問題的關鍵在於:如何確定這個條件?

1)雙向信號作一個信號的輸入,作另一信號的輸出

ENTITY bidir IS
PORT(
bidir : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0);
oe, clk : IN STD_LOGIC;
from_core : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
to_core : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END bidir;

ARCHITECTURE logic OF bidir IS
SIGNAL a : STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL b : STD_LOGIC_VECTOR (7 DOWNTO 0);
BEGIN
PROCESS (clk)
BEGIN
IF clk = '1' AND clk'EVENT THEN
a <= from_core;
to_core <= b;
END IF;
END PROCESS;

PROCESS (oe, bidir)
BEGIN
IF( oe = '0') THEN
bidir <= "ZZZZZZZZ";
b <= bidir;
ELSE
bidir <= a;
b <= bidir;
END IF;
END PROCESS;
END logic;

  這種設計方式叫做寄存雙向信號的方法.本設計中bidir為雙向信號,from_core為數據輸入端,to_core為數據輸出端,oe為三態輸出使能,clk為讀寫數據的時鐘.在程序設計中,需要定義兩個signal a和b信號.a信號用於輸入數據from_core的寄存器,b用於輸出數據to_core的寄存器.採用寄存器的方法需要設計兩個進程,一個進程把a, b信號在時鐘的控制下負責埠的輸入信號from_core和埠輸出信號to_core的連接,這一步實現了寄存雙向的功能.另外一個進程則負責信號 a,b和雙向口之間的賦值關係.本設計只揭示了簡單的雙向信號操作方式,即bidir既可以作為from_core的輸出,又可以作為to_core的輸入

2)雙向信號既做輸出又做輸出

上例是最簡單的雙向信號應用的特例.在實際的工程中,雙向信號既做信號的輸入,又做信號的輸出,常見的數據匯流排就是這種操作模式.

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity dir_data is
  port(
   clk : in STD_LOGIC;
   rst : in STD_LOGIC;
   rw : in STD_LOGIC;
   address : in STD_LOGIC_VECTOR(1 downto 0);
   data : inout STD_LOGIC_VECTOR(7 downto 0)
      );
end dir_data;

architecture arc_dir of dir_data is

signal data_in : STD_LOGIC_VECTOR(7 downto 0);
signal data_out: STD_LOGIC_VECTOR(7 downto 0);
signal reg_a: STD_LOGIC_VECTOR(7 downto 0);
signal reg_b: STD_LOGIC_VECTOR(7 downto 0);

begin  
 
 data_in<=data;
 
 d1:process(clk,rst,rw)
 begin
  if rst='1' then
   reg_a<= (others=>'0');
   reg_b<= (others=>'0');
  elsif clk'event and clk='1' then
   if rw='1' then
    if address="00" then 
     reg_a<=data_in;
    elsif address="01" then
     reg_b<=data_in;
    else null;
    end if;
   else null;
   end if;
  else null;
  end if;
  end process d1;

 d2:process(clk,rw,reg_a,reg_b)
 begin
 if clk'event and clk='1' then
  if rw='0' then
   if address="00" then
    data_out<=reg_a;
   elsif address="01" then
    data_out<=reg_b;
   else null;
   end if;
  else null;
  end if;
 else null;
 end if;
 end process d2;
 
 data<=data_out when (rw='0' and address(1)='0') else
   (others=>'Z');
 
end arc_dir;

  在程序設計中,首先需要定義data_in, data_out, reg_a, reg_b四個signal,我們把data_in叫做輸入寄存器,它是從雙向信號data接收數據的寄存器,data_out叫做輸出寄存器,它是向雙向信號data發送信號的寄存器,reg_a和reg_b叫做操作寄存器,它們是在一定的時序控制下把data_in數據送給reg_a,reg_b,在一定的時序控制下從reg_a和reg_b讀出數據的.
 這樣的處理方式必須有兩個進程,因為在architecture arc_dir of dir_data is和begin之間定義了data_in, data_out, reg_a, reg_b四個signal,它在同一進程內不支持既賦值,又調用,也就是說它不支持在d1進程中對信號reg_a, reg_b賦值,又在d1進程中又調用reg_a, reg_b.
首先有語句”data_in<=data;”它表示輸入寄存器無條件的接收雙先信號的數據.在d1進程中,首先在rst信號有效時,對操作寄存器reg_a,和reg_b進行清零操作,然後在時鐘(clk)的控制下,在寫 (rw)信號有效的情況下,對reg_a, reg_b寄存器在不同的地址控制下寫入不同的data_in值.在d2進程中,在時鐘(clk)的控制下,在讀(rw)信號有效的時候,把不同地址的 reg_a, reg_b的值送進data_out中.
最關鍵的是最後一句:“data<=data_out when (rw='0' and address(1)='0') else (others=>'Z');”它表示雙向信號的三態輸出,而最最關鍵的是when後面的條件,如果條件限制太寬,就會錯誤佔用雙向信號匯流排,引起匯流排的誤操作,如果條件限制太窄,輸出寄存器的數據就不能夠正確的送到數據匯流排上去,會引起數據的丟失.也就是說,只有正確的限制了when語句後面的條件,才能夠把輸出寄存器的數據正確地送到數據匯流排上去.仔細查看此條件,有如下的規律:when語句后的條件是操作寄存器寫入輸出寄存器的條件的公共條件.比如:rw=’0’是操作寄存器的數據寫入輸出寄存器的讀使能信號,address(1)是地址線的公共部分.在實際工程應用中,需要設計者在分配地址匯流排的時候掌握一定的技巧,盡量從地址的低位到到高位,保證地址匯流排有更多位的公共部分,比如只對四個寄存器操作時,地址線分配為”100”,” 010”,”110”,”001”是不科學的,而”000”,”001”,”010”和”011”則是理想的.兩者不同的是前者地址線沒有公共部分,這樣的設計無法用when語句對條件進行直接的控制,如果置之不理,由於列舉不全,在邏輯綜合時,電路會利用器件的乘積項和查找表的資源形成一個Latch, Latch不僅會把電路的時序變得複雜,而且電路存在潛在的危險性.雖然when語句后的條件不能夠對條件進行直接的控制,但是可以使用枚舉法一一把用到的地址線羅列出來,表示只有在這樣的地址線的情況下才會用到數據匯流排,否則其他狀態對數據匯流排送高阻,表示不佔用數據匯流排.
總而言之,雙向信號是程序設計中尤其重要的基礎,設計者在設計程序的時候,要尤其注意,何時會佔用數據匯流排,何時不佔用數據匯流排.




[admin via 研發互助社區 ] 雙向電路設計經驗已經有2843次圍觀

http://cocdig.com/docs/show-post-43518.html