日曜技術者としてはIntel(Altera)のFPGAもAMD(Xilinx)のFPGAも巨大すぎる。ロジックが多いのはいいけどパッケージがでかい。パッケージがちいさくてもBGAとかじゃ素人には扱えない。そこでLattice。Lattice Semiconductorは小規模ラインアップが多いのでホビーユーザには魅力的。ユーザ登録とかライセンス入手とかが面倒だけどまぁしょがない。
Lattice Diamondのマニュアルはあまりないのでここで一通りやってみて記録する。
すべてうまくやって、Diamondを起動。
File-->New-->Project...
Next
適当に入力してNext(Max10の教科書のクセでFPGAとしているが、何でもいいんだと思う)。
あとで追加するのでここではなにもせずにNext。
今回は秋月で売っているMachXO2-256HCなので、そう選びます。
ここはこれでいいのかわからんけど、デフォがこうなっているので、そのままNext。
こうなるので、Finish。
トップレベルのモジュールを作るので、File-->New-->File...
VHDLで作る。
ちなみにLattice Diamondではプロジェクト内のコードにおいてどれがトップレベルかどうかは関係はない。どこからも参照されないポートがあるモジュールはおのずとトップレベルって感じになっている。
MySPIをプロジェクトのフォルダにコピペする。
Lattice DiamondはVHDLの拡張子はvhdlではなくvhdなので、変更する。
MySPIを追加。
いっぺんに選べる。
トップレベルモジュールにするつもりで作成したFPGA.vhdをダブルクリックして開く。
LIBRARY ieee; USE ieee.std_logic_1164.ALL; library machxo2; use machxo2.all; ENTITY FPGA IS PORT ( clkout : out STD_LOGIC ); END FPGA; ARCHITECTURE fpga_body OF FPGA IS SIGNAL res_n : STD_LOGIC; SIGNAL por_n : INTEGER RANGE 0 TO 1; SIGNAL por_count : INTEGER RANGE 0 TO 65535; CONSTANT POR_MAX : INTEGER := 127; SIGNAL clkdiv_count : INTEGER RANGE 0 TO 65535; CONSTANT CLKDIV_MAX : INTEGER := 16; component OSCH generic( NOM_FREQ: string:="66.5" ); port( STDBY: in std_logic; OSC: out std_logic; SEDSTDBY: out std_logic ); end component; SIGNAL clk66p5 : STD_LOGIC; SIGNAL clk2p078125 : STD_LOGIC; COMPONENT MySPI IS PORT ( NSEND : IN STD_LOGIC_VECTOR(2 DOWNTO 0); NCLKDIV : IN STD_LOGIC_VECTOR(2 DOWNTO 0); CLKIN : IN STD_LOGIC; CLKOUT : OUT STD_LOGIC; CLKSYS : IN STD_LOGIC; BUSY : OUT STD_LOGIC; INIT : IN STD_LOGIC; WDATA : IN STD_LOGIC_VECTOR(7 DOWNTO 0); RDATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); OUTP : OUT STD_LOGIC; INP : IN STD_LOGIC; EN : IN STD_LOGIC ); END COMPONENT MySPI; signal NSEND : std_logic_vector(2 downto 0):="111"; signal NCLKDIV : std_logic_vector(2 downto 0):="111"; signal INIT : std_logic:='1'; signal WDATA : std_logic_vector(7 downto 0):="01010110"; signal MISO : std_logic:='1'; signal EN : std_logic:='1'; signal SCK : std_logic; signal BUSY : std_logic; signal RDATA : std_logic_vector(7 downto 0); signal MOSI : std_logic; BEGIN uOSCH : component OSCH generic map( NOM_FREQ=>"66.5" ) port map( STDBY=>'0', OSC=>clk66p5, SEDSTDBY=>OPEN ); MySPI_inst : COMPONENT MySPI PORT MAP( NSEND => NSEND, NCLKDIV => NCLKDIV, CLKIN => clk2p078125, CLKOUT => SCK, CLKSYS => clk66p5, BUSY => BUSY, INIT => INIT, WDATA => WDATA, RDATA => RDATA, OUTP => MOSI, INP => MISO, EN => EN ); --internal reset PROCESS (clk66p5) BEGIN IF clk66p5'event AND clk66p5 = '1' THEN IF por_count = POR_MAX THEN por_n <= 1; por_count <= por_count; ELSE por_n <= 0; por_count <= por_count + 1; END IF; END IF; END PROCESS; res_n <= '1' WHEN por_n = 1 ELSE '0'; process(clk66p5,clkdiv_count) begin if clk66p5'event and clk66p5='1' then clkdiv_count<=clkdiv_count+1; if clkdiv_count=CLKDIV_MAX then clkdiv_count<=0; end if; if clkdiv_count=0 then if clk2p078125='1' then clk2p078125<='0'; else clk2p078125<='1'; end if; end if; end if; end process; clkout<=clk2p078125; END;
いったん、動かさない。MachXO2には内蔵オシレータがあるんだけど、それを使って生成したクロックがちゃんと出ることだけ確認してみる。
Processタブを表示して、Lattice Synthesis Engineを右クリックしてRUN。論理合成する。
成功と言っている。
例によって回路図を見てみる。
まぁ変なことにはなってなさそう。
ピンを割り当てるツールを表示する。
雑にpin1に約2MHzになるようにしたクロックを出力する。ってして保存。
Lattice Programmerで書き込むときはJEDEC Fileというものがあればいいらしい。JEDEC Fileを右クリックしてRUN。
秋月の回路図を参考にしてこんなものを作りました。今回は秋月のFT2232Hモジュールで書き込みます。こんなもので書き込めちゃうのもLattice FPGAのいいところ。ドライバはFTDIのが認識されていればいいんだけど、うちではなぜかMichrochipってなっていたので、削除してFTDIのドライバをインストール。
で、今はこうなっている。
これを押してLattice Programmerを立ち上げる。
ちゃんとつながっていれば、自動的に認識してくれる。
ここいらへんをポチポチ押して、IC名を設定する。
ファイルは拡張子jedのものを選択。
まぁこうなる。
Programボタンを押す。
なんかやってる。
成功裏に終わったっぽい。
成功裏に終わったっぽい。
実測で1.96MHz。まぁちゃんとできているんだろう。
次回はMySPIを動かしてSPIを出してみる。MAX10と比較して回路規模が小さいので、マイコンを埋め込んで動かすことができるのかどうか、、、外部からマイコンで動かすのか、、、はたまたもうちょっと大きいデバイスで試すことになるのか、、、
コメントをお書きください