microblaze也有簡化版的免錢ipcore,在此紀錄使用過程
板子是ml605
*建立專案並新增ipcore,注意ipcore的名子不可以設為mcs_0
,不然之後下script的時候會找不到ipcore
, 之前這個地方卡了半天
= =
進入設定以後會看到系統已經自動設Hierarchical
Design Name 為mcs_0
clk 調成系統可以送進去的頻率
Memory size
可以先設大一點,免得之後在SDK隨便用uart印幾個字就說爆表了
= =
將io
bus打開
設定好uart
gpio以後就可以開始generate
code ,完了以後檢查一下ipcore_dir裡面的資料夾應該會有四個檔案
microblaze_mcs_sdk.xml
microblaze_mcs.bmm
microblaze_mcs_setup.tcl
mb_bootloop_le.elf
好了以後打開view-panel-tcl
console,輸入
source ipcore_dir/microblaze_mcs_setup.tcl成功的話會看到下列訊息
Command>source
ipcore_dir/microblaze_mcs_setup.tcl
microblaze_mcs_setup:
Found 1 MicroBlaze MCS core.
microblaze_mcs_setup:
Added "-bm" option for "microblaze_mcs.bmm" to
ngdbuild command line options.
microblaze_mcs_setup:
Done.
|
開始寫top
file 將mcs
instance 進入code,並加上ucf
,注意mcs的
instance
top level code
library IEEE; use IEEE.STD_LOGIC_1164.ALL; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; entity ml605_mcs_top is Port ( CLK_N : in STD_LOGIC; CLK_P : in STD_LOGIC; RESET : in STD_LOGIC; DIP : in STD_LOGIC_VECTOR (7 downto 0); LED : out STD_LOGIC_VECTOR (7 downto 0); UART_Rx : in STD_LOGIC; UART_Tx : out STD_LOGIC); end ml605_mcs_top; architecture Behavioral of ml605_mcs_top is COMPONENT microblaze_mcs PORT ( Clk : IN STD_LOGIC; Reset : IN STD_LOGIC; IO_Addr_Strobe : OUT STD_LOGIC; IO_Read_Strobe : OUT STD_LOGIC; IO_Write_Strobe : OUT STD_LOGIC; IO_Address : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); IO_Byte_Enable : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); IO_Write_Data : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); IO_Read_Data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); IO_Ready : IN STD_LOGIC; UART_Rx : IN STD_LOGIC; UART_Tx : OUT STD_LOGIC; GPO1 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); GPI1 : IN STD_LOGIC_VECTOR(7 DOWNTO 0); GPI1_Interrupt : OUT STD_LOGIC ); END COMPONENT; signal Clk : std_logic; signal IO_Addr_Strobe : std_logic; signal IO_Read_Strobe : std_logic; signal IO_Write_Strobe : std_logic; signal IO_Address : std_logic_vector(31 downto 0); signal IO_Byte_Enable : std_logic_vector(3 downto 0); signal IO_Write_Data : std_logic_vector(31 downto 0); signal IO_Read_Data : std_logic_vector(31 downto 0); signal IO_Ready : std_logic; signal slv_reg0 : std_logic_vector(31 downto 0); signal slv_IO_Read_Data : std_logic_vector(31 downto 0); signal slv_write_ack : std_logic; signal IO_Ready_w : std_logic; signal Read_rdy_w, Read_rdy : std_logic; signal Write_rdy_w, Write_rdy : std_logic; signal Data_Buffer_w, Data_Buffer : std_logic_vector(31 downto 0); signal IO_Write_Strobe_D, IO_Write_Strobe_D_w : std_logic; begin -- Input Clock Buffer clkin1_ibuf : IBUFGDS port map ( I => CLK_P, IB => CLK_N, O => Clk); mcs_0 : microblaze_mcs PORT MAP ( Clk => Clk, Reset => Reset, IO_Addr_Strobe => IO_Addr_Strobe, IO_Read_Strobe => IO_Read_Strobe, IO_Write_Strobe => IO_Write_Strobe, IO_Address => IO_Address, IO_Byte_Enable => IO_Byte_Enable, IO_Write_Data => IO_Write_Data, IO_Read_Data => IO_Read_Data, IO_Ready => IO_Ready, UART_Rx => UART_Rx, UART_Tx => UART_Tx, GPO1 => open, GPI1 => DIP, GPI1_Interrupt => OPEN ); ------------------ test iobuf --------------------------- LED <= slv_reg0(7 downto 0); process ( IO_Write_Strobe, IO_Addr_Strobe) is -- write begin if( IO_Write_Strobe = '1' and IO_Addr_Strobe = '1') then Write_rdy_w <= '1'; else Write_rdy_w <= '0'; end if; end process; process ( IO_Addr_Strobe, IO_Read_Strobe ) is -- read begin if( IO_Read_Strobe = '1' and IO_Addr_Strobe = '1') then Read_rdy_w <= '1'; else Read_rdy_w <= '0'; end if; end process; process( IO_Write_Data, IO_Write_Strobe,Data_Buffer) begin if(IO_Write_Strobe = '1') then Data_Buffer_w <= IO_Write_Data; IO_Write_Strobe_D_w <= '1'; else Data_Buffer_w <= Data_Buffer; IO_Write_Strobe_D_w <= '0'; end if; end process; IO_Ready <= '1' when Write_rdy = '1' or Read_rdy = '1' else '0'; IO_Read_Data <= slv_IO_Read_Data when Read_rdy = '1' else (others => '0'); process(Clk,reset) begin if reset = '1' then Write_rdy <= '0'; Read_rdy <= '0'; Data_Buffer <= (others => '0'); IO_Write_Strobe_D <= '0'; elsif CLK'event and CLK = '1' then Write_rdy <= Write_rdy_w; Read_rdy <= Read_rdy_w; Data_Buffer <= Data_Buffer_w; IO_Write_Strobe_D <= IO_Write_Strobe_D_w; end if; end process; process( Clk,reset ) is begin if reset = '1' then slv_reg0 <= (others => '0'); elsif Clk'event and Clk = '1' then if(IO_Write_Strobe_D = '1') then case IO_Address is when "11000000000000000000000000000000" => -- C0000000 slv_reg0(31 downto 0) <= Data_Buffer(31 downto 0); when others => null; end case; end if; end if; end process; -- implement slave model software accessible register(s) read mux process( IO_Address, IO_Addr_Strobe, slv_reg0 ) is begin if( IO_Addr_Strobe = '1' and IO_Read_Strobe = '1') then case IO_Address is when "11000000000000000000000000000000" => slv_IO_Read_Data <= slv_reg0; when others => slv_IO_Read_Data <= (others => '0'); end case; end if; end process; end Behavioral;ucf file
NET "CLK_N" LOC = H9 | DIFF_TERM = "TRUE" | IOSTANDARD = "LVDS_25"; NET "CLK_P" LOC = J9 | DIFF_TERM = "TRUE" | IOSTANDARD = "LVDS_25"; NET "RESET" LOC = H10 | IOSTANDARD = "SSTL15" | TIG; NET "LED<0>" LOC = AC22 | IOSTANDARD = "LVCMOS25"; NET "LED<1>" LOC = AC24 | IOSTANDARD = "LVCMOS25"; NET "LED<2>" LOC = AE22 | IOSTANDARD = "LVCMOS25"; NET "LED<3>" LOC = AE23 | IOSTANDARD = "LVCMOS25"; NET "LED<4>" LOC = AB23 | IOSTANDARD = "LVCMOS25"; NET "LED<5>" LOC = AG23 | IOSTANDARD = "LVCMOS25"; NET "LED<6>" LOC = AE24 | IOSTANDARD = "LVCMOS25"; NET "LED<7>" LOC = AD24 | IOSTANDARD = "LVCMOS25"; NET "DIP<7>" LOC = K21; NET "DIP<6>" LOC = K22; NET "DIP<5>" LOC = B18; NET "DIP<4>" LOC = C18; NET "DIP<3>" LOC = L20; NET "DIP<2>" LOC = L21; NET "DIP<1>" LOC = C22; NET "DIP<0>" LOC = D22; NET "UART_Rx" LOC = J24 | IOSTANDARD = "LVCMOS25"; NET "UART_Tx" LOC = J25 | IOSTANDARD = "LVCMOS25";接下來 generate programming file
在目錄裡面建立一個workspace
資料夾
打開SDK指向這個workspace
file-new-project-xilinx-hardware
platform specification
new-board support package
file-new-project-application project
elf file
已經產生,每次修改code以後儲存便會自動compile產生elf
file
回到
ISE 在tcl
console下
Command>microblaze_mcs_data2mem
workspace/hello_world_0/debug/hello_world_0.elf
microblaze_mcs_data2mem:
Found 1 MicroBlaze MCS core.
microblaze_mcs_data2mem:
Using "hello_world_0.elf" for microblaze_mcs
microblaze_mcs_data2mem:
Added "-bd" options to bitgen command line.
microblaze_mcs_data2mem:
Running "data2mem" to create simulation files.
microblaze_mcs_data2mem:
Running "data2mem" to update bitstream with software.
microblaze_mcs_data2mem:
Done.
|
基本上可以在ise上面用fpga
program 燒入bit
file然後,在run
sdk 看結果,但是我常常燒不進去,不知道是我頭腦有問題還是eclips實在是寫太爛了,我想應該是前者
= =
所以我比較喜歡把bit
file 跟elf
合在一起再用impact燒入
可以在ISE
上面command合併bmm,bit,elf
成一個全新的download.bit
Command>data2mem -bm
ipcore_dir/microblaze_mcs_bd.bmm -bd
workspace/hello_world_0/Debug/hello_world_0.elf -bt ml605_mcs_top.bit
-o b download.bit
hello world . nice to see you !
再原本的microblaze所用的uart
lite 可以使用函數XUartLite_IsReceiveEmpty,XUartLite_RecvByte
但是這個ipcore似乎沒有這種support的函式,表示又要回去使用大魔頭!!!!!
收集uart的範例函式可以再xapp493
DisplayPort Source Core Reference Design
裡面的程式
xlib_string.h,xlib_string.c裡面找到
再ipcore裡面有打開
io
IO_Addr_Strobe
IO_Read_Strobe
IO_Write_Strobe
IO_Address
IO_Byte_Enable
IO_Write_Data
IO_Read_Data
IO_Ready
再
top level裡面將
address 0xc0000000 送入的資料slv_reg0給LED
再SDK裡面可以寫入測試,可以看到板子上LED全亮
#include "stdio.h" #include "platform.h" #include "xparameters.h" #include "xiomodule.h" #include "xiomodule_l.h" #include "xdebug.h" #include "xio.h" u32 volatile *LED = (u32 volatile *)(0xC0000000); // slv_reg0 void print(char *str); int main() { init_platform(); print("HELLO LED \n\r"); *LED = 0x000000ff; cleanup_platform(); return 0; }
如果改變
C 或是
VHDL 都會重新產生ELF或是BIT
所以都要重新下COMMAND
Command>data2mem
-bm ipcore_dir/microblaze_mcs_bd.bmm -bd
workspace/hello_world_0/Debug/hello_world_0.elf -bt ml605_mcs_top.bit
-o b download.bit
,再燒入版子才看的到結果
沒有留言:
張貼留言