2015年11月27日 星期五

Xilinx Vivado packaging IP 筆記



Reference
Vivado Design Suite Tutorial
Creating and Packaging Custom IP(UG1119)

除了IP本身的constraint以外,還需要另外準備一個out-of-context(OOC) constraintparent design來定義external clocking. 如果IP內的clocklocal或是經由IBUF,則寫在IP本身的constraint, 如果clock是由parent design 提供,則須寫在OOC constraint.這樣如果IP被別的設計引用,則會自動繼承parent design clock.
IMPORTANT: A synthesized design checkpoint (DCP) is created as part of the default Out-of-Context (OOC) design flow for IP packaging and use.

For more information on the Out-Of-Context (OOC) design flow, and the use of the DCP file, see the Vivado Design Suite User Guide: Designing with IP (UG896).

IPconstraint 會比top level先讀入,可以經由processing oder 來修改,但是如果在ip constraint中有set_max_delay則需要將processing oder 設為late
TIP: Xilinx delivered IP with “_clock” appended to the XDC filename are all marked for LATE processing.

寫完ooc constraint以後還要將屬性的used in 加入out_of_context(p.13)

IMPORTANT: The USED_IN property for an OOC XDC file should be {synthesis implementation out_of_context}. If it is just out_of_context, it is not used during synthesis or implementation.

2015年11月22日 星期日

VHDL read bmp image

Reference:
the same as in the reference, just only read

package 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

package bmp_read_package is
 
 constant cMAX_X : integer := 1300; -- 1280
 constant cMAX_Y : integer := 1300; -- 1024
 constant cBytesPerPixel : integer := 3;
 
 constant cMaxMemSize : integer := cMAX_X * cMAX_Y * cBytesPerPixel;

 subtype bmp_element is std_logic_vector(7 downto 0);
 type mem_array is array(cMaxMemSize downto 0) of bmp_element;
 type header_array is array(53 downto 0) of bmp_element;
 
 procedure ReadFile(FileName : in string);
 procedure ReadByteFromMemory(addr : in integer; variable data: out std_logic_vector(7 downto 0));
 
 function GetWidth(header        : in  header_array) return integer;
 procedure GetWidth(signal width : out integer);

 function GetHeight(header         : in  header_array) return integer;
 procedure GetHeight(signal height : out integer);
 
 procedure GetPixel(x : in integer; y : in integer; signal data : out std_logic_vector(23 downto 0));
 
end package bmp_read_package;

package body bmp_read_package is 

 shared variable memory_in : mem_array;
 shared variable memory_out : mem_array;
 shared variable header   : header_array;
 shared variable BmpSize   : integer;
 shared variable BmpWidth  : integer;
 shared variable BmpHeight  : integer;
 
 procedure ReadFile(FileName : in string) is
  variable next_vector : bit_vector(0 downto 0);
  variable actual_length : natural;
  variable index   : integer := 0;
  type bit_vector_file is file of bit_vector;
  file read_file   : bit_vector_file open read_mode is FileName;
  
 begin 
  report " Read File";
  report FileName;
  
  index := 0;
  
  report " Read Header";
  for i in 0 to 53 loop 
   read(read_file,next_vector,actual_length);
   if actual_length > next_vector'length then 
    report " vector too long";
   else 
    header(index) := conv_std_logic_vector(bit'pos(next_vector(0)),8);
    index    := index + 1 ;
   end if;
  end loop;

  BmpWidth  := GetWidth(header);
  BmpHeight  := GetHeight(header);
  BmpSize  := BmpWidth * BmpHeight;
 
  report " Read Image";
  index := 0;
  while not endfile(read_file) loop
   read(read_file,next_vector,actual_length);
   if actual_length > next_vector'length then 
    report " vector too long";
   else 
    memory_in(index) := conv_std_logic_vector(bit'pos(next_vector(0)),8);
    memory_out(index) := x"45";
    index := index + 1;
   end if;
  end loop;
  
  report "Okay";
 END ReadFile;
 
 procedure ReadByteFromMemory(addr : in integer; variable data : out std_logic_vector(7 downto 0)) is 
 begin 
  data := memory_in(addr);
 end ReadByteFromMemory;
 
 procedure GetPixel(x : in integer; y : in integer; signal data : out std_logic_vector(23 downto 0)) is
 begin 
  if( x >= 0 and x < cMAX_X ) and ( y >= 0 and y < cMAX_Y ) then 
   data(23 downto 16) <= memory_in(x*3 + 3*y*GetWidth(header));
   data(15 downto 8)  <= memory_in(x*3+1 + 3*y*GetWidth(header));
   data(7 downto 0)   <= memory_in(x*3+2 + 3*y*GetWidth(header));
     end if;
 end GetPixel;
 
    -- Get Width of Image
    function GetWidth(header : in header_array) return integer is
    begin
      return conv_integer(header(21) & header(20) & header(19) & header(18));
    end function GetWidth;
    
    procedure GetWidth(signal width : out integer) is
    begin
      width <= BmpWidth;
    end GetWidth;
    
    -- Get Height of Image
    function GetHeight(header : in header_array) return integer is
    begin
      return conv_integer(header(25) & header(24) & header(23) & header(22));
    end function GetHeight;
    
    procedure GetHeight(signal height : out integer) is
    begin
      height <= BmpHeight;
    end GetHeight;
 
end bmp_read_package;



Xilinx Vivado Timing Constraint 筆記


                  http://blog.xuite.net/bcshih.tw/jobs/201031160
                  Vivado Design Suite User Guide Using Constraints(UG903)


Xilinx 建議把timing constraint physical constraint 分開放在兩個sdc裡面,也可以同時設定多個constraint set,用設定target來指定目前使用的constraint,注意ip所使用的constraint會出現在ip自己的project裡面,不會出現在top level

Xdc file 也可以設定屬性,彈性的應用在synthesis或是implementation(source file property), 也可以在tcl中設定在synthesis前或synthesis

xdc中下的constraint需要依照下面的順序來寫, clock之前所設的constraint會變成error且會被忽略, 不同的constraint file不能具有相依性,如果兩個constraint file具有相依性,可以將其依照順序合寫成一個,或是分割成多個然後依照順序排列



Timing constraint要被排在第一位,並設為target


IP core裡面的constraint, 其比user constraint 先讀入,以便做為reference, IP core 也可以設定physical constraint,但是後來還是會被user constraint 覆寫, 例外情況為如果ip core引用clock object,其被user constraint 或是其他ip core所產生,則不會優先讀入, 譬如( for example, get_clocks -of_objects [get_ports clka])

在每個xdc file property中都可以選processing_order, 這個order只能在import或是create IP cores時決定,project建立以後即不能再更改.



User constraintIP constraint 的前後關係需如下



IOClock Planning可以從Layout-> I/O Planning/ Clock Planning來看
如果用constraints wizard來建立constraint,裡面就會自動排列正確的順序,但是如果要改的話,最好使用edit timing constraint來更改,如果有時候用手動更改,有時候用edit timing constraint,可能會造成系統混淆

注意 : 更改constraints以後,除了apply以外,一定要按Save,不然constraint不會被更改
IPconstraint不能被更改或是刪除,要把其disable,然後把ip constraint的內容複製到user constraint,才能被修改

Timing constraint 用在synthesis, physical and configuration constraint 用在implementation, 第一次建立xdc應該先簡單寫最上層的constraints,之後合成以後在慢慢調成符合timing requirement

Do not attach constraints to nets connecting combinatorial logic operators.
They will likely be merged into a LUT and disappear from the netlist.


在網路上找到一個解釋set_false_path, set_multicycle_path,max&min_delay 的部落格(reference),講解的太棒了,讓我一看就懂了
以下截取部落格內容
下面三個constraint是跳脫STA所產生的特殊情形

set_false_path  :
表示這路徑雖然存在,但是不會有人走過, 一旦路徑被設為false path, 不管slack為證或 
是為負,STA將不再回報,最常碰到的狀況是用來決定工作或是測試狀態的register(configuration register),所有系統的狀態都要等configuration register定値了以後才會動作,時脈路徑是存在的,也有信號傳輸,但是不需要達成timing上的要求,另一種狀況是兩個不同的clock domain之間,信號只需要傳輸,不需要及時,這種狀況要寫兩個constraint表示雙向,或是信號在兩個mux之中傳遞,以上這些狀況可以將其設回false path

Xilinx官方解釋,false path 的基本條件
(1)   Is not functional
(2)   Does not need to be timed

例如下面這些例子


set_multicycle_path :  見部落格的精闢叫車比喻,要小心本來應該設set_multicycle_path的路經被設為false path


如果一條timing path被重複設定,false path優先multicycle path,在優先於max&min delay