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
,再燒入版子才看的到結果















沒有留言:
張貼留言