FC2カウンター FPGAの部屋 Altium でC to Hardware(ラプラシアンフィルタ)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Altium でC to Hardware(ラプラシアンフィルタ)

Altium でもう一度、C to Hardwareをやってみた。今度はラプラシアンフィルタを自分で作ってやってみた。

最初に、Cのコードを書いた。
Altium_Designer_C2H_25_120430.png

Cコードを下に示す。

#include <stdint.h>
#include <stdbool.h>

void Laplacian_filer(uint8_t x0y0, uint8_t x1y0, uint8_t x2y0, uint8_t x0y1, uint8_t x1y1, uint8_t x2y1, uint8_t x0y2, uint8_t x1y2, uint8_t x2y2, uint8_t * out_sig)
{
     int32_t temp;

     temp = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
     if (temp <0)
        *out_sig = 0;
     else if (temp>255)
        *out_sig = 255;
     else
        *out_sig = temp;
}


入力8ビット、出力8ビットにしてあるので、飽和演算を入れてある。

・ファイルメニュー -> 新規 -> 回路図 で新規回路図を作成した。

・デザインメニュー -> C言語からコードシンボル作成 でC言語のコードシンボルを作成した。

・ポートを置いて回路図を作成した。
Altium_Designer_C2H_26_120430.png

・最初は、Parallel Combinatorial でやってみたが、エラーだった。(”Altium Designer でC to Hardware のサンプルを試してみる2”を参照のこと)

やはり、自動変数のtemp を定義してしまっているので組み合わせ回路にならないのだろうか?

・前回同様、Parallel Multi-cycle で設定するとコンパイルができた。
Altium_Designer_C2H_24_120429.png

・ログを見ると、clock cycles は at leastとのことだった。一体何クロックかかるのだろうか?

・生成されたVHDLファイル(laplacian_filter_u_laplacian_filer.VHD)をISEのプロジェクトに入れて、インプリメントしてみた。使用FPGAは XC3S1400AN-FGG676-4。

・CLOCKのPERIOD制約を150MHzにしてみたが、結果はタイミングエラーだった。最小周期は9.439ns だったので100MHzでは動作する。

・テストベンチ(Laplacian_filter_tb.vhd) を作成して、シミュレーションを行った。
Laplacian_filter_tb.vhdを下に示す。

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY Laplacian_filter_tb IS
END Laplacian_filter_tb;
 
ARCHITECTURE behavior OF Laplacian_filter_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT Laplacian_filter_U_Laplacian_filer
    PORT(
         CLOCK : IN  std_logic;
         DONE : OUT  std_logic;
         RESET : IN  std_logic;
         RESET_DONE : OUT  std_logic;
         START : IN  std_logic;
         out_sig : OUT  std_logic_vector(7 downto 0);
         x0y0 : IN  std_logic_vector(7 downto 0);
         x0y1 : IN  std_logic_vector(7 downto 0);
         x0y2 : IN  std_logic_vector(7 downto 0);
         x1y0 : IN  std_logic_vector(7 downto 0);
         x1y1 : IN  std_logic_vector(7 downto 0);
         x1y2 : IN  std_logic_vector(7 downto 0);
         x2y0 : IN  std_logic_vector(7 downto 0);
         x2y1 : IN  std_logic_vector(7 downto 0);
         x2y2 : IN  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
    

   --Inputs
   signal CLOCK : std_logic := '0';
   signal RESET : std_logic := '0';
   signal START : std_logic := '0';
   signal x0y0 : std_logic_vector(7 downto 0) := (others => '0');
   signal x0y1 : std_logic_vector(7 downto 0) := (others => '0');
   signal x0y2 : std_logic_vector(7 downto 0) := (others => '0');
   signal x1y0 : std_logic_vector(7 downto 0) := (others => '0');
   signal x1y1 : std_logic_vector(7 downto 0) := (others => '0');
   signal x1y2 : std_logic_vector(7 downto 0) := (others => '0');
   signal x2y0 : std_logic_vector(7 downto 0) := (others => '0');
   signal x2y1 : std_logic_vector(7 downto 0) := (others => '0');
   signal x2y2 : std_logic_vector(7 downto 0) := (others => '0');

     --Outputs
   signal DONE : std_logic;
   signal RESET_DONE : std_logic;
   signal out_sig : std_logic_vector(7 downto 0);

   -- Clock period definitions
   constant CLOCK_period : time := 10 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: Laplacian_filter_U_Laplacian_filer PORT MAP (
          CLOCK => CLOCK,
          DONE => DONE,
          RESET => RESET,
          RESET_DONE => RESET_DONE,
          START => START,
          out_sig => out_sig,
          x0y0 => x0y0,
          x0y1 => x0y1,
          x0y2 => x0y2,
          x1y0 => x1y0,
          x1y1 => x1y1,
          x1y2 => x1y2,
          x2y0 => x2y0,
          x2y1 => x2y1,
          x2y2 => x2y2
        );

   -- Clock process definitions
   CLOCK_process :process
   begin
        CLOCK <= '0';
        wait for CLOCK_period/2;
        CLOCK <= '1';
        wait for CLOCK_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin
      RESET <= '1';
      START <= '0';
      x0y0 <= CONV_STD_LOGIC_VECTOR(0, 8);
      x1y0 <= CONV_STD_LOGIC_VECTOR(10, 8);
      x2y0 <= CONV_STD_LOGIC_VECTOR(20, 8);
      x0y1 <= CONV_STD_LOGIC_VECTOR(30, 8);
      x1y1 <= CONV_STD_LOGIC_VECTOR(40, 8);
      x2y1 <= CONV_STD_LOGIC_VECTOR(50, 8);
      x0y2 <= CONV_STD_LOGIC_VECTOR(60, 8);
      x1y2 <= CONV_STD_LOGIC_VECTOR(70, 8);
      x2y2 <= CONV_STD_LOGIC_VECTOR(80, 8);
      -- hold reset state for 100 ns.
      wait for 100 ns;    

      wait for CLOCK_period*10;

      -- insert stimulus here 
      RESET <= '0';
      wait for CLOCK_period;
      
      for i in 1 to 10 loop
          START <= '1';
          wait for CLOCK_period;
          START <= '0';
          wait for CLOCK_period*5;
          x0y0 <= x0y0;
          x1y0 <= x1y0;
          x2y0 <= x2y0;
          x0y1 <= x0y1;
          x1y1 <= x1y1 + i;
          x2y1 <= x2y1;
          x0y2 <= x0y2;
          x1y2 <= x1y2;
          x2y2 <= x2y2;
      end loop;

      wait;
   end process;

END;


.ISim でシミュレーションした結果を下に示す。
Altium_Designer_C2H_27_120430.png

ラプラシアンフィルタの演算に5クロックかかっているようだ。
  1. 2012年04月30日 05:55 |
  2. Altium Designer
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/2127-cccb139e
この記事にトラックバックする(FC2ブログユーザー)