顯示具有 SDK 標籤的文章。 顯示所有文章
顯示具有 SDK 標籤的文章。 顯示所有文章

2014年9月15日 星期一

SDK Memo

紀錄 SDK 常用函式與方法

int to string : sprintf()

void int2str(int i, char *s) {
sprintf(s,"%d",i);
}


int to hex

u32 int_value;
char hex_value[8];

int_value = 291;
hex_value[0] = (char)((int_value >> 28) & 0xF);
hex_value[1] = (char)((int_value >> 24) & 0xF);
hex_value[2] = (char)((int_value >> 20) & 0xF);
hex_value[3] = (char)((int_value >> 16) & 0xF);
hex_value[4] = (char)((int_value >> 12) & 0xF);
hex_value[5] = (char)((int_value >> 8) & 0xF);
hex_value[6] = (char)((int_value >> 4) & 0xF);
hex_value[7] = (char)((int_value) & 0xF);
hex_value[8] = '\n';



2014年8月29日 星期五

simulate microblaze with chipscope

Reference http://www.zpss.aei.polsl.pl/content/dydaktyka/SD/Xilinx/lab6.pdf

為了想要看到上篇spi出來的訊號是不是跟我在scope看到的一樣
所以研究了一下怎麼simulate microblaze
本來是想要用外加chipscope來看波形,但是總出現PR Error
後來搜尋了一下用simulate microblaze, 我覺得因為ISE版本改很大
所以我在網路上找到的例子都不適用在ISE 14.4,別人可以checkbutton我的都是disable
直到找到這篇reference,我的心靈才得到了救贖阿!!!!

原來chipscope本來就可以內嵌進去microblaze,不用另外寫程式! 這麼方便的事情我竟然到今天才發現(崩╰(〒皿〒)╯ )

xps上選擇Debug->Debug Configuration
然後按左下角的Add ChipScope Peripheral,就會出現一個讓你選要加IBA,ILA or VIO
因為我要看得只是spimaster output 訊號,所以用ILA就可以了



然後會出現選項讓你選你要觀察哪個訊號,我把SPI中要觀察的訊號分別接到不同的triger當中,這樣比較好控制,下面的butter長度可以拉長一點,clk記得要選對,我一開始選200mosc,後來PR Error, FSL也不行,可能其他選項的CLK可以,還沒試過



建立完以後,會在Interface看到vioila



Hardware->Generate Netlist
然後在ISE重新generate bit file

xpsProject->Export Hardware Design to SDK
確定elfcompile成功以後programm FPGA
bit,bmm,elf檔燒入之後
Run->Run Configuration,Xilinx C/C++ ELF下面新增,會自動加入spi_test Debug



然後run就會Debug進入main的第一行等待,如果之後要從新debug,要按Run->Debug history->spi_test Debug



然後打開chipscope設定trigger的條件,不用重燒一次bit file
先觀察右邊是不是有看到ila
然後trigger的數量跟我設定的一樣,改不改名都可以
我把trigger條件設定在sck拉高的時候,因為它是active high

如果要加入其它的條件可以在下面設定與M2 and 或是or



然後按run等待sdk發出指令來trigger訊號,sdk上可以resume也可以stepover,看實際需求,然後就可以在chipscope上面看到spi的訊號了


看到圖形後果然ssactive low,但是匪夷所思的是為甚麼是在tri-state!!!!
然後正常的ss卻沒有啦low,但是我在Scope上看到的是active high!

果然bug沒有解完的一天! But anyway! Its nice to learn something new !


2014年5月16日 星期五

Ml605 microblaze with your own IP

Ml605 microblaze with your own IP

無可避免的還是用microblaze比較威,先來建立一個自己的IP放在AXI,方便接來下用UART進來的資料可以一起經由bus進入IP內部的邏輯

前兩年做過的東西早就忘光了,今天又依照tutorial 做了一次,趕快來紀錄一下,這樣下次複習比較快XDDDD

Tutorial 原版 EDK Concepts, Tools, and Techniques
A Hands-On Guide to EffectiveEmbedded System Design
UG683 (v13.4) January 18, 2012

建立一個專案,新增processer
選擇讓processor先預選基本的配備,然後在刪掉不需要的
local memory size 調大一點
timer新增進來,並加上interrupt

LED之後要做測試用所以不加進來


完成了以後可以看到大致的結構


接下來新增一個自己的IP


依照tutorial 新增一個blink ip,然後一直按到finish


打開\system\pcores\blink_v1_00_a\hdl\vhdl
裡面的兩個vhdl檔來新增port與寫入功能

blink.vhdl


user_logic.vhdl,利用輸入addressdata來決定讓led閃爍或是停止


在打開\system\pcores\blink_v1_00_a\data 裡面的 blink_v2_1_0.mpd
LEDs加入port


改完了以後按


就會在左側的ip列表裡面看到剛剛的blink,按兩下加入bus


base_address 先不用改,稍後系統會自動分配


portleds拉到外面的pin


addresses可以看到我們新增的ipaddress0x7c600000


接下來按hardware- generate netlist

成功了以後來寫top levelucf,注意blink_0_LEDs_pin 是否出現在output pin

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_microblaze_top is
    Port (
    osc_200m_p : in  STD_LOGIC;
    osc_200m_n : in  STD_LOGIC;
    reset : in  STD_LOGIC;
    uart_tx : out  STD_LOGIC;
    uart_rx : in  STD_LOGIC;
    gpio_led : out  STD_LOGIC_VECTOR (3 downto 0);
    gpio_dip : in  STD_LOGIC_VECTOR (7 downto 0));
end ml605_microblaze_top;

architecture Behavioral of ml605_microblaze_top is

  component system is
    port (
      RS232_Uart_1_sout : out std_logic;
      RS232_Uart_1_sin : in std_logic;
      RESET : in std_logic;
      blink_0_LEDs_pin : out std_logic_vector(3 downto 0);
      DIP_Switches_8Bits_TRI_I : in std_logic_vector(7 downto 0);
      CLK_P : in std_logic;
      CLK_N : in std_logic
    );
  end component;

begin

  microblaze_i : system
    port map (
      RS232_Uart_1_sout => uart_tx,
      RS232_Uart_1_sin => uart_rx,
      RESET => reset,
      blink_0_LEDs_pin => gpio_led,
      DIP_Switches_8Bits_TRI_I => gpio_dip,
      CLK_P => osc_200m_p,
      CLK_N => osc_200m_n
    );
end Behavioral;

NET osc_200m_n LOC = "H9" | DIFF_TERM = "TRUE" | IOSTANDARD = "LVDS_25";
NET osc_200m_p LOC = "J9" | DIFF_TERM = "TRUE" | IOSTANDARD = "LVDS_25";
NET gpio_dip[0] LOC = "D22" | IOSTANDARD = "LVCMOS15";
NET gpio_dip[1] LOC = "C22" | IOSTANDARD = "LVCMOS15";
NET gpio_dip[2] LOC = "L21" | IOSTANDARD = "LVCMOS15";
NET gpio_dip[3] LOC = "L20" | IOSTANDARD = "LVCMOS15";
NET gpio_dip[4] LOC = "C18" | IOSTANDARD = "LVCMOS15";
NET gpio_dip[5] LOC = "B18" | IOSTANDARD = "LVCMOS15";
NET gpio_dip[6] LOC = "K22" | IOSTANDARD = "LVCMOS15";
NET gpio_dip[7] LOC = "K21" | IOSTANDARD = "LVCMOS15";
NET gpio_led[0] LOC = "AC22" | IOSTANDARD = "LVCMOS25";
NET gpio_led[1] LOC = "AC24" | IOSTANDARD = "LVCMOS25";
NET gpio_led[2] LOC = "AE22" | IOSTANDARD = "LVCMOS25";
NET gpio_led[3] LOC = "AE23" | IOSTANDARD = "LVCMOS25";

NET reset LOC = "H10" | IOSTANDARD = "SSTL15" | TIG;
NET uart_rx LOC = "J24" | IOSTANDARD = "LVCMOS25";
NET uart_tx LOC = "J25" | IOSTANDARD = "LVCMOS25";

接下來在ISE geberate programming file

新增一個workspace資料夾

之後在XPS上直接連到SDK,指向剛剛新增的workspace



可以看到SDK上已經有Processor的資料


file-new-application project
新增一個hello world project

然後programm FPGA  


接下來可以用兩種方法來玩一下UART
  1. hello world 不用改,XMD Console
XMD%
Accepted a new TCLSock connection from 127.0.0.1 on port 53775
Programming Bitstream -- D:/ml605_microblaze/workspace/system_hw_platform/download.bit
Fpga Programming Progress ......10....20....30....40....50....60....70....80....90.....Done
mb

JTAG chain configuration
--------------------------------------------------
Device ID Code IR Length Part Name
1 0a001093 8 System_ACE_CF
2 64250093 10 XC6VLX240T

MicroBlaze Processor Configuration :
-------------------------------------
Version............................8.40.b
Optimization.......................Performance
Interconnect.......................AXI-LE
MMU Type...........................No_MMU
No of PC Breakpoints...............1
No of Read Addr/Data Watchpoints...0
No of Write Addr/Data Watchpoints..0
Instruction Cache Support..........off
Data Cache Support.................off
Exceptions Support................off
FPU Support.......................off
Hard Divider Support...............off
Hard Multiplier Support............on - (Mul32)
Barrel Shifter Support.............on
MSR clr/set Instruction Support....on
Compare Instruction Support........on
Data Cache Write-back Support......off
Fault Tolerance Support............off
Stack Protection Support...........off

Connected to MicroBlaze "mdm" target. id = 0
Starting GDB server for "mdm" target (id = 0) at TCP port no 1234

Note:: "mbconnect" command is Deprecated. Use "connect mb" command
XMD% stop
Processor stopped

XMD% mwr 0x7c600000 0x1
XMD% mrd 0x7c600000
7C600000: 00000001

XMD% mwr 0x7c600000 0x0
XMD%

第二種方法新增peripheral_tests_0 application project , 讓我們用c來控制uart



可以看到在左欄已經產了一些與周邊相關的程式,但這不是全部我需要的XD
我需要可以一個可以從UART搜集資料進來變成hex,好讓我可以把資料送入microblazeaxi bus,進而控制自創IPLED



裡面的reference code中的xlib_string.hxil_string.c,人家寫好的函式總是比較好用阿XD \xapp493_DisplayPort_SPM\XAPP493\v6\ML605\sdk_workspace\dp_source_policy_maker_0\src
xlib_string.h
//#define SIMULATION
#define DEBUG_LEVEL 1


#include "xil_types.h"

#define PRINT_TS 0
#define PRINT_EDID 1
#define LLC_TEST_MODE 0

#if (DEBUG_LEVEL >= 4)
#define dbg4_printf xil_printf
#else
#define dbg4_printf do_nothing
#endif

#if (DEBUG_LEVEL >= 3)
#define dbg3_printf xil_printf
#else
#define dbg3_printf do_nothing
#endif

#if (DEBUG_LEVEL >= 2)
#define dbg2_printf xil_printf
#else
#define dbg2_printf do_nothing
#endif

#if (DEBUG_LEVEL >= 1)
#define dbg_printf xil_printf
#define dbg1_printf xil_printf
#else
#define dbg_printf do_nothing
#define dbg1_printf do_nothing
#endif

#if (DEBUG_LEVEL == 0)
#define dbg_printf do_nothing
#endif

#define dbg_llc_printf do_nothing //xil_printf
#define dbg1_llc_printf do_nothing //xil_printf
#define dbg2_llc_printf do_nothing

void do_nothing();

char xil_getc(u32 timeout_ms);

u32 xil_gethex(u8 num_chars);


xil_string.c
#include "xlib_string.h"
#include "stdio.h"
#include "xlib_string.h"
#include "xuartlite_l.h"
#include "xparameters.h"
#include "xtmrctr.h"

char xil_getc(u32 timeout_ms){
 char c;
 u32 timeout = 0;

   extern XTmrCtr TimerCounter;

   //dbg_printf ("timeout_ms = %x\n\r",timeout_ms);
     // Reset and start timer
   if ( timeout_ms > 0 && timeout_ms != 0xff ){
    XTmrCtr_Start(&TimerCounter, 0);
    //dbg_printf ("timeout_ms = %x\n\r",timeout_ms);
   }



  while(XUartLite_IsReceiveEmpty(STDIN_BASEADDRESS) && (timeout == 0)){
      if ( timeout_ms == 0 ){ // no timeout - wait for ever
      timeout = 0;
      } else if ( timeout_ms == 0xff ) { // no wait - special case
      timeout = 1;
      } else if(timeout_ms > 0){
    if(XTmrCtr_GetValue(&TimerCounter, 0) > ( timeout_ms * (XPAR_MICROBLAZE_CORE_CLOCK_FREQ_HZ / 1000) )){
     timeout = 1;
    }
      }
  }
  if(timeout == 1){
   c = 0;
  } else {
   c = XUartLite_RecvByte(STDIN_BASEADDRESS);
  }

  return c;
}


u32 xil_gethex(u8 num_chars){
u32 data;
u32 i;
u8 term_key;
data = 0;

for(i=0;i= 'a') {
  term_key = term_key - 'a' + 10;
 } else if(term_key >= 'A') {
   term_key = term_key - 'A' + 10;
 } else {
  term_key = term_key - '0';
 }
 data = (data << 4) + term_key;
}


return data;
}

void do_nothing(){

}



將這兩個檔案加入我們建立的peripheral project,因為要init platform, 所以也把hello_world_0 裡面的platform.c, platform.h, platform_config.h 加入 peripheral project

將原本的testperiph.c main()拿掉,加入剛剛的h file
#include 
#include "xparameters.h"
#include "xil_cache.h"
#include "xintc.h"
#include "intc_header.h"
#include "uartlite_header.h"
#include "xbasic_types.h"
#include "xgpio.h"
#include "gpio_header.h"
#include "xtmrctr.h"
#include "tmrctr_header.h"
#include "tmrctr_intr_header.h"

//------------------ ADD CODE ---------------------
#include "xlib_string.h"
#include "platform.h"

void reg_write(u32 reg_address, u32 data);
u32  reg_read(u32 reg_address);
XTmrCtr TimerCounter;

int main()
{
    init_platform();
    while(1){
     dbg_printf(" TEST ");
     u32 addr = xil_gethex(8);
     u32 data = xil_gethex(8);
     reg_write(addr,data);
    }//end while
    cleanup_platform();
    return 0;
}

void reg_write(u32 reg_address, u32 data)
{
 dbg_printf("reg_write (0x%08x) 0x%08x\n\r", reg_address, data);
    *(volatile u32*)reg_address = data;
}

u32 reg_read(u32 reg_address)
{
 dbg_printf("reg_read (0x%08x) ", reg_address);
 u32 data = *(volatile u32*)reg_address;
 dbg_printf(" 0x%08x\n\r", data);
    return data;
}


在將產生的elf檔燒入版子,打開tera term,連續寫入addressdata就可以看到板子上的LED已經開始閃耀搂!




要注意一下microblazebaudrateteraterm的是否一致

如果之後不會再改sdk或是下次懶得再開sdk的話也可以直接把download.bit 燒進去板子裡面, programm FPGA後的console下方寫著
data2mem -bm D:/ml605_microblaze/edkBmmFile_bd.bmm -bt \
D:/ml605_microblaze/ml605_microblaze_top.bit -bd \
D:/ml605_microblaze/workspace/peripheral_tests_0/Debug/peripheral_tests_0.elf tag \
microblaze_0 -o b D:/ml605_microblaze/workspace/system_hw_platform/download.bit

系統已經自動幫你下commandworkspace/system_hw_platform/download.bit

結論有錢的真的是大爺,系統都幫你做好了,如果用免錢的microblaze就是童養媳的命運阿阿阿阿!!!!

這篇寫得太囉嗦了,後記下一篇用wxpythonserial來寫一個簡單的小介面來跟板子溝通,並產生exe檔方便其他沒有灌python的人使用

2014年5月14日 星期三

ML605 ipcore microblaze 筆記

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 ,注意mcsinstance


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
再燒入之前打開 tera term 觀察uart




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_reg0LED
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

,再燒入版子才看的到結果