FC2カウンター FPGAの部屋 2010年10月

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

FPGAの部屋

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

2進数からBCDへの変換回路(まとめ)

2進数からBCDへの変換回路1”の続き。この前、お恥ずかしい自分の回路を公開してから、いろんなかたに変換回路を紹介していただいた。やはり、アルゴリズムが大事だな、ということを実感した。

すべての回路のFPGAはSpartan-3E-500(xc3s5000e-4pq208)を使用して、ISE12.3でインプリメントし、使用ロジックを調べた。(動作周波数は調べていない)それから、ISimでシミュレーションしてみた。

・武内さんの回路
まずは、武内さんの回路からやってみることにした。2進数10ビット、BCD4桁の設定でのインプリメント結果を下に示す。
Takeuchi_1_101030.png

Number of Slice Flip Flopsが42、Number of 4 input LUTsが83、Number of occupied Slicesが49だった。
次に、付属のテストベンチでシミュレーションしてみた。
Takeuchi_2_101030.png

レイテンシは、25クロックだった。

・Sさんの回路
次にコメントで教えていただいたSさんの回路を検証してみる。2進数10ビット、BCD3桁だ。
下にVerilogコードを表示させていただきます。

module bin2bcd (clk, bin, bcd); 
    input clk; 
    input [ 9:0] bin; 
    output [15:0] bcd; 

    wire [13:0] k3; 
    reg [13:0] k3b; 
    reg [ 3:0] d32; 
    reg [ 3:0] d31; 
    reg [ 3:0] d30; 
    wire [13:0] k2; 
    reg [13:0] k2b; 
    reg [ 3:0] d21; 
    reg [ 3:0] d20; 
    wire [13:0] k1; 
    reg [ 3:0] d10; 
    reg [ 3:0] d00; 

    assign k3 = bin + bin[9:6] + bin[9:7] + bin[9] + 1'b1; 
    always @(posedge clk) d32 <= k3[13:10]; 
    always @(posedge clk) k3b <= bin - (k3[13:10] * 1000); 

    assign k2 = k3b * 10 + k3b[13:2]; 
    always @(posedge clk) d21 <= k2[13:10]; 
    always @(posedge clk) k2b <= k3b - (k2[13:10] * 100); 
    always @(posedge clk) d31 <= d32; 

    assign k1 = k2b * 102 + k2b[13:1]; 
    always @(posedge clk) d00 <= k2b - (k1[13:10] * 10); 
    always @(posedge clk) d10 <= k1[13:10]; 
    always @(posedge clk) d20 <= d21; 
    always @(posedge clk) d30 <= d31; 

    assign bcd = {d30,d20,d10,d00}; 
endmodule 


2進数10ビット、BCD3桁でのインプリメント結果を下に示す。
S_1_101030.png

Number of Slice Flip Flopsが41、Number of 4 input LUTsが73、Number of occupied Slicesが51だった。
自分でテストベンチを書いてシミュレーションしてみた。下にテストベンチを示す。

`timescale 1ns / 1ps

module bin2bcd_tb;

    // Inputs
    reg clk;
    reg [9:0] bin;

    // Outputs
    wire [15:0] bcd;
    
    parameter CLK_PERIOD = 10;
    integer i, j;

    // Instantiate the Unit Under Test (UUT)
    bin2bcd uut (
        .clk(clk), 
        .bin(bin), 
        .bcd(bcd)
    );

    always begin // clk
       #(CLK_PERIOD/2)    clk = 1'b1 ;
       #(CLK_PERIOD/2)    clk = 1'b0 ;
    end

    initial begin
        // Initialize Inputs
        bin = 0;

        // Add stimulus here
        for (i=0; i<=1000; i=i+1) begin
            @(posedge clk);
            #1;
            bin = i;
            for (j=0; j<=3; j=j+1) begin
                @(posedge clk);
                #1;
            end
        end
        #50;
        $stop;
    end
      
endmodule


ISimでのシミュレーション画面を下に示す。
S_2_101030.png

レイテンシは3クロックだった。

・ame_feb4さんに教えていただいた回路
次にツイッターでame_feb4さんに教えていただいたConverionsのページだ。
2進数10ビット、BCD3桁のbin2bcd.vhdを作成した。下に示す。

-- bin2bcd.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity bin2bcd is
    port(
        clk : in std_logic;
        reset : in std_logic;
        din : in std_logic_vector(9 downto 0);
        load : in std_logic;
        bcd_out : out std_logic_vector(11 downto 0);
        done : out std_logic
    );
end bin2bcd;

architecture RTL of bin2bcd is
component BcdDigit
    Port ( Clk :    in  STD_LOGIC;
           Init :   in  STD_LOGIC;
           DoneIn:  in  STD_LOGIC;
           ModIn :  in  STD_LOGIC;
           ModOut : out  STD_LOGIC;
           Q :      out  STD_LOGIC_VECTOR (3 downto 0));
end component;
signal shift_reg : std_logic_vector(9 downto 0);
signal count : std_logic_vector(3 downto 0);
signal done_node : std_logic;
signal modout0, modout1 : std_logic;
begin
    -- 3つのBcdDigit をインスタンス
    BcdDigit0 : BcdDigit port map(
        Clk => clk,
        Init => reset,
        DoneIn => done_node,
        ModIn => shift_reg(9),
        ModOut => modout0,
        Q => bcd_out(3 downto 0)
    );
    BcdDigit1 : BcdDigit port map(
        Clk => clk,
        Init => reset,
        DoneIn => done_node,
        ModIn => modout0,
        ModOut => modout1,
        Q => bcd_out(7 downto 4)
    );
    BcdDigit2 : BcdDigit port map(
        Clk => clk,
        Init => reset,
        DoneIn => done_node,
        ModIn => modout1,
        ModOut => open,
        Q => bcd_out(11 downto 8)
    );
    
    -- shift_reg
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                shift_reg <= (others => '0');
            else
                if load='1' then
                    shift_reg <= din;
                else
                    shift_reg <= shift_reg(8 downto 0) & '0';
                end if;
            end if;
        end if;
    end process;
    
    -- Doneを制御する
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                count <= (others =>'0');
            else
                if load='1' then
                    count <= (others => '0');
                elsif unsigned(count) <= 10 then
                    count <= count + 1;
                end if;
            end if;
        end if;
    end process;
    
    done_node <= '1' when count=10 else '0';
    done <= done_node;
end RTL;


これでインプリメントして、インプリメント結果を下に示す。
ame_feb4_1_101030.png

Number of Slice Flip Flopsが26、Number of 4 input LUTsが31、Number of occupied Slicesが17だった。
次に、テストベンチを作った。下に示す。

-- bin2bcd_tb.vhd

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
 
ENTITY bin2bcd_tb IS
END bin2bcd_tb;
 
ARCHITECTURE behavior OF bin2bcd_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT bin2bcd
    PORT(
            clk : in std_logic;
            reset : in std_logic;
            din : in std_logic_vector(9 downto 0);
            load : in std_logic;
            bcd_out : out std_logic_vector(11 downto 0);
            done : out std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
   signal reset : std_logic := '0';
   signal din : std_logic_vector(9 downto 0) := (others => '0');
   signal load : std_logic := '0';

     --Outputs
   signal bcd_out : std_logic_vector(11 downto 0) := (others => '0');
   signal done : std_logic := '0';

   -- Clock period definitions
   constant clk_period : time := 10 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: bin2bcd PORT MAP (
          clk => clk,
          reset => reset,
          din => din,
          load => load,
          bcd_out => bcd_out,
          done => done
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin        
        -- hold reset state for 100 ns.
        reset <= '1';
        wait for 100 ns;    
        reset <= '0'; 
        wait for clk_period*10;

        -- insert stimulus here 
        STIMULUS_LOOP : for i in 0 to 1000 loop
            wait until clk'event and clk='1';
            wait for 1 ns;
            din <= CONV_STD_LOGIC_VECTOR(i, 10);
            reset<='1';
            wait until clk'event and clk='1';
            wait for 1 ns;
            load <= '1'; reset<='0';
            wait until clk'event and clk='1';
            wait for 1 ns;
            load <= '0';
            TRANS_WAIT_LOOP : for j in 0 to 9 loop -- 11クロックwait
                wait until clk'event and clk='1';
                wait for 1 ns;
            end loop TRANS_WAIT_LOOP;
        end loop STIMULUS_LOOP;    
        
        wait for clk_period*10;
        assert (false) report "Simulation End!" severity failure;
   end process;

END;


ISimでのシミュレーション結果を下に示す。
ame_feb4_2_101030.png

レイテンシは11クロックだった。

・Sさんに教えていただいた回路
Sさんにブログのコメントで教えていただいた回路をやってみた。
インプリメント結果を下に示す。
fpgaz_1_101030.png

Number of 4 input LUTsが138、Number of occupied Slicesが76だった。
自分でテストベンチを書いた。テストベンチを下に示す。

module bin2bcd_m16_tb;

    // Inputs
    reg [15:0] bin_in;

    // Outputs
    wire [15:0] bcd_out;

    parameter CLK_PERIOD = 10;
    integer i;
    reg clk;

    // Instantiate the Unit Under Test (UUT)
    bin2bcd_m16 uut (
        .bin_in(bin_in), 
        .bcd_out(bcd_out)
    );
    
    always begin // clk
       #(CLK_PERIOD/2)    clk = 1'b1 ;
       #(CLK_PERIOD/2)    clk = 1'b0 ;
    end

    initial begin
        // Initialize Inputs
        bin_in = 0;

        // Wait 100 ns for global reset to finish
        #100;
        
        // Add stimulus here
        for (i=0; i<=1000; i=i+1) begin
            @(posedge clk);
            #1;
            bin_in = i;
        end
        #50;
        $stop;

    end
      
endmodule


シミュレーション結果を下に示す。
fpgaz_2_101030.png

レイテンシは0クロックだ。つまり組み合わせ回路だ。
  1. 2010年10月30日 17:06 |
  2. IP
  3. | トラックバック:0
  4. | コメント:6

PlanAheadのチュートリアルをやってみた

PlanAheadのチュートリアルをやってみました。
行ったチュートリアルは12.2の”PlanAhead チュートリアル : RTLデザインとCORE GeneratorでのIP生成”です。PlanAhead 12.3を使ってやってみました。12.3のチュートリアルは英語だったので、ほとんど変わらない(たぶん)12.2のを使ってやってみました。やってみたら、いろいろな機能があって、やはり、Project NavigatorからPlanAheadでやるのが主流になるんだろうな?と思いました。いろいろ細かく情報が出てきます。例えば、”PlanAhead チュートリアル : RTLデザインとCORE GeneratorでのIP生成”の27ページの”リソース使用率と電力の概算”でリソース使用率の概算が各モジュールごとに詳しい内訳が出るのが良いと思いました。31ページのRTL DRCも良いです。ラッチが生成されていたらWarningを出してくれます。LINTチェックのようなことをしてくれる機能です。
もう少しPlanAheadのチュートリアルをやってみようと思います。

オプションを設定するのが面倒かもしれませんが、一時中止した”PlanAhead12.3でCreate New Projectしてみる2(一時休止)”も再開してみようかと思っています。
  1. 2010年10月29日 06:04 |
  2. PlanAheadについて
  3. | トラックバック:0
  4. | コメント:0

2進数からBCDへの変換回路

必要があって10ビットの2進数から3桁のBCD(Binary-coded decimal)への変換回路を作りました。
私はビットごとに+6補正を入れながら、足していきました。変換するに11クロックです。
変換クロックに余裕があれば、BCDカウンタとバイナリカウンタ2つ作って、両方をカウントアップしていって、バイナリカウンタと10ビットの2進数が同じになったところの、BCDカウンタの値を使っても良いと思います。
武内さんから、10のn乗で割っていく方式を教えてくださいました。ありがとうございました。
自分のVHDLコードもブログに貼っておきます。

#使いものにならないよ。どうしてこんなコードを書いたの?とか、厳しい御指導があるかと思いますが、どうぞお手柔らかにお願いします。

-- Binary to Decimal Test

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity binary_decimal_test is
    port(
        clk : in std_logic;
        reset : in std_logic;
        complete : in std_logic;
        latched_quotient : in std_logic_vector(9 downto 0);
        persent : out std_logic_vector(11 downto 0)
    );
end binary_decimal_test;

architecture RTL of binary_decimal_test is
signal persent_node : std_logic_vector(11 downto 0);
type binary_decimal_state is (idle_bds, state_0, state_1, state_2, state_3, state_4, state_5, state_6, state_7, state_8, state_9, state_10, val_valid);
signal cs_bds : binary_decimal_state;
type complete_state is (idle_comp, divide_complete);
signal cs_div : complete_state;
begin
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                cs_div <= idle_comp;
            else
                case cs_div is
                    when idle_comp =>
                        if complete='1' then
                            cs_div <= divide_complete;
                        end if;
                    when divide_complete =>
                        cs_div <= idle_comp;
                end case;
            end if;
        end if;
    end process;
    
    -- 2進化10進用ステートマシン
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                cs_bds <= idle_bds;
            else
                case cs_bds is
                    when idle_bds =>
                        if cs_div = divide_complete then
                            if unsigned(latched_quotient)>999 then -- 999以上は999と表示する
                                cs_bds <= state_9;
                            else
                                cs_bds <= state_0;
                            end if;
                        end if;
                    when state_0 =>
                        cs_bds <= state_1;
                    when state_1 =>
                        cs_bds <= state_2;
                    when state_2 =>
                        cs_bds <= state_3;
                    when state_3 =>
                        cs_bds <= state_4;
                    when state_4 =>
                        cs_bds <= state_5;
                    when state_5 =>
                        cs_bds <= state_6;
                    when state_6 =>
                        cs_bds <= state_7;
                    when state_7 =>
                        cs_bds <= state_8;
                    when state_8 =>
                        cs_bds <= state_9;
                    when state_9 =>
                        cs_bds <= state_10;
                    when state_10 =>
                        cs_bds <= val_valid;
                    when val_valid => -- present_nodeの値が有効
                        cs_bds <= idle_bds;
                end case;
            end if;
        end if;
    end process;
    
    -- 10進数変換用のテーブル
    
    -- 割り算で導き出したパーセンテージを10進にする
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                persent_node <= (others => '0');
            else
                case cs_bds is
                    when state_0 =>
                        if latched_quotient(0)='1' then
                            persent_node <= "000000000001";
                        else
                            persent_node <= (others => '0');
                        end if;
                    when state_1 => 
                        if latched_quotient(1)='1' then
                            persent_node <= persent_node + 2;
                        else
                            persent_node <= persent_node;
                        end if;
                    when state_2 =>
                        if latched_quotient(2)='1' then
                            persent_node <= persent_node + 4;
                        else
                            persent_node <= persent_node;
                        end if;
                    when state_3 =>
                        if latched_quotient(3)='1' then
                            persent_node <= persent_node + 8;
                        else
                            persent_node <= persent_node;
                        end if;
                    when state_4 =>
                        if unsigned(persent_node(3 downto 0))>9 then -- 前までの総計15
                            if latched_quotient(4)='1' then
                                persent_node <= persent_node + x"01C"; -- +6+16
                            else
                                persent_node <= persent_node + x"006"; -- +6
                            end if;
                        else
                            if latched_quotient(4)='1' then 
                                persent_node <= persent_node + x"016";
                            else
                                persent_node <= persent_node;
                            end if;
                        end if;
                    when state_5 =>
                        if unsigned(persent_node(3 downto 0))>9 then -- 前までの総計は31
                            if latched_quotient(5)='1' then
                                persent_node <= persent_node + x"038"; -- +6+32
                            else
                                persent_node <= persent_node + x"006"; -- +6
                            end if;
                        else
                            if latched_quotient(5)='1' then 
                                persent_node <= persent_node + x"032";
                            else
                                persent_node <= persent_node;
                            end if;
                        end if;
                    when state_6 =>
                        if unsigned(persent_node(3 downto 0)) >9 then -- 前までの総計は63
                            if latched_quotient(6)='1' then
                                persent_node <= persent_node + x"06A"; -- +6+64
                            else
                                persent_node <= persent_node + x"006"; -- +6
                            end if;
                        else
                            if latched_quotient(6)='1' then 
                                persent_node <= persent_node + x"064";
                            else
                                persent_node <= persent_node;
                            end if;
                        end if;
                    when state_7 => -- 前までの総計は127
                        if unsigned(persent_node(3 downto 0)) >9 then
                            if unsigned(persent_node(7 downto 4)) >9 then
                                if latched_quotient(7)='1' then
                                    persent_node <= persent_node + x"18E"; -- +6+60+128=18E
                                else
                                    persent_node <= persent_node + x"066"; -- +6+60
                                end if;
                            else -- +6補正のみ
                                if latched_quotient(7)='1' then
                                    persent_node <= persent_node + x"12E"; -- +6+128
                                else
                                    persent_node <= persent_node + x"006"; -- +6
                                end if;
                            end if;
                        else
                            if unsigned(persent_node(7 downto 4)) >9 then
                                if latched_quotient(7)='1' then
                                    persent_node <= persent_node + x"188"; -- +60+128=18E
                                else
                                    persent_node <= persent_node + x"060"; -- +60
                                end if;
                            else
                                if latched_quotient(7)='1' then
                                    persent_node <= persent_node + x"128"; -- +128
                                else
                                    persent_node <= persent_node;
                                end if;
                            end if;
                        end if;
                    when state_8 => -- 前までの総計は255
                        if unsigned(persent_node(3 downto 0)) >9 then
                            if unsigned(persent_node(7 downto 4)) >9 then
                                if latched_quotient(8)='1' then
                                    persent_node <= persent_node + x"2BC"; -- +6+60+256=2BC
                                else
                                    persent_node <= persent_node + x"066"; -- +6+60
                                end if;
                            else -- +6補正のみ
                                if latched_quotient(8)='1' then
                                    persent_node <= persent_node + x"25C"; -- +6+256
                                else
                                    persent_node <= persent_node + x"006"; -- +6
                                end if;
                            end if;
                        else
                            if unsigned(persent_node(7 downto 4)) >9 then
                                if latched_quotient(8)='1' then
                                    persent_node <= persent_node + x"2B6"; -- +60+256=2B6
                                else
                                    persent_node <= persent_node + x"060"; -- +60
                                end if;
                            else
                                if latched_quotient(8)='1' then
                                    persent_node <= persent_node + x"256"; -- +256
                                else
                                    persent_node <= persent_node;
                                end if;
                            end if;
                        end if;
                    when state_9 => -- 前までの総計は511
                        if unsigned(latched_quotient)>999 then -- 999よりも大きい
                            persent_node <= "100110011001"; -- 999
                        else
                            if unsigned(persent_node(3 downto 0)) >9 then
                                if unsigned(persent_node(7 downto 4)) >9 then
                                    if latched_quotient(9)='1' then
                                        persent_node <= persent_node + x"578"; -- +6+60+512=578
                                    else
                                        persent_node <= persent_node + x"066"; -- +6+60
                                    end if;
                                else -- +6補正のみ
                                    if latched_quotient(9)='1' then
                                        persent_node <= persent_node + x"518"; -- +6+512
                                    else
                                        persent_node <= persent_node + x"006"; -- +6
                                    end if;
                                end if;
                            else
                                if unsigned(persent_node(7 downto 4)) >9 then
                                    if latched_quotient(9)='1' then
                                        persent_node <= persent_node + x"572"; -- +60+512=572
                                    else
                                        persent_node <= persent_node + x"060"; -- +60
                                    end if;
                                else
                                    if latched_quotient(9)='1' then
                                        persent_node <= persent_node + x"512"; -- +512
                                    else
                                        persent_node <= persent_node;
                                    end if;
                                end if;
                            end if;
                        end if;
                    when state_10 => -- 10進補正のみ
                            if unsigned(persent_node(3 downto 0)) >9 then
                                if unsigned(persent_node(7 downto 4)) >9 or (unsigned(persent_node(3 downto 0)) >9 and unsigned(persent_node(7 downto 4))=9) then -- 桁が上がって2桁目がAになる時も+66補正をする
                                    persent_node <= persent_node + x"066"; -- +6+60
                                else -- +6補正のみ
                                    persent_node <= persent_node + x"006"; -- +6
                                end if;
                            else
                                if unsigned(persent_node(7 downto 4)) >9 then
                                    persent_node <= persent_node + x"060"; -- +60
                                else
                                    persent_node <= persent_node;
                                end if;
                            end if;
                    when others =>
                        persent_node <= persent_node;
                end case;
            end if;
        end if;
    end process;
   
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                persent <= (others => '0');
            else
                if cs_bds=val_valid then
                    persent <= persent_node;
                end if;
            end if;
        end if;
    end process;
            
end RTL;



テストベンチのVHDLコードも下に貼っておきます。

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
 
ENTITY binary_decimal_test_tb IS
END binary_decimal_test_tb;
 
ARCHITECTURE behavior OF binary_decimal_test_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT binary_decimal_test
    PORT(
         clk : IN  std_logic;
         reset : IN  std_logic;
         complete : IN  std_logic;
         latched_quotient : IN  std_logic_vector(9 downto 0);
         persent : OUT  std_logic_vector(11 downto 0)
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
   signal reset : std_logic := '0';
   signal complete : std_logic := '0';
   signal latched_quotient : std_logic_vector(9 downto 0) := (others => '0');

     --Outputs
   signal persent : std_logic_vector(11 downto 0);

   -- Clock period definitions
   constant clk_period : time := 40 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: binary_decimal_test PORT MAP (
          clk => clk,
          reset => reset,
          complete => complete,
          latched_quotient => latched_quotient,
          persent => persent
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin        
        -- hold reset state for 100 ns.
        reset <= '1';
        wait for 100 ns;    
        reset <= '0';
        wait for clk_period*10;

        -- insert stimulus here 
        STIMULUS_LOOP : for i in 0 to 1000 loop
            wait until clk'event and clk='1';
            wait for 1 ns;
            latched_quotient <= CONV_STD_LOGIC_VECTOR(i, 10);
            complete <= '1';
            wait until clk'event and clk='1';
            wait for 1 ns;
            complete <= '0';
            TRANS_WAIT_LOOP : for j in 0 to 10 loop -- 11クロックwait
                wait until clk'event and clk='1';
                wait for 1 ns;
            end loop TRANS_WAIT_LOOP;
        end loop STIMULUS_LOOP;    
        
        wait for clk_period*10;
        assert (false) report "Simulation End!" severity failure;
   end process;

END;


このVHDLコードをISE12.3、Spartan3E-500でインプリメントしたところ、60スライス、91LUTでした。
binary_decimal_101027.png
  1. 2010年10月27日 10:59 |
  2. IP
  3. | トラックバック:0
  4. | コメント:4

AlteraのFPGAでのクロック出力とデータ出力3(Assignment Editorを使ってみる2)

AlteraのFPGAでのクロック出力とデータ出力2(Assignment Editorを使ってみる1)”では、Assignment Editorを使用してFAST_OUTPUT_REGISTER属性を入れてみた。今回は、FAST_INPUT_REGISTER属性を試してみることにする。(Quartus II 10.0 SP1を使用)

前回同様に、Assignment Editorで、今度はdinにFast input Registerを設定する。下が設定している途中。
CLK_DATA_test_21_101026.png

Createボタンをクリックすると、8ビットのdinにFast input Register属性が指定された。
CLK_DATA_test_22_101026.png

これでコンパイルして、din[0]を見てみると、I/Oセル内のレジスタが使われていなかった。
CLK_DATA_test_23_101026.png

実際にdin[0]がd0[0]にどうつながっているかと言うと下の図の用に普通の配線でつながっている。
CLK_DATA_test_24_101026.png

Fast input Registerを設定したのになぜ?というところだが、”HardCopy シリーズ・ハンドブック Volume 1”(なぜか?HardCopyだが)この20ページによると、fast_input_registerは、”I/O セルまたは隣接LAB に、高速入力レジスタを実装。”だそうだ。必ずしもI/Oセルに実装されるものではないらしい?

CLK_DATA_test.qsfを貼っておく。

set_global_assignment -name FAMILY "Cyclone III"
set_global_assignment -name DEVICE EP3C16F484C6
set_global_assignment -name TOP_LEVEL_ENTITY CLK_DATA_test
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "10.0 SP1"
set_global_assignment -name PROJECT_CREATION_TIME_DATE "05:20:24 OCTOBER 21, 2010"
set_global_assignment -name LAST_QUARTUS_VERSION "10.0 SP1"
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V
set_global_assignment -name VERILOG_FILE CLK_DATA_test.v
set_global_assignment -name QIP_FILE clk_data_test_pll.qip
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"
set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V"
set_global_assignment -name MISC_FILE "H:/HDL/Altera/qdesigns/DE0/Test/CLK_DATA_test/CLK_DATA_test.dpf"
set_location_assignment PIN_AA3 -to clk_out
set_location_assignment PIN_Y2 -to dout[0]
set_location_assignment PIN_Y1 -to dout[1]
set_location_assignment PIN_M8 -to dout[2]
set_location_assignment PIN_N8 -to dout[3]
set_location_assignment PIN_T3 -to dout[4]
set_location_assignment PIN_M7 -to dout[5]
set_location_assignment PIN_P3 -to dout[6]
set_location_assignment PIN_M5 -to dout[7]
set_location_assignment PIN_G1 -to reset
set_location_assignment PIN_G2 -to clk
set_location_assignment PIN_V1 -to din[0]
set_location_assignment PIN_N2 -to din[1]
set_location_assignment PIN_V4 -to din[2]
set_location_assignment PIN_T4 -to din[3]
set_location_assignment PIN_W1 -to din[4]
set_location_assignment PIN_U2 -to din[5]
set_location_assignment PIN_U1 -to din[6]
set_location_assignment PIN_V2 -to din[7]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dout[0]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dout[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dout[2]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dout[3]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dout[4]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dout[5]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dout[6]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dout[7]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to din[0]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to din[1]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to din[2]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to din[3]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to din[4]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to din[5]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to din[6]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to din[7]
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

  1. 2010年10月27日 04:36 |
  2. QuartusⅡ
  3. | トラックバック:0
  4. | コメント:0

AlteraのFPGAでのクロック出力とデータ出力2(Assignment Editorを使ってみる1)

さて、”AlteraのFPGAでのクロック出力とデータ出力1”では、Verilogだけ書いて、Quartus IIおまかせでやってみたが、今度は、Assignment Editorを使ってみることにした。長船さんに教えていただいたFAST_OUTPUT_REGISTER属性と、FAST_INPUT_REGISTER属性を試してみることにする。(Quartus II 10.0 SP1を使用)

最初に、Assignment Editorを立ち上げる。Assignmentメニューから、Assignment Editorを選択する。もしくは、Assignment Editorアイコンをクリックする。
CLK_DATA_test_8_101025.png

Assignment Editorが起動した。でも、何も項目が入っていない。これでは、Assignmentできない。
CLK_DATA_test_9_101025.png

これは。。。というわけで、IOピンを制約しないとだめなんだろうと思った。そこで、Assignment Editorを終了して、バックアノテーションしてみることにした。
AssignmentメニューからBack-Annotate Assignments... を選択する。
CLK_DATA_test_10_101025.png

Back-Annotate Assignmentsダイアログが開く。Pin & device assignmetsのラジオボタンをチェックしてOKボタンをクリックすると、Pinとデバイスを固定できるはず。。。OKボタンを押した。
CLK_DATA_test_11_101025.png

Assignment Editorを開くと今度は、固定されたIOピンが表示された。(後で、IOピンをバックアノテーションしなくても大丈夫そうということがわかりました)(とりあえず書いたので、このままにします、IOピンなどのバックアノテートのサンプルとします。ただしAlteraのコンフィグ関係のIOマップは消去しました)
CLK_DATA_test_12_101026.png

次に、出力ピンにFast Output Register属性を付加する。
下のTo Create New assignmentsからToの下のスペースを ダブルクリックすると、Node Finderのアイコンが出てくるので、それをクリックする。
CLK_DATA_test_13_101026.png

Node Finderのダイアログが出てくるので、Listボタンをクリックする。
CLK_DATA_test_14_101026.png

ノードが左のNodes Found:に表示されれる。8個のdoutを選択して、真ん中の>ボタンをクリックすると、右のSelected Nodes:に8このdoutが表示される。これでOKボタンをクリックする。
CLK_DATA_test_15_101026.png

これで8このdoutがToの項に入った。次にAssignment Nameを入力する。これは、プルダウンメニューで、Fast Output Registerを選択する。
CLK_DATA_test_16_101026.png

次に、Valueを入力する。これもプルダウンメニューでOnを選択する。
CLK_DATA_test_17_101026.png

必要な値は全部入った。Createボタンをクリックする。
CLK_DATA_test_18_101026.png

これで、dout[0]~dout[8]にFast Output Register属性が設定された。
CLK_DATA_test_19_101026.png

Saveして、Assignment Editorを終了し、もう一度コンパイルする。
Chip Plannerを起動して、dout[3]をResource Property Editorで見てみた。d2[3]のFFがI/Oセルに実装された。
CLK_DATA_test_20_101026.png

FAST_INPUT_REGISTER属性を試すところまで行かなかったが、次回試してみることにする。

# Alteraのアサインメント・エディタの日本語マニュアルが古くて、10.0 SP1のGUIにあってなかった。どうやってやるのか迷ってしまった。英語のマニュアルも詳しい説明書が見つからなかった。
  1. 2010年10月26日 05:34 |
  2. QuartusⅡ
  3. | トラックバック:0
  4. | コメント:0

今日の木工(基板スタンド)

今日の木工ではこれを作りました。なんだと思いますか?
kibantate_1_101024.jpg

これは、Spartan-3A Starter Kit用の基板スタンドです。
kibantate_2_101024.jpg

蝶ネジの部分は、エンザート(セルフ・タッピング・インサート309型 超荒目外ねじ)を埋め込んで、蝶ネジを取り付けています(M6です。下穴は9mmの木工用ドリル刃で開けました)。
Spartan-3A Starter Kitの基板の裏も4mmのシナベニアを切って両面テープで貼り付けました。ショートするのが怖いからです。
kibantate_3_101024.jpg

蝶ネジで板を動かすことで、Spartan-3A Starter Kitの基板の角度を変えることができます。なかなか良いものができた気がします。下の板と縦の板は桧です。蝶ネジの下の板は、SPF1X4材です。オール桧にしたかったのですが、この前の端材で作ったので、こうなりました。これもMakeで展示したいと思います。

いろいろケースなども作りたくなってきました。黒檀や紫檀で作ったら素敵そうですね。木が硬そうですけど。。。タモなどもオスモカラーのナチュラルを塗ると綺麗な黄色になります。いろいろやってみたいと思います。
  1. 2010年10月24日 17:57 |
  2. 木工
  3. | トラックバック:0
  4. | コメント:0

富弘美術館、草木ダムに行ってきました

今日は、群馬県みどり市に行ってきました。家の奥さんが、トロッコ列車、富弘美術館バスツアーに申し込むために電話したら、いっぱいだと断られたそうなので、群馬だったら車で楽勝で行けるということで車で行ってきました。今回は、子供たちは声を掛けても、誰も来ないので、私と奥さんだけで行ってきました。
家から大体110Kmくらいです。往復220kmくらいでした。行くときは8時10分ころ出て、11時40分頃に着きました。だいぶ登ったので、山の景色が素晴らしいです。
富弘美術館は、星野富弘さんの絵が展示してある美術館です。星野さんは首から下が事故で動かなくなったので、筆を口でくわえて、素晴らしい絵を書かれています。素晴らしい景色の中にある素敵な建物でした。
tomihiro_museum_1_101023.jpg

とても素敵な絵がたくさんありました。中でも朝顔の絵が気に入りました。いろいろ絵を見ているとアイディアも浮かびました。
そのあとは、富弘美術館のカフェでお茶というか昼食。本当は道の途中で見た蕎麦屋で食べたかったのですが、奥さんがとても眺めが素敵なので、食べたいとのことでしたので、(しょうがなく、でもこれは内緒)昼食にしました。下は眺めです。
tomihiro_museum_2_101023.jpg

奥さんはシフォンケーキとコーヒーでした。
tomihiro_museum_3_101023.jpg

私は、自家製パンとローズヒップティーでした。
tomihiro_museum_4_101023.jpg

パンにはバターとメイプルシロップとはちみつが付いていました。パンはくるみパンでバターとメイプルシロップを付けて食べると美味しかったです。ローズヒップティーが酸っぱすぎたので、はちみつを入れてのみました。でも酸っぱすぎて残してしまいました。カモミールティーがあったら良かったんですけどね。。。

富弘美術館の下には遊歩道があって、湖水当たりまで降りることができました。
その後、車で来た道を戻って、草木ダムを見学しました。凄い大きなダムですね。黒部ダムよりは小さいかもしれませんが、すごい迫力です。
tomihiro_museum_5_101023.jpg
tomihiro_museum_6_101023.jpg

ダムを堪能した後に、もっと来た道をもどって、水沼駅温泉センターに行ってきました。この温泉はわたらせ渓谷鐵道の水沼駅にあります。
tomihiro_museum_7_101023.jpg

500円でした。入ると、風呂がありますが、その奥に結構大きな露天風呂があります。眼が悪いので、良く見えませんが山が良く見えました。温泉を堪能して帰ってきました。ここの食堂には、鹿御膳、1000円とシカそぼろ丼、650円がありました。ぜひ食べたかったんですが、腹がいっぱいで食べられませんでした。今度行ったら、ぜひ食べたい。。。

その後は家路について、大体、5時10分頃家に到着。50号線は大体快適に流れていて、オービスに注意しながら帰ってきました。オービスの位置はナビが教えてくれます。
今日は本当に天気が良くて楽しい旅行になりました。

お土産はイノシシの缶詰とシカの缶詰です。まだ食べていません。
  1. 2010年10月23日 20:44 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:4

AlteraのFPGAでのクロック出力とデータ出力1

XilinxでFPGAからSDRAMなどの外部デバイスにクロックを供給する場合は、グローバルクロックからIOブロック(IOB)のDDRレジスタを叩いてクロックを生成した。データも同じグローバルクロックラインからクロックを供給されるクロックを使用するものは、IOBのレジスタ(DDR or SDR)を使用するとFPGAから供給するクロックと大体(スキューがあるときがあるから)同期できた。
Alteraではどうなんだろう?FPGAからSDRAMなどの外部デバイスにクロックを供給する場合のクロックの遅延は?出力するデータの同期はどうなるのか、IOブロックの中のFFを使用するにはどうするのか?実際にDE0のCyclone III (EP3C16F484C6)で、テストプロジェクトを作って調べてみることにした。

まずは、MegaWizard Plug-In Manager でALTPLLを作成して、50MHz入力、133.333MHz外部出力用のc0と内部で使用するためのc1を作成した。
CLK_DATA_test_1_101021.png

これを使って、上のモジュール(CLK_DATA_test.v)を書いた。CLK_DATA_test.vを下に示す。

// CLK_DATA_test.v

`default_nettype none

module CLK_DATA_test (
    input    wire    clk,
    input    wire    reset,
    input    wire    [7:0] din,
    output    wire    clk_out,
    output    wire    [7:0] dout
);
    
    reg [7:0] d0, d1, d2;
    wire c0_sig, c1_sig;
    wire locked_sig;
    wire reset_sig;

    clk_data_test_pll    clk_data_test_pll_inst (
        .areset ( reset ),
        .inclk0 ( clk ),
        .c0 ( c0_sig ),
        .c1 ( c1_sig ),
        .locked ( locked_sig )
    );
    
    assign reset_sig = ~locked_sig;
    
    always @(posedge c1_sig) begin
        if (reset_sig) begin
            d0 <= 8'd0;
            d1 <= 8'd0;
            d2 <= 8'd0;
        end else begin
            d0 <= din;
            d1 <= d0;
            d2 <= d1;
        end
    end
    assign dout = d2;
    
    assign clk_out = c0_sig;
    
endmodule

`default_nettype wire


これで、Quartus II 10.0SP1でコンパイルしてみた。制約ファイルは全く書いていない状態だ。
CLK_DATA_test_2_101022.png

次にChip Plannerを起動して、内部を覗いてみた。
左下をほんの少し使ってある。どうやら、4つの隅にPLLが実装されているようだ。
CLK_DATA_test_3_101022.png

使っている部分を拡大する。ピンクの四角や黒い四角で囲んだ部分が使用されている部分だ。
CLK_DATA_test_4_101022.png

黒い四角で囲んだ部分がPLLなので、これをダブルクリックすると内部構造が見える。Resource Property Editorが開いてPLLのプロパティを見ることができた。
CLK_DATA_test_5_101022.png

CLK0とCLK1がイネーブルされて、133.33MHzが出力されるように設定されている。

さて、一番見たかったのが、最後のFFのd2が何処に割り当てられているかだ。IOブロックのFF(Flip-Flop)かそれともLE(Logic Element)か?
LEの割り当てられていた。
CLK_DATA_test_6_101022.png

PLLのC0の出力先IOピン(clk_out)を見てみる。
CLK_DATA_test_7_101022.png

PLLからIOパッドまで行く配線は立ち上がりの遅延が1.764ns、立ち下がりの遅延が1.783nsだった。
次に、PLLでc0とc1の配線を反対にしてコンパイルしてみた。Chip Planner を立ち上げて、PLLからIOパッドまで行く配線を見てみたが、配線遅延は変化がなかった。

  1. 2010年10月21日 05:50 |
  2. AlteraのFPGA
  3. | トラックバック:0
  4. | コメント:0

CENTURYのLCD-8000Vサブモニタを購入

CENTURYのLCD-8000Vサブモニタを購入しました。8インチのVGAポート入力、USB電源のモニタです。現在のところはサブモニタとして使用していますが、本来はMakeなどでのデモ用に購入しました。
LCD-8000V_1_101020.jpg

まだ、640X480ドットで写してみたことがないのが、少し不安ですが、多分大丈夫だと思います。ただ、思ったより画面サイズが少し小さいかな?
LCD-8000Vを置いた私のパソコン周りはこんな感じです。手前にあるのが、以前購入したFILCO Majestouchテンキーレス 茶軸キーボードです。なかなかタッチが良いです。入力しやすいですね。職場では、東プレ NG0100 REALFORCE91Uを使っていますが、家の茶軸とタッチが違って、それぞれ良いところを楽しんでいます。液晶ディスプレイはIOデータの19インチを未だに使っています。これが、一番ドットピッチが大きいです。4対3のディスプレイの中では。
LCD-8000V_2_101020.jpg
  1. 2010年10月20日 04:47 |
  2. パソコン関連
  3. | トラックバック:0
  4. | コメント:0

DE0のSDR SDRAMコントローラ4(デバック中)

”DE0のSDR SDRAMコントローラ3(ALTPLL)”でMegaWizard Plug-In Manager でALTPLLを生成した。しかし、SDRAMに供給するクロックは、位相シフトを考えても、独立に1つのポートを割り当てたほうが良いと思ったので、ALTPLLの出力を変更した。

ここで疑問なのだが、Cyclone IIIのSDRAMへのクロックの出し方はどうすればよいのだろう?Xilinxだと、IOBに内蔵されたDDRレジスタを叩いて、クロックを出力させたが、Cyclone IIIではPLLから直接外部IOパッドに出力のだろうか?
Cyclone III デザイン・ガイドラインの13ページのクロック出力数の項を下に参照させて頂く。

Cyclone III PLL は、最大5 個のクロック出力(c0-c4)を備えています。c0 クロッ ク出力は、専用外部クロック出力ピン(推奨)、通常のユーザI/O または専用グ ローバル・クロック・ネットワークに接続することができます。


ということなので、どうやらALTPLLのc0にSDRAMへのクロック出力をアサインする必要がある。もう一度、ALTPLLの設定を変更した。
SDRAMCTL_DE0_2_101019.png

これで、c0がSDRAMへのクロック出力(133.333MHz)、c1が内部でSDRAMをコントロールする為に使用するクロック0度(133MHz)、c2が内部でSDRAMをコントロールする為に使用するクロック180度(133.333MHz)、c3が133.333/16MHz=8.3333MHz、c4がCMOSカメラ・ディスプレイ回路用の25MHzとなった。

次に、SDR SDRAMコントローラ単体でバーストテストをすることにした。現在、Veritakでシミュレーションをできるようにソースを修正中だ。XilinxのDDR2 SDRAMコントローラのプロジェクトからAlteraのSDR SDRAMコントローラに変更しているので、バグが満載だけれど、少しずつ直している。
SDRAMCTL_DE0_3_101019.png
  1. 2010年10月19日 05:45 |
  2. SDR SDRAMコントローラ
  3. | トラックバック:0
  4. | コメント:4

引き戸の製作2(戸車の溝堀)

引き戸も、前回ブログに書いてから、トリマーで4mmのアクリル板を入れる溝を掘ったが、昨日は戸車を入れる溝を掘った。
まずは、トリマーに12mmのストレートピットを付けて、4.5mmの深さで戸車の取付部を収める溝を掘った。戸車の幅は15mmだったので、奥行きを変えて2回掘った。
その後、戸車が収まるように、基準面から34mm程度掘り込んだ。それでも戸車が収まらなかったので、今度はノミで整形した。
hikido_3_101017.jpg

戸車が収まった。良かった。。。
hikido_4_101017.jpg

結構、うまく行ったのではないか?と思う。

次は、取っ手の部分を掘り込む予定。昨日はリハビリの意味でこのくらいにした。

今日は、FPGA-CAFEに行ってきた。原稿の話やカメラ音楽演奏?回路を見てもらって、いろいろアドバイスをもらった。いろいろな応用があるかな?と思った。
  1. 2010年10月17日 19:33 |
  2. 木工
  3. | トラックバック:0
  4. | コメント:0

ISEのWindows7対応

ISEはISE13からWindows7対応らしいですが、私は職場で、Windows 7 Professional 32bit版でISE10.1.03、ISE11.5、ISE12.1、ISE12.2、ISE12.3を同時に入れて使っています。
今のところ、問題なく使えています。
キャラクタ・ディスプレイ・コントローラをISE10.1.03、ISE11.5、ISE12.3でインプリメントして、iMPACTでSpartan-3 Starter Kitにダンロードしましたが、問題なく動作しました。(論理合成はXSTを使用)
さらに、ISE12.3では同じプロジェクトで、ChipScope Proを使ってみましたが、問題なく使用できました。
Windows 7 Professional 64bit版にもISE12.1をインストールしましたが、インプリメントには問題ありません。こっちはiMPACTでコンフィグしたことはまだないです。
なお、公式には対応していないですし、あくまでも私の環境で動いたということですので、試される場合は自己責任でお願いいたします。
  1. 2010年10月17日 05:43 |
  2. Xilinx ISEについて
  3. | トラックバック:0
  4. | コメント:0

お腹から喉に来る風邪

やっと体調が良くなってきました。
先週は木曜日にお腹が痛くなったと思ったら、金曜日に熱が出てきて、休暇をとって家に帰って寝ていました。
先週の土曜日は午後に熱が下がったので、大丈夫だと思ったら、日曜日の午前にまた37度5分程度の熱が出てしまいました。月曜日も同様です。
火曜日は、少し熱が出たのですが、すぐ下がって、疲労感があったけど、なんとか仕事に行けました。
水曜日は、扁桃腺にできた口内炎がひどく痛かったので、医者に行って薬をもらってきて、つけて次の木曜の朝は、肩こり、首コリから頭が痛くなりました。薬が効いて、扁桃腺はましになったのですが、頭痛がひどいことに。。。
夕方にマッサージに行こうと思ったら、気持ちが悪くなって、行けなくなって、家に直行して、夕食も食べられずに寝てました。
なんとか、今日の朝食は食べられて、今日の会議が終わってから、マッサージに行ってました。なんとか回復できたような気がします。近頃はお腹に来てから、喉に来る風邪が流行っていると、医者が言ってましたので、皆さんもお気をつけください。
段々と、リハビリをしながら普段の生活に戻そうと思います。人間ドックもキャンセルしてしまいました。

  1. 2010年10月15日 13:07 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:7

Visual Studio 2008でのコンソールCアプリケーション

久しぶりにVC++でコードを書いたら、いつの間にか、mainが_tmainになって、char* argv[]が_TCHAR* argv[]になっていた。
argv[1]をsscanf(argv[1], "%d", &a)でint aに値を取り込もうと思ってもエラーになってしまう。(プロパティで変えられると思うけど。。。)
この最、勉強して、Unicodeで書いてみた。コードはBMPのRGBコードの指定された何ビットかを落とすソフトウェアだ。

sscanf(argv[1], "%d",&bit_and);



_stscanf_s(argv[1], _T("%d"), &bit_and, sizeof(int));


に書き換えた。
下にすべてのソースコードを示す。

// Data2BitLimit.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
// 使い方:Data2BitLimit <落とすビット数> <元のBMPファイル名> <ビット数を落としたBMPファイル名>
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <cstring>

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    _TCHAR org_file[100];
    _TCHAR new_file[100];
    BITMAPFILEHEADER bmpfh; // BMPファイルのファイルヘッダ
    BITMAPINFOHEADER bmpih; // BMPファイルのINFOヘッダ
    FILE *orgfp, *newfp;
    BMP24FORMAT **bmp_data; // 24ビットのBMPファイルのデータ 640*480
    int i, j;
    int bit_and;
    unsigned char bit_and_pt;

    // 引数の処理
    if (argc==1){ // 引数なしはエラー
        fprintf(stderr, "使い方:Data2BitLimit <落とすビット数> <元のBMPファイル名(cam_bmp_file.bmp)> <ビット数を落としたBMPファイル名(new_bmp_file.bmp)>\n");
        exit(1);
        //bit_and = 2;
        //_stprintf_s(org_file, 100, _T("cam_bmp_file.bmp"), 138);
        //_stprintf_s(new_file, 100, _T("new_bmp_file.bmp"), 138);
    } else if (argc==2) { // 引数1つ、落とすビット数
        _stscanf_s(argv[1], _T("%d"), &bit_and, sizeof(int));
        _stprintf_s(org_file, 100, _T("cam_bmp_file.bmp"), 138);
        _stprintf_s(new_file, 100, _T("new_bmp_file.bmp"), 138);
    } else if (argc==3) {
        _stscanf_s(argv[1], _T("%d"), &bit_and, sizeof(int));
        _stprintf_s(org_file, 100, argv[2]);
        _stprintf_s(new_file, 100, _T("new_bmp_file.bmp"), 138);
    } else { // それ以外
        _stscanf_s(argv[1], _T("%d"), &bit_and, sizeof(int));
        _stprintf_s(org_file, 100, argv[2]);
        _stprintf_s(new_file, 100, argv[3]);
    }

    
    if (_tfopen_s(&orgfp, org_file, _T("rb")) != 0) { // org_fileをバイナリリードモードでオープン
        fprintf(stderr, "Can't Open %s\n", org_file);
        exit(1);
    }
    if (_tfopen_s(&newfp, new_file, _T("wb")) != 0) { // new_fileをバイナリライトモードでオープン
        fprintf(stderr, "Can't Open %s\n", new_file);
        exit(1);
    }
    
    // BMPファイルヘッダの読み出し
    fread(&bmpfh.bfType, sizeof(short), 1, orgfp);
    fread(&bmpfh.bfSize, sizeof(long), 1, orgfp);
    fread(&bmpfh.bfReserved1, sizeof(short), 1, orgfp);
    fread(&bmpfh.bfReserved2, sizeof(short), 1, orgfp);
    fread(&bmpfh.bfOffBits, sizeof(long), 1, orgfp);

    fread(&bmpih.biSize, sizeof(long), 1, orgfp);
    fread(&bmpih.biWidth, sizeof(long), 1, orgfp);
    fread(&bmpih.biHeight, sizeof(long), 1, orgfp);
    fread(&bmpih.biPlanes, sizeof(unsigned short), 1, orgfp);
    fread(&bmpih.biBitCount, sizeof(unsigned short), 1, orgfp);
    fread(&bmpih.biCompression, sizeof(unsigned long), 1, orgfp);
    fread(&bmpih.biSizeImage, sizeof(unsigned long), 1, orgfp);
    fread(&bmpih.biXPixPerMeter, sizeof(long), 1, orgfp);
    fread(&bmpih.biYPixPerMeter, sizeof(long), 1, orgfp);
    fread(&bmpih.biClrUsed, sizeof(unsigned long), 1, orgfp);
    fread(&bmpih.biClrImporant, sizeof(unsigned long), 1, orgfp);

    // BMPファイルヘッダの書き込み
    fwrite(&bmpfh.bfType, sizeof(short), 1, newfp);
    fwrite(&bmpfh.bfSize, sizeof(long), 1, newfp);
    fwrite(&bmpfh.bfReserved1, sizeof(short), 1, newfp);
    fwrite(&bmpfh.bfReserved2, sizeof(short), 1, newfp);
    fwrite(&bmpfh.bfOffBits, sizeof(long), 1, newfp);

    fwrite(&bmpih.biSize, sizeof(long), 1, newfp);
    fwrite(&bmpih.biWidth, sizeof(long), 1, newfp);
    fwrite(&bmpih.biHeight, sizeof(long), 1, newfp);
    fwrite(&bmpih.biPlanes, sizeof(unsigned short), 1, newfp);
    fwrite(&bmpih.biBitCount, sizeof(unsigned short), 1, newfp);
    fwrite(&bmpih.biCompression, sizeof(unsigned long), 1, newfp);
    fwrite(&bmpih.biSizeImage, sizeof(unsigned long), 1, newfp);
    fwrite(&bmpih.biXPixPerMeter, sizeof(long), 1, newfp);
    fwrite(&bmpih.biYPixPerMeter, sizeof(long), 1, newfp);
    fwrite(&bmpih.biClrUsed, sizeof(unsigned long), 1, newfp);
    fwrite(&bmpih.biClrImporant, sizeof(unsigned long), 1, newfp);

    // メモリをアロケートする
    if ((bmp_data=(BMP24FORMAT **)malloc(sizeof(BMP24FORMAT *)*bmpih.biHeight)) == NULL){
        fprintf(stderr, "bmp_dataの1次元目の480ののメモリを確保できません\n");
        exit(1);
    }
    for (i=0; i<bmpih.biHeight; i++){
        if ((bmp_data[i]=(BMP24FORMAT *)malloc(sizeof(BMP24FORMAT) * bmpih.biWidth)) == NULL){
            fprintf(stderr, "bmp_dataの2次元目の%d番目のメモリが確保できません\n");
            exit(1);
        }
    }

    // ビットを落として書き込む
    for (i=0, bit_and_pt=0; i<bit_and; i++)
        bit_and_pt = bit_and_pt | (1<<i);
    bit_and_pt = 0xff ^ bit_and_pt;

    for (i=0; i<bmpih.biHeight; i+=1){
        for (j=0; j<bmpih.biWidth; j+=1){
            bmp_data[i][j].blue = fgetc(orgfp);
            bmp_data[i][j].green = fgetc(orgfp);
            bmp_data[i][j].red = fgetc(orgfp);
            
            fputc((int)(bmp_data[i][j].blue & bit_and_pt), newfp);
            fputc((int)(bmp_data[i][j].green & bit_and_pt), newfp);
            fputc((int)(bmp_data[i][j].red & bit_and_pt), newfp);
        }
    }

    fclose(orgfp);
    fclose(newfp);
    
    for (i=0; i<bmpih.biHeight; i++)
        free(bmp_data[i]);
    free(bmp_data);
    return 0;
}


ヘッダは、ここにある
最初に、BMPヘッダの読み出しで、下のコードで良いと思った。

fread(&bmpfh, sizeof(BITMAPFILEHEADER), 1, orgfp);
fread(&bmpih, sizeof(BITMAPINFOHEADER), 1, orgfp);


上のコードを使用したところ、構造体tagBITMAPFILEHEADERは、最初にshort bfTypeがあって、次がlong bfSizeだったが、bfSizeの値が違っていた。おかしいと思ったら、どうやら、short bfSize、2バイトの後に、2バイトのダミー・パッディングが入っていて、その後にlong bfSizeだと、状況があう。どうやら、4バイト境界に構造体のメンバを揃えているようだ。(少なくともintやlongは)というわけで、構造体を一気にファイルから読むという目論見は甘いという教訓を得た。
改めて考えてみると、4バイト境界に揃っていたほうが1サイクルで読めるし、効率が良いと思う。

#fprintfがそのまま使ってあるから、後で直すことにする。
fprintfを_ftprintf_sに変更して、文字列は、_T( )でくくりました。

参考にしたWebサイト”Visual C++のUNICODE対応”、”VC++2005よりセキュリティが強化された関数の一覧"
  1. 2010年10月13日 21:16 |
  2. VC++
  3. | トラックバック:0
  4. | コメント:4

FPGAのSoC化

以前のブログで、Xilinx社の2010年10月6日のプレスリリースでISE12.3がAXI4に対応してきていることを書いたが、今度はtech-onによるとAlteraが”マルチコア・プロセサ搭載のFPGAソリューションを発表,Intelの「Stellarton」も利用可能に”なるそうだ。
記事によると、

例えばCortex-A9のハード・コアを搭載した28nm世代FPGAを2011年に発表する予定である。


そうだ。
いよいよ、FPGAがメジャーになってくる気がする。そして、Xilinxが押され気味な気がするな?Xilinxもがんばれ!!!
Alteraも勉強しておきたい。なんといってもSOPC Builderを勉強したい。その進化したQsysも。
  1. 2010年10月13日 05:13 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:2

DE0のSDR SDRAMコントローラ3(ALTPLL)

どうも、先週の金曜日くらいから調子が悪いです。朝に熱が出て、昼ごろ下がる状態が続いています。扁桃腺が腫れているようです。

さて、Altera の方に戻って、SDR SDRAMコントローラを作っています。Xilinxの時にはDCMでしたが、Cyclone IIIは、PLLなので、MegaWizard Plug-In Manager でALTPLLを生成した。DCMはカスケードして使っていたが、ALTPLLはカスケードしなくても必要な出力が出ていたので、単体で使用している。
SDRAMCTL_DE0_1_101011.png

c0はカメラ用の25MHz、c1はSDRAM用の133.33MHz位相0度、c2は133.33MHz位相180度、c3は133.33MHz/16 = 8.3333MHzだ。
一発で、出せてうれしい。
早く、バーストテスト用の回路を作ってテストしてみたい。まずはシミュレーションからやってみよう。

(2010/10/19:追記)
ALTPLLの設定を変更しました。詳しくは、”DE0のSDR SDRAMコントローラ4(デバック中)”をご覧くさい。
  1. 2010年10月11日 17:13 |
  2. SDR SDRAMコントローラ
  3. | トラックバック:0
  4. | コメント:0

PlanAhead12.3でCreate New Projectしてみる2(一時休止)

Xilinxの資料サイトが復活したようなので、PlanAheadのチュートリアルが見えるようになった。そのうちの”PlanAhead Software Tutorial Quick Front-to-Back Overview”の17ページ、”Step 3: Synthesizing the Design”からを参照して、やってみることにする。

最初にSynthesizeを行う。左のSynthesizeをポイントすると色が変わるので、クリックした。
PlanAhed_20_101010.png

そうするとエラーダイアログが出てきた。OKボタンをクリックした。
PlanAhed_21_101010.png

すると、やはり、ddr2_cont_parameters.vhが見つからないと言われた。
PlanAhed_22_101010.png

どうもSynthesizeのオプッションを見たときにインクルードパスがないと思ったんだよな。前回、XSTの設定をインポートしたはずなのに...
PlanAheadプロジェクトでのXSTのオプションのダイアルログを下に示す。
PlanAhed_23_101010.png

XST用の設定ファイル、CamDisp_Cntrler_DDR2.xstの内容を下に示す。

set -tmpdir "xst/projnav.tmp"
set -xsthdpdir "xst"
run
-ifn CamDisp_Cntrler_DDR2.prj
-ifmt mixed
-ofn CamDisp_Cntrler_DDR2
-ofmt NGC
-p xc3s700a-4-fg484
-top CamDisp_Cntrler_DDR2
-opt_mode Speed
-opt_level 1
-iuc NO
-keep_hierarchy No
-netlist_hierarchy Rebuilt
-rtlview Yes
-glob_opt AllClockNets
-read_cores YES
-sd {"ipcore_dir" }
-write_timing_constraints NO
-cross_clock_analysis NO
-hierarchy_separator /
-bus_delimiter <>
-case Maintain
-slice_utilization_ratio 100
-bram_utilization_ratio 100
-verilog2001 YES
-vlgincdir { "H:/HDL/OVL/std_ovl" "H:/HDL/FndtnISEWork/Spartan3A_starter_kit/CamDispCntrler_DDR2_Capt_SCCB_WS/Sources" "H:/HDL/FndtnISEWork/Spartan3A_starter_kit/DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont" }
-fsm_extract YES -fsm_encoding Auto
-safe_implementation No
-fsm_style LUT
-ram_extract Yes
-ram_style Auto
-rom_extract Yes
-mux_style Auto
-decoder_extract YES
-priority_extract Yes
-shreg_extract YES
-shift_extract YES
-xor_collapse YES
-rom_style Auto
-auto_bram_packing NO
-mux_extract Yes
-resource_sharing YES
-async_to_sync NO
-mult_style Auto
-iobuf YES
-max_fanout 500
-bufg 24
-register_duplication YES
-register_balancing No
-slice_packing YES
-optimize_primitives NO
-use_clock_enable Yes
-use_sync_set Yes
-use_sync_reset Yes
-iob Auto
-equivalent_register_removal YES
-slice_utilization_ratio_maxmargin 5


内容が違いすぎる... これ全部をPlanAheadプロジェクトでのXSTのオプションのダイアルログのMore Optionsに書くのは辛いので、これはここで中断することにした。もう少し、PlanAheadのプロジェクトが洗練されたら、もう一度やってみることにする。多分、インクルードファイルを使わないプロジェクトではうまく行くのだと思う。
今まで通りに、Project Navigatorをメインに使って、PlanAheadは、Project Navigatorから呼び出して使うようにしよう。
  1. 2010年10月10日 05:37 |
  2. PlanAheadについて
  3. | トラックバック:0
  4. | コメント:0

栗のワイン煮としその実の塩漬け

昨日は、具合が悪くて休暇を取って、家に帰って寝ていました。体温を測ったら37.8℃だったので、医者に行ってきたら、風邪だろうということでした。夜は気持ち悪くて、殆ど食べられなかったのですが、今朝起きたら具合が良くなっていました。熱も平熱に戻って、食事も普通に食べられるようになりました。ですが、まだ体がだるいです.

さて、この頃の検索語にしその実やしその実の塩漬けというのが多いんです。やはり季節なんですね。しその実の塩漬けは普通はスーパーなどで売っていません。お漬物にしその実が入っているのは見たことがありますが、しその実100%は見たことがありません。ということでしそを作っていないと食べられない逸品です。前にも書きましたが、私はこれが大好物。美味しいですよ。ご飯にかけても、チャーハンにかけてもいけます。香と噛んだ時のプチプチ感がたまりません。
下の写真で、左が奥さんの煮た栗のワイン煮、美味しかったです。右がしその実漬けです。
kuri_shisonomi_101009.jpg

ちなみにしその実は、このように枝に鈴なりに実を付けています
しその実は収穫する時期が肝心です。早いとプチプチ感が得られません。また遅くなると、硬すぎて食べにくくなります。家でしその実の塩漬けにするのは、青じそだけです。なんでだろう?赤じそのしその実の塩漬けは食べたことがないので、わかりませんが、硬いのかな?

(追記)赤紫蘇は香が悪いのでだめだそうです。このブログで書いていました
  1. 2010年10月09日 13:15 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:2

PlanAhead12.3でCreate New Projectしてみる1(プロジェクトを作るまで)

前回、Example ProjectでPlanAheadを試してみたが、自分のSpartan-3A Starter KitでCMOSカメラ・ディスプレイ回路で、どのようになるか試してみたくなった。本当はDE0のVerilog HDL を書きたいのだが、これをやってみないと気が済まないみたいだ。

さて、PlanAhead12.3を立ち上げて、Create New Projectをクリックする。すると、New Projectダイアログが立ち上がるので、Next>をクリックする。
PlanAhed_9_101008.png

Project NameとProject locationを指定する。Next>をクリックする。
PlanAhed_10_101008.png

Design Sourceを選択する。RTLやネットリスト、I/OプランニングやP&R後の結果をプロジェクトにすることもできるみたいだ。私はSpecify RTL Sourcesを選択して、XSTの設定もインポートする設定にチェックを入れた。Next>をクリックする。
PlanAhed_11_101008.png

XSTの設定をインポートする。Import XSTのラジオボタンをクリックして(すでにされている)、右の...ボタンをクックする。
PlanAhed_12_101008.png

Specify XST Fileダイアログが開く。既存の.xstファイルを選択すると、ファイルがPreviewされる。開くボタンをクリックする。
PlanAhed_13_101008.png

Import Settings from XST or Synplify Projectに戻って、.xstファイルが指定されている。Next>をクリックする。
PlanAhed_14_101008.png

Add/Create Sources にすべてのVerilog HDL 、VHDLファイルが入っていた。Next>をクリックする。
PlanAhed_15_101008.png

次に制約ファイル(UCF)を設定する。ラジオボタンをクリックして設定後に、Next>をクリックする。
PlanAhed_16_101008.png

次にFPGAを選択する。デフォルトのままで、Next>をクリックする。
PlanAhed_17_101008.png

Summaryが出て、やっとFinishボタンをクリックする。
PlanAhed_18_101008.png

そして、プロジェクトが出来た。しかし、parameterが書いてある.vhファイルが入っていない様な気がする?入っていない様で入っているのか?Project Navigatorだと、Automatic 'includeのところに入っていたのだが。。。
PlanAhed_19_101008.png

果たしてうまくインプリメント出来るのか?続く。
  1. 2010年10月08日 04:46 |
  2. PlanAheadについて
  3. | トラックバック:0
  4. | コメント:0

PlanAheadがISEのIDEになる?

Xilinx社の2010年10月6日のプレスリリースを読んでいると、”ISE Design Suite に含まれる PlanAhead デザイン解析ツールは、このリリースよりシームレスな「プッシュ ボタン」フローと、高度な視覚化 / 分析フローを実現している。”と書かれている。もしかすると、PlanAheadがProject Navigatorに変わる新しいISEのIDEになるんじゃないか?と思ってしまった。(あくまで推測です)
PlanAheadを単体で立ち上げたことが、最近なかったので、立ち上げてみた。下が起動画面。
PlanAhed_1_101007.png

本当は、PlanAhead Tutorialsに従って、やってみようと思ったが、いまXilinxのDocumentsのWebサイトが工事しているみたいなので、PlanAhead Tutorialsを見ることが出来ない。それで、Example Projectを適当にやってみることにした。(しかし、結構、Xilinxのサイトはそういうのが多い気がする。裏で書き換えて、取り替えないのでしょうか?)
やってみたのは、Wave(HDL)サンプルだ。
開いたのが下の画面。SynthesizeやImplementなどの項目が左に見える。ソース名も表示されていて、ダブルクリックすると、右にソースが表示された。
PlanAhed_2_101007.png

Synthesizeしてみることにした。左のSynthesizeをポイントすると色が変わるので、クリックした。(上図)
Synthesize Completedダイアログが出た。Implementには行かずにCancelボタンをクリックしてキャンセルした。
PlanAhed_3_101007.png

合成後の回路図も見えるようだった。回路図のインスタンスをクリックすると、何処の階層の何かを表示してくれた。結構便利。
次に、Implementしてみた。
PlanAhed_4_101007.png

Implement Completedダイアログが出た。ラジオボタンをOpen Implemented DesginにしたままOkボタンをクリックした。
PlanAhed_5_101007.png

インプリメント後の配置画面が出てきた。左を見るとここから、タイミング解析やFPGA Editorなども起動できるようだ。
PlanAhed_6_101007.png

左からSlack Histogramをクリックしてみた。すると、スラックのヒストグラムが表示された。
PlanAhed_7_101007.png

次に、Generate Bitstream...もやってみた。その後の左のProgram and Debugを開くと、ChipScope AnalyzerやiMPACTもここから開けるようだ。
PlanAhed_8_101007.png

いつの間にか、PlanAheadは、ISEのIDEとしての機能を備えていたのはびっくりした。まだ、ソースの階層表示が出来ない、論理合成やインプリメントのオプションがコマンドの引数の表示で説明がないとか(裏で、CUIコマンドを実行しているのが見える)いろいろ不満はあるが、新機能もあるし、PlanAheadをIDEとして使用するのも良いかもしれない。推測だが、多分、Project NavigatorからPlanAheadに移行していくのだろう。。。
  1. 2010年10月07日 05:57 |
  2. PlanAheadについて
  3. | トラックバック:0
  4. | コメント:0

ISE12.3

ISE12.3がXilinx社のダウンロードページに出ていた。早速ダウンロードした。今はインストールの途中だ。どのように、PlanAhead等が変わったか?見てみた。
EDKはAMBAのAXIバス対応 (Viretex-6, Spartan-6のみ) になっているのが、新しいようだ。
AXI4 インターフェイスを使用する CORE Generator IP が増えているみたいだ。FIFO GeneratorもMIGもAXIサポートの様だ。
Spartan-6でIPコアを追加してみた。FIFO Generator7.2とMIG3.6がAXI4対応になっていた。
ISE123_1_101006.png

FIFO Generator7.2を起動するとInterface TypeをNativeとAXI4から選べるようになっていた。
ISE123_2_101006.png

かなり、AXI4インターフェースに対応してきているようだ。EDKでなく、ISEでもAIX4を使うということかな?EDKでAXI4インターフェースを使うのに、CORE GeneratorでもAXI4対応なのかな?
自分でもAXI4インターフェース対応で回路を作ることが増えるのかな?上にラッパーかませるのでは無く?
  1. 2010年10月06日 05:33 |
  2. Xilinx ISEについて
  3. | トラックバック:0
  4. | コメント:0

DE0のSDR SDRAMコントローラ2

DE0にCMOSカメラを搭載するためのSDR SDRAMコントローラを作っていこうと思っている。
SDR SDRAMコントローラは、Xilinx用に作ったDDR SDRAMコントローラを改造する。実はXilinxのVirtex-2ProではVHDLだが、すでに動作してるコントローラだ(動作確認はしたのですが、使ってはいません)。それをVerilog HDL にすでに変更してあるので、XilinxからAlteraへの変更を行えば良い。
問題はアドレスや書き込み、読み出しデータのFIFOが分散RAMを使用したFIFOを使用しているところだ。Altera ではMLABを使おうと思っていたが、CycloneシリーズではMLABはないみたい。
そこで、勿体無いがM9Kブロックを使用する。これはMegaWizard Plug-In Manager でFIFOを生成することにした。すでに、”MegaWizard Plug-In Manager で作った同期FIFOの動作を確かめる1 ”と”MegaWizard Plug-In Manager で作った同期FIFOの動作を確かめる2(シミュレーション) ”でSFIFOの動作は確かめてある。
書き込み、読み出しデータのFIFOは、そのままSFIFOをMegaWizard Plug-In Manager で生成して使うこととするが、アドレスFIFOは次の出力ポートがあるので、SFIFOを内部にインスタンスして、ロジックを加えることにする。

DE0のSDRAMは、Integrated Circuit Solution Inc. のIS42S16400ということだった。このSDRAMは64Mbitの16ビット幅のデータバスを持つSDRAMだ。シミュレーションをするためのVerilog HDLモデルを探したのだが、なかったので、Micron社の256MbitのMT48LC16M16のモデルで代用することにした。
2つのSDRAMの違いは、アドレスビット幅がIS42S16400が12ビットで、MT48LC16M16が13ビット幅、カラムアドレス幅がIS42S16400が8ビットで、MT48LC16M16が9ビット幅であることだ。
動作周波数は一応、133MHzを目指すことにしようと思う。CL=3となる。


# いろいろ迷ったんですが、SOPC Builder使わないとAltera じゃないかな? FPGA-BBSで出ていたSG-DMA使おうか?とか。結局、お蔵入りしているSDR SDRAMコントローラも動かしてみたいし、Alteraの実装の様子も見てみたいので、今回はXilinxからの変更で行くことにしました。FPGA技術6号がでたらSOPC BuilderのMMマスタでつくり直してみようと思っています。
  1. 2010年10月05日 05:58 |
  2. SDR SDRAMコントローラ
  3. | トラックバック:0
  4. | コメント:0

FPGAの部屋の有用と思われるコンテンツのまとめサイトの更新(2010/10/04)

FPGAの部屋の有用と思われるコンテンツのまとめサイトを更新しました。
Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路AlteraのDE0ボードの項目を追加しました。
  1. 2010年10月04日 05:13 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

アリエッティ展、浅草、誕生会

今日は東京都現代美術館に行って、借りぐらしのアリエッティX種田陽平展を見てきました。
arietti_1_101003.jpg

今日が最終日なので、ものすごい人でした。入るのに80分待ちです。
arietti_2_101003.jpg

だいぶ待って中に入ると、そこはアリエッティの世界でした。巨大な釘やドリル、どんぐり、昆虫等、まるでアリエッティの世界に迷い込んだかのようでした。なかなか楽しめました。種田陽平さんて、フラガールなども手がけている美術監督なんですね?展示を見てはじめて知りました。
その後で、東京都現代美術館の常設展示を見ましたが、現代美術はとても私の理解を超えていました。もうに来ることもないでしょう。多分。。。
清澄白河の駅の街並みはカカシが道に点在していて、カカシ展をやっているようでした。途中で、焼鳥屋さんがあったので、焼き鳥を買って食べました。食事は現代美術館を出てから外でローソンのおにぎりを食べただけだったので、美味しかったです。ぼんじりって美味しいんですね。

その後は、浅草へ。昔々は浅草に行ったことあるみたいですが、全く憶えていないので、浅草寺は初めてのようなものです。
arietti_3_101003.jpg

暑かったので、仲見世でラムレーズンのソフトクリームと串に刺してある、ぬれあられ?を食べました。どっちも美味しかった。。。
浅草寺にお参りするときに、娘は凶の御籤を引きました。珍しい。。。早速結んでいましたよ。
arietti_4_101003.jpg

帰るときに気がついたのですが、東京スカイツリーが良く見えました。
arietti_5_101003.jpg

そういえば、最後に屋台で串もんじゃ焼きを食べました。美味しかったです。ですが、もんじゃ焼きとは違う食べ物のような気がします。

さて、帰って、娘の誕生会です。今日は娘のリクエストでラザニアです。私は、あまり食べたくなかったので、サンマの刺身でご飯にしました。今日のケーキはガトー・プリオのケーキでした。美味しかったです。
arietti_6_101003.jpg
  1. 2010年10月03日 21:58 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Divider Generator を使ってみた

割り算器が必要になったので、ISE12.2のCore GeneratorのDivider Generator を使って割り算コアを生成してみた。
ProjectメニューのNew Source..からIP(CORE Generator & Architecture Wizard) を選択し、File Name:をdivider_perとして、割り算器を生成する。下が、Divider Generator の設定。
divider_IP_1_101001.png

Dividend and Quotient Widthが23ビット、Divisor Widthが15ビットだ。Remainder TypeはRemainderで、Clocks per Divisonは1にしてある。Operand SignはUnsigned で、Control SignalsはCE を追加してある。
このパラメータで割り算器を生成した。これだけではインプリメントとシミュレーションができないので、トップファイルとテストベンチを追加した。
まずは、トップファイルのDivider_test.vhd から下に示す。

-- Divider Test(Divider_test.vhd)

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity Divider_test is
    port (
        clk: IN std_logic;
        ce: IN std_logic;
        rfd: OUT std_logic;
        dividend: IN std_logic_VECTOR(22 downto 0);
        quotient: OUT std_logic_VECTOR(22 downto 0);
        fractional: OUT std_logic_VECTOR(14 downto 0)
    );
end Divider_test;

architecture RTL of Divider_test is
component divider_per
    port (
    clk: IN std_logic;
    ce: IN std_logic;
    rfd: OUT std_logic;
    dividend: IN std_logic_VECTOR(22 downto 0);
    divisor: IN std_logic_VECTOR(14 downto 0);
    quotient: OUT std_logic_VECTOR(22 downto 0);
    fractional: OUT std_logic_VECTOR(14 downto 0));
end component;

signal divisor: std_logic_VECTOR(14 downto 0);
begin
    divider_per_inst : divider_per port map (
        clk => clk,
        ce => ce,
        rfd => rfd,
        dividend => dividend,
        divisor => divisor,
        quotient => quotient,
        fractional => fractional
    );
    divisor <= "110000000000000";
end RTL;


次にテストベンチ・ファイルのDivider_test_tb.vhdを下に示す。

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
ENTITY Divider_test_tb IS
END Divider_test_tb;
 
ARCHITECTURE behavior OF Divider_test_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT Divider_test
    PORT(
         clk : IN  std_logic;
         ce : IN  std_logic;
         rfd : OUT  std_logic;
         dividend : IN  std_logic_vector(22 downto 0);
         quotient : OUT  std_logic_vector(22 downto 0);
         fractional : OUT  std_logic_vector(14 downto 0)
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
   signal ce : std_logic := '0';
   signal dividend : std_logic_vector(22 downto 0) := (others => '0');

     --Outputs
   signal rfd : std_logic;
   signal quotient : std_logic_vector(22 downto 0);
   signal fractional : std_logic_vector(14 downto 0);

   -- Clock period definitions
   constant clk_period : time := 40 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: Divider_test PORT MAP (
          clk => clk,
          ce => ce,
          rfd => rfd,
          dividend => dividend,
          quotient => quotient,
          fractional => fractional
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;
 

    -- Stimulus process
    stim_proc: process
    begin
        ce <= '0';
        dividend <= "00000000000000000000000";    
        wait for clk_period*2;    
        ce <= '1';
        dividend <= "00000000110000000000000";
        wait for clk_period*2;    
        ce <= '1';
        dividend <= "00000011100000000000000";
        
        wait for clk_period*10;

        wait;
    end process;

END;


これで、とりあえずインプリメントをしてみた。無事に終了したが、Summaryには何も表示されない?
divider_IP_2_101001.png

なんででしょうか?
FPGA Editorで見てみると、FPGA内部では確かにIOとスライスが使用されている。
divider_IP_3_101001.png

次にシミュレーションを行ってみた。ISimによるシミュレーション波形を下に示す。
divider_IP_4_101001.png

rfdが1のままだった。rfdが0になることはない。rfdは入力データがコアにサンプルされるタイミングを表す。Divider Generator の設定で、Clocks per Divisonは1だったので、rfdは1クロックごとに入力データをサンプルできるはずなので、1のままなのだろう?この設定では、Dividend and Quotient Widthが23ビットなので、割り算データが出力されるレイテンシは上のシミュレーション波形のカーソルから1usec、25クロックである。データシートでもDividend and Quotient Width + 2クロックなので、25クロックとなり同一である。

次に、Clocks per Divisonを8にしてみた。
divider_IP_5_101001.png

これで、シミュレーションしてみたのが下の波形だ。
divider_IP_6_101001.png

今度は、rfdが8クロックごとに1になっていて、そこでサンプルされたデータが、1.04usec、26クロック後に割り算されて出力されている。データシートではClocks per Divisonが1以上の時は、Dividend and Quotient Width + 3クロックなので等しい。
当然、Clocks per Divisonが8の方がリソースは食わないはず。。。これで、この用途には十分だと思う。

Core Generatorの割り算器を確かめてみた。レイテンシは、Dividend and Quotient Width + 数クロックかかるということがわかった。
  1. 2010年10月01日 12:50 |
  2. Core Generator
  3. | トラックバック:0
  4. | コメント:0

イノベーション・ジャパン2010の様子

イノベーション・ジャパン2010は今日まで開催されていますが、東京国際フォーラムはすごい建物でした。こんな巨大な建造物が有楽町駅のすぐ近くにあるとは思いませんでした。
tokyo_fourm_1_101001.jpg

私たちのブースの様子です。
tokyo_fourm_2_101001.jpg

他にも、たくさん展示していました。350位あるようでした。今日も開催されていますが、私は実験で行けません。
  1. 2010年10月01日 05:52 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0