RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

多平臺FPGA工程快速移植與構(gòu)建

FPGA技術(shù)江湖 ? 來源:OpenFPGA ? 2024-11-20 16:12 ? 次閱讀

以下文章來源于 OpenFPGA,作者 碎碎思

作為一名FPGA工程師,經(jīng)常需要在多個FPGA設(shè)備之間移植項目,核心的問題是IP的管理和移植,今天通過安裝和使用 FuseSoC 在多個 AMD FPGA 之間移植一個簡單的項目。從 AMD Spartan 7 更改為 AMD Artix 7 設(shè)備,然后是 AMD Kintex UltraSacle。

FuseSoC 介紹

FuseSoC 是一款I(lǐng)P管理器和一套用于 HDL(硬件描述語言)代碼的構(gòu)建工具。

其主要目的是增加 IP 核心的重用,有助于創(chuàng)建、構(gòu)建和仿真 SoC的解決方案。

FuseSoC 具有如下功能:

重復(fù)使用現(xiàn)有核心

創(chuàng)建編譯時或運行時配置

針對多個仿真器運行回歸測試

讓其他項目輕松使用你的代碼

FuseSoC 最新可擴(kuò)展版本支持使用 GHDL、Icarus Verilog、Isim、ModelSim、Verilator 和 Xsim 進(jìn)行仿真。還支持使用 Altera Quartus、IceStorm、Xilinx ISE 和 Xilinx Vivado 構(gòu)建 FPGA 映像。支持新的 EDA 工具需要大約 100 行代碼,并且會不斷添加新工具。

FuseSoC 已成功用于構(gòu)建或仿真 Nyuzi、Pulpino、VScale、OpenRISC SoC、picorv32、osvvm 等項目。

安裝 FuseSoC

FuseSoC 以 Python 包的形式提供,因此我們可以使用 pip 安裝。對于這個項目,將使用 VSCode 作為安裝和使用 FuseSoC 的主要方法。

首先要檢查是否安裝了 Python

python--version
cec2aeca-a6d0-11ef-93f3-92fbcf53809c.png

下一步是安裝 FuseSoC

pip3install--upgradefusesoc
cecde056-a6d0-11ef-93f3-92fbcf53809c.png

要檢查 FuseSoC 是否已正確安裝,可以運行命令

fusesoc--version

可以看到類似下面的內(nèi)容

cedea008-a6d0-11ef-93f3-92fbcf53809c.png

FuseSoC 結(jié)構(gòu)

FuseSoC 提供包管理和構(gòu)建系統(tǒng)功能,因此需要了解一些基本概念才能有效地使用它。

FuseSoC 的關(guān)鍵元素是核心,核心就像我們平時熟知的 HDL IP。核心由 FuseSoC 包管理器進(jìn)行管理,為了能夠管理核心,每個核心都有一個名稱和附加信息,這些附加信息在核心文件中提供。

為了 FuseSoC 管理 IP 核,核心文件的擴(kuò)展名為.core

cee87cc2-a6d0-11ef-93f3-92fbcf53809c.png

FuseSoC 的一個優(yōu)點是核心可以具有依賴關(guān)系,例如,實現(xiàn)圖像直方圖和通過 AXI 接口的核心可以依賴于實現(xiàn) AXI 接口的核心。

核心可以存儲在本地或遠(yuǎn)程服務(wù)器上。核心的集合稱為核心庫,核心庫最簡單的實現(xiàn)是包含多個核心的目錄。

FuseSoC 構(gòu)建系統(tǒng)時能夠解決核心依賴關(guān)系,就頂層核心而言。它可以是位于 github 或 bitbucket 上的 git repo 上的遠(yuǎn)程庫。

雖然 FuseSoC 構(gòu)建系統(tǒng)整理了構(gòu)建設(shè)計所需的所有文件,但 AMD Vivado Design Suite 中的實際使用 EDAlize。EDALize 抽象了項目創(chuàng)建過程并執(zhí)行 AMD Vivado Design Suite 完成綜合、布局和布線以及生成比特流。

我們可以使用頂層的.core文件來整合幾個不同的核心庫,并控制頂層入口點和最終 FPGA 設(shè)計的目標(biāo)。

cf0e4826-a6d0-11ef-93f3-92fbcf53809c.png

FuseSoC 能夠與多個不同的庫協(xié)同工作,為了向 FuseSoC 提供庫的位置,需要使用名為 fusesoc.conf的文件。FuseSoC 將首先在當(dāng)前工作目錄中查找 .conf 文件,如果未找到,它將在主目錄 (Linux) 或 Windows %homedirectory% 中查找。

雖然我們可以手動創(chuàng)建此文件,但我們可以使用下面的命令自動創(chuàng)建它。

fusesoclibraryadd/path/to/directory
cf198c4a-a6d0-11ef-93f3-92fbcf53809c.png

使用 FuseSoC

上面介紹的比較抽象,我們接下來使用一個實例來介紹FuseSoC的使用。

我們將在該項目中使用的源代碼是 UART to AXI 邏輯(文末提供)。

針對以下主板:Digilent Arty S7、Digilent Arty A7、Alinx KU040進(jìn)行相同的工程設(shè)計。

首相,創(chuàng)建一個名為 SRC 的核心庫,在該庫下添加 HDL 元素的三個源文件。

還展示如何使用 AMD Vivado Design Suite IP 集成器設(shè)計并使用 FuseSoC 構(gòu)建它們。將在 IP 集成器中包含一些設(shè)計元素。這種方法可以被視為一種混合方法,IP 集成器設(shè)計將映射到頂層 VHDL 設(shè)計中。

由于不想在 AMD Vivado Design Suite 中為不同的構(gòu)建版本創(chuàng)建幾個不同的構(gòu)建元素,所以將創(chuàng)建一個可由 FuseSoC 運行的 tcl 腳本。

該腳本將實例化 AXI BRAM 控制器和 BRAM 連接到自定義 RTL 模塊。

#StartanewprojectoropenanexistingoneinVivado
#OpentheIPIntegratordesigntool
create_bd_design"design_1"

#AddanAXIBRAMController
setaxi_bram_ctrl[create_bd_cell-typeip-vlnvxilinx.comaxi_bram_ctrl:4.1axi_bram_ctrl_0]

#ConfiguretheAXIBRAMControllerforAXI4-Liteinterface
set_propertyCONFIG.PROTOCOL{AXI4LITE}[get_bd_cells$axi_bram_ctrl]

#AddaBlockRAM(BRAM)
setbram[create_bd_cell-typeip-vlnvxilinx.comblk_mem_gen:8.4bram_0]

#ConnecttheBRAMControllertotheBRAM
connect_bd_intf_net-intf_netS_AXI$axi_bram_ctrl/BRAM_PORTA$bram/BRAM_PORTA

#MakeAXIinterface,clock,andresetexternal
#ExposetheAXIinterfacetoexternalports
make_bd_intf_pins_external[get_bd_intf_pins$axi_bram_ctrl/S_AXI]

#Exposetheclocktoanexternalport
make_bd_pins_external[get_bd_pins$axi_bram_ctrl/s_axi_aclk]

#Exposetheresettoanexternalport
make_bd_pins_external[get_bd_pins$axi_bram_ctrl/s_axi_aresetn]

#Assignaddresses
assign_bd_address

#Saveandvalidatethedesign
validate_bd_design
save_bd_design

#GeneratetheHDLwrapperforthedesignandcapturethegeneratedfilename
setwrapper_file[make_wrapper-files[get_filesdesign_1.bd]-top]

#Addthegeneratedwrapperfiletotheproject
add_files$wrapper_file

#Updatetheprojecthierarchytoincludethenewwrapperfile
update_compile_order-filesetsources_1

該腳本將創(chuàng)建如下所示的框圖。

cf204d78-a6d0-11ef-93f3-92fbcf53809c.png

然后,將創(chuàng)建一個頂層 RTL 文件,將 IP 集成器框圖與自定義 RTL 模塊連接起來完成設(shè)計。

協(xié)議文件

libraryieee;
useieee.std_logic_1164.all;
useieee.numeric_std.all;
--Declareentity
entityaxi_protocolis
generic(
G_AXIL_DATA_WIDTH:integer:=32;--WidthofAXILitedatabus
G_AXI_ADDR_WIDTH:integer:=32;--WidthofAXILiteAddressBu
G_AXI_ID_WIDTH:integer:=8;--WidthofAXIIDBus
G_AXI_AWUSER_WIDTH:integer:=1--WidthofAXIAWUserbus
);
port(
--Masterclock&reset
clk:instd_ulogic;--Systemclock
reset:instd_ulogic;--Systemreset,asyncactivelow
--!MasterAXISInterface
m_axis_tready:instd_logic;
m_axis_tdata:outstd_logic_vector(7downto0);
m_axis_tvalid:outstd_logic;
--!SlaveAXISInterface
s_axis_tready:outstd_logic;
s_axis_tdata:instd_logic_vector(7downto0);
s_axis_tvalid:instd_logic;
--!AXILInterface
--!Writeaddress
axi_awaddr:outstd_logic_vector(G_AXI_ADDR_WIDTH-1downto0);
axi_awprot:outstd_logic_vector(2downto0);
axi_awvalid:outstd_logic;
--!writedata
axi_wdata:outstd_logic_vector(G_AXIL_DATA_WIDTH-1downto0);
axi_wstrb:outstd_logic_vector(G_AXIL_DATA_WIDTH/8-1downto0);
axi_wvalid:outstd_logic;
--!writeresponse
axi_bready:outstd_logic;
--!readaddress
axi_araddr:outstd_logic_vector(G_AXI_ADDR_WIDTH-1downto0);
axi_arprot:outstd_logic_vector(2downto0);
axi_arvalid:outstd_logic;
--!readdata
axi_rready:outstd_logic;
--writeaddress
axi_awready:instd_logic;
--writedata
axi_wready:instd_logic;
--writeresponse
axi_bresp:instd_logic_vector(1downto0);
axi_bvalid:instd_logic;
--readaddress
axi_arready:instd_logic;
--readdata
axi_rdata:instd_logic_vector(G_AXIL_DATA_WIDTH-1downto0);
axi_rresp:instd_logic_vector(1downto0);
axi_rvalid:instd_logic
);
endentityaxi_protocol;
architecturertlofaxi_protocolis
constantC_SINGLE_READ:std_logic_vector(7downto0):=x"05";
constantC_SINGLE_WRITE:std_logic_vector(7downto0):=x"09";
constantC_NUMB_ADDR_BYTES:integer:=4;
constantC_NUMB_LENGTH_BYTES:integer:=1;
constantC_NUMB_DATA_BYTES:integer:=4;
constantC_NUMB_AXIL_DATA_BYTES:integer:=4;
constantC_NUMB_CRC_BYTES:integer:=4;
constantC_MAX_NUMB_BYTES:integer:=4;--maxnumberoftheaboveconstantfornumberofbytes
constantC_ZERO_PAD:std_logic_vector(7downto0):=(others=>'0');
typet_fsmis(idle,address,length,dummy,write_payload,read_payload,crc,write_axil,write_axi,read_axi,read_axil);
typet_op_fsmis(idle,output,check);
typet_arrayisarray(0to7)ofstd_logic_vector(31downto0);
typeaxil_read_fsmis(IDLE,START,CHECK_ADDR_RESP,READ_DATA,DONE);
typeaxil_write_fsmis(IDLE,START,CHECK_ADDR_RESP,WRITE_DATA,RESP_READY,CHECK_RESP,DONE);
signalwrite_state:axil_write_fsm;
signalread_state:axil_read_fsm;
signals_current_state:t_fsm;
signals_command:std_logic_vector(7downto0);
signals_address:std_logic_vector((C_NUMB_ADDR_BYTES*8)-1downto0);
signals_length:std_logic_vector(7downto0);
signals_length_axi:std_logic_vector(7downto0);
signals_buf_cnt:unsigned(7downto0);
signals_byte_pos:integerrange0toC_MAX_NUMB_BYTES;
signals_num_bytes:integerrange0toC_MAX_NUMB_BYTES;
signals_s_tready:std_logic;
signals_write_buffer:t_array:=(others=>(others=>'0'));
signals_read_buffer:t_array:=(others=>(others=>'0'));
signals_write_buffer_temp:std_logic_vector(31downto0);
signals_read_buffer_temp:std_logic_vector(31downto0);
--axillitedatainterface
signals_axil_data:std_logic_vector(G_AXIL_DATA_WIDTH-1downto0);
signals_axil_valid:std_logic;
signals_axil_idata:std_logic_vector(G_AXIL_DATA_WIDTH-1downto0);
--aximstream
signals_opptr:unsigned(7downto0);
signals_start:std_logic;
signals_op_state:t_op_fsm;
signals_op_byte:integerrange0toC_MAX_NUMB_BYTES;
signalstart_read:std_logic;
signalstart_write:std_logic;
signals_m_axis_tvalid:std_logic;
begin
s_axis_tready<=?s_s_tready;
FSM?:?process(clk,?reset?)
begin
if?(reset?=?'0')?then
start_read??<=?'0';
start_write?<=?'0';
s_s_tready??<=?'0';
elsif?rising_edge(clk)?then
s_s_tready??<=?'1';
s_start?????<=?'0';
start_read??<=?'0';
start_write?<=?'0';
case?s_current_state?is
when?idle?=>--todoneedstocheckthecommandisvalid
s_buf_cnt<=?(others?=>'0');
if(s_axis_tvalid='1'ands_s_tready='1')and
(s_axis_tdata=C_SINGLE_READors_axis_tdata=C_SINGLE_WRITE)then
s_s_tready<=?'0';
s_command?<=?s_axis_tdata;
s_current_state?<=?address;
s_byte_pos?<=?C_NUMB_ADDR_BYTES;
end?if;
when?address?=>
ifs_byte_pos=0then
s_s_tready<=?'0';
s_byte_pos?<=?C_NUMB_LENGTH_BYTES;
s_current_state?<=?length;
elsif?s_axis_tvalid?=?'1'?and?s_s_tready?=?'1'?then
s_address?<=?s_address(s_address'length-8-1?downto?0)?&?s_axis_tdata;
s_byte_pos?<=?s_byte_pos?-?1;
if?s_byte_pos?=?1?then
s_s_tready?<=?'0';
end?if;
end?if;
when?length?=>
ifs_byte_pos=0then
s_s_tready<=?'0';
if?s_command?=?C_SINGLE_READ?and?unsigned(s_length)?=?1?then
s_current_state?<=?read_axil;
start_read??????<=?'1';
s_num_bytes?????<=?C_NUMB_AXIL_DATA_BYTES;
elsif?s_command?=?C_SINGLE_WRITE?then
s_buf_cnt???????<=?(others?=>'0');
s_byte_pos<=?C_NUMB_AXIL_DATA_BYTES;
s_num_bytes?????<=?C_NUMB_AXIL_DATA_BYTES;
s_current_state?<=?write_payload;
end?if;
elsif?s_axis_tvalid?=?'1'?and?s_s_tready?=?'1'?then
s_length????????????<=?s_axis_tdata;
s_length_axi????????<=?std_logic_vector(unsigned(s_axis_tdata)-1);
s_byte_pos??????????<=?s_byte_pos?-?1;
s_s_tready?<=?'0';
end?if;
when?read_axil?=>
ifs_axil_valid='1'then
s_start<=?'1';
s_read_buffer(0)(G_AXIL_DATA_WIDTH-1?downto?0)?<=?s_axil_data;
end?if;
if?(read_state?=?DONE)?then
s_current_state?<=?read_payload;
end?if;
when?write_payload?=>
ifs_buf_cnt=unsigned(s_length)then
s_s_tready<=?'0';
s_current_state?<=?write_axil;
start_write?<=?'1';
else
if?s_byte_pos?=?0?then
s_s_tready?<=?'0';
s_byte_pos?<=?s_num_bytes;
s_write_buffer(to_integer(s_buf_cnt))?<=?s_write_buffer_temp;
s_buf_cnt?<=?s_buf_cnt?+?1;
elsif?(s_axis_tvalid?=?'1'?and?s_s_tready?=?'1')?then
s_write_buffer_temp?<=?s_write_buffer_temp(s_write_buffer_temp'length-8-1?downto?0)?&?s_axis_tdata;
s_byte_pos?<=?s_byte_pos?-?1;
if?s_byte_pos?=?1?then
s_s_tready?<=?'0';
end?if;
end?if;
end?if;
when?write_axil?=>
s_s_tready<=?'0';
s_axil_idata?<=?s_write_buffer(0);
if?(write_state?=?DONE)?then
s_current_state?<=?idle;
end?if;
when?read_payload?=>
s_current_state<=?idle;
when?others?=>null;
endcase;
endif;
endprocess;
m_axis_tvalid<=?s_m_axis_tvalid;
process(clk,?reset)
begin
if?(reset?=?'0')?then
s_m_axis_tvalid??????<=?'0';
m_axis_tdata????????<=?(others?=>'0');
s_opptr<=?(others?=>'0');
s_op_byte<=?C_NUMB_AXIL_DATA_BYTES;
elsif?rising_edge(clk)?then
case?s_op_state?is
when?idle?=>
s_m_axis_tvalid<=?'0';
if?s_start?=?'1'?then
s_opptr?????<=?(others?=>'0');
s_read_buffer_temp<=?s_read_buffer(0);
s_op_byte???<=?s_num_bytes;
s_op_state??<=?output;
end?if;
when?output?=>
ifs_opptr=unsigned(s_length)then
s_op_state<=?idle;
s_m_axis_tvalid?<=?'0';
else
s_m_axis_tvalid?<=?'1';
m_axis_tdata?<=?s_read_buffer_temp(7?downto?0);
if?s_op_byte?=?0?then
s_op_byte???<=?s_num_bytes;
s_opptr?????<=?s_opptr?+?1;
s_m_axis_tvalid?<=?'0';
elsif?m_axis_tready?=?'1'?then
s_m_axis_tvalid?<=?'1';
s_read_buffer_temp?<=?C_ZERO_PAD?&?s_read_buffer_temp(s_read_buffer_temp'length-1?downto?8);
s_op_byte?<=?s_op_byte?-?1;
s_op_state??<=?check;
end?if;
end?if;
when?check?=>
s_m_axis_tvalid<=?'0';
s_op_state??<=?output;
end?case;
end?if;
end?process;
process(clk,?reset)
begin
if?(reset?=?'0')?then
write_state?<=?IDLE;
axi_awaddr??<=?(others?=>'0');
axi_awprot<=?(others?=>'0');
axi_awvalid<=?'0';
axi_wdata???<=?(others?=>'0');
axi_wstrb<=?(others?=>'0');
axi_wvalid<=?'0';
axi_bready??<=?'0';
elsif?rising_edge(clk)?then
axi_wstrb???<=?(others?=>'0');
casewrite_stateis
--Sendwriteaddress
whenIDLE=>
ifstart_write='1'then
write_state<=?START;
end?if;
when?START?=>
axi_awaddr<=?s_address;
axi_awprot??<=?"010";
axi_awvalid?<=?'1';
axi_wdata???<=?s_axil_idata;
axi_wvalid??<=?'1';
axi_wstrb???<=?(others?=>'1');
write_state<=?WRITE_DATA;--CHECK_ADDR_RESP;
--Wait?for?slave?to?acknowledge?receipt
when?CHECK_ADDR_RESP?=>
if(axi_awready='1')then
axi_awaddr<=?(others?=>'0');
axi_awprot<=?(others?=>'0');
axi_awvalid<=?'0';
write_state?<=?WRITE_DATA;
else
write_state?<=?CHECK_ADDR_RESP;
end?if;
--Send?write?data
when?WRITE_DATA?=>
if(axi_awready='1')then
axi_awaddr<=?(others?=>'0');
axi_awprot<=?(others?=>'0');
axi_awvalid<=?'0';
axi_wstrb???<=?(others?=>'0');
endif;
axi_wdata<=?s_axil_idata;
axi_wvalid?<=?'1';
axi_wstrb???<=?(others?=>'1');
if(axi_wready='1')then
write_state<=?RESP_READY;
else
write_state?<=?WRITE_DATA;
end?if;
--Set?response?ready
when?RESP_READY?=>
axi_wstrb<=?(others?=>'0');
axi_wvalid<=?'0';
axi_bready?<=?'1';
write_state?<=?CHECK_RESP;
--Check?the?response
when?CHECK_RESP?=>
if(axi_bvalid='1')then
axi_bready<=?'0';
write_state?<=?DONE;
end?if;
--Indicate?the?transaction?has?completed
when?DONE?=>
write_state<=?IDLE;
when?others?=>
write_state<=?START;
end?case;
end?if;
end?process;
process(clk,?reset)
begin
if?(reset?=?'0')?then
read_state?<=?IDLE;
axi_araddr??<=?(others?=>'0');
axi_arprot<=?(others?=>'0');
axi_arvalid<=?'0';
axi_rready??<=?'0';
elsif?rising_edge(clk)?then
case?read_state?is
when?IDLE?=>
ifstart_read='1'then
read_state<=?START;
end?if;
--Send?read?address
when?START?=>
axi_araddr<=?s_address;
axi_arprot??<=?"010";
axi_arvalid?<=?'1';
s_axil_valid?<=?'0';
read_state?<=?CHECK_ADDR_RESP;
--Wait?for?the?slave?to?acknowledge?receipt?of?the?address
when?CHECK_ADDR_RESP?=>
if(axi_arready='1')then
axi_araddr<=?(others?=>'0');
axi_arprot<=?(others?=>'0');
axi_arvalid<=?'0';
read_state?<=?READ_DATA;
else
read_state?<=?CHECK_ADDR_RESP;
end?if;
s_axil_valid?<=?'0';
--Read?data?from?the?slave
when?READ_DATA?=>
s_axil_data<=?axi_rdata;
if?(axi_rvalid?=?'1')?then
s_axil_valid?<=?'1';
read_state?<=?DONE;
else
s_axil_valid?<=?'0';
read_state?<=?READ_DATA;
end?if;
axi_rready?<=?'1';
--Indicate?the?transaction?has?completed
when?DONE?=>
axi_rready<=?'0';
s_axil_data??<=?(others?=>'0');
s_axil_valid<=?'0';
read_state?<=?IDLE;
when?others?=>
read_state<=?START;
end?case;
end?if;
end?process;
end?architecture;

UART 及 UART 封裝

libraryieee;
useieee.std_logic_1164.all;
useieee.numeric_std.all;
useieee.math_real.all;
usework.adiuvo_uart.all;
entityuartisgeneric(
reset_level:std_logic:='0';--resetlevelwhichcausesareset
clk_freq:natural:=100_000_000;--oscillatorfrequency
baud_rate:natural:=115200--baudrate
);
port(
--!SystemInputs
clk:instd_logic;
reset:instd_logic;
--!ExternalInterfaces
rx:instd_logic;
tx:outstd_logic;
--!MasterAXISInterface
m_axis_tready:instd_logic;
m_axis_tdata:outstd_logic_vector(7downto0);
m_axis_tvalid:outstd_logic;
--!SlaveAXISInterface
s_axis_tready:outstd_logic;
s_axis_tdata:instd_logic_vector(7downto0);
s_axis_tvalid:instd_logic
);
endentity;
architecturertlofuartis
constantbit_period:integer:=(clk_freq/baud_rate)-1;
typecntrl_fsmis(idle,set_tx,wait_tx);
typerx_fsmis(idle,start,sample,check,wait_axis);
signalcurrent_state:cntrl_fsm;--:=idle;
signalrx_state:rx_fsm;--:=idle;
signalbaud_counter:unsigned(vector_size(real(clk_freq),real(baud_rate))downto0):=(others=>'0');--timerforoutgoingsignals
signalbaud_en:std_logic:='0';
signalmeta_reg:std_logic_vector(3downto0):=(others=>'0');--fedetectiontoo
signalcapture:std_logic_vector(7downto0):=(others=>'0');--dataandparity
signalbit_count:integerrange0to1023:=0;
signalpos_count:integerrange0to15:=0;
signalrunning:std_logic:='0';
signalload_tx:std_logic:='0';
signalcomplete:std_logic:='0';
signaltx_reg:std_logic_vector(11downto0):=(others=>'0');
signaltmr_reg:std_logic_vector(11downto0):=(others=>'0');
signalpayload:std_logic_vector(7downto0):=(others=>'0');
constantzero:std_logic_vector(tmr_reg'range):=(others=>'0');
begin
process(reset,clk)
begin
ifreset=reset_levelthen
current_state<=?idle;
payload???????<=?(others?=>'0');
load_tx<=?'0';
elsif?rising_edge(clk)?then
load_tx?<=?'0';
case?current_state?is
when?idle?=>
ifs_axis_tvalid='1'then
current_state<=?set_tx;
load_tx???????<=?'1';
payload???????<=?s_axis_tdata;
end?if;
when?set_tx?=>
current_state<=?wait_tx;
when?wait_tx?=>
ifcomplete='1'then
current_state<=?idle;
end?if;
when?others?=>
current_state<=?idle;
end?case;
end?if;
end?process;
s_axis_tready?<=?'1'?when?(current_state?=?idle)?else?'0';
process?(reset,?clk)
--!?baud?counter?for?output?TX
begin
if?reset?=?reset_level?then
baud_counter?<=?(others?=>'0');
baud_en<=?'0';
elsif?rising_edge(clk)?then
baud_en?<=?'0';
if?(load_tx?=?'1')?then
baud_counter?<=?(others?=>'0');
elsif(baud_counter=bit_period)then
baud_en<=?'1';
baud_counter?<=?(others?=>'0');
else
baud_counter<=?baud_counter?+?1;
end?if;
end?if;
end?process;
process?(reset,?clk)
--!metastability?protection?rx?signal
begin
if?reset?=?reset_level?then
meta_reg?<=?(others?=>'1');
elsifrising_edge(clk)then
meta_reg<=?meta_reg(meta_reg'high?-?1?downto?meta_reg'low)?&?rx;
end?if;
end?process;
process?(reset,?clk)
begin
if?reset?=?reset_level?then
pos_count?<=?0;
bit_count?<=?0;
capture?????<=?(others?=>'0');
rx_state<=?idle;
m_axis_tvalid?<=?'0';
m_axis_tdata?????<=?(others?=>'0');
elsifrising_edge(clk)then
caserx_stateis
whenidle=>
m_axis_tvalid<=?'0';
if?meta_reg(meta_reg'high?downto?meta_reg'high?-?1)?=?fe_det?then
pos_count?<=?0;
bit_count?<=?0;
capture??<=?(others?=>'0');
rx_state<=?start;
end?if;
when?start?=>
ifbit_count=bit_periodthen
bit_count<=?0;
rx_state??<=?sample;
else
bit_count?<=?bit_count?+?1;
end?if;
when?sample?=>
bit_count<=?bit_count?+?1;
rx_state??<=?sample;
if?bit_count?=?(bit_period/2)?and?(pos_count?
ifparity(capture)='1'then
m_axis_tvalid<=?'1';
m_axis_tdata??<=?capture(7?downto?0);
rx_state??????<=?wait_axis;
else
m_axis_tvalid?<=?'1';
m_axis_tdata??<=?capture(7?downto?0);
rx_state??????<=?wait_axis;
end?if;
when?wait_axis?=>
ifm_axis_tready='1'then
m_axis_tvalid<=?'0';
rx_state??????<=?idle;
end?if;
end?case;
end?if;
end?process;
op_uart?:?process?(reset,?clk)
begin
if?reset?=?reset_level?then
tx_reg??<=?(others?=>'1');
tmr_reg<=?(others?=>'0');
elsifrising_edge(clk)then
ifload_tx='1'then
tx_reg<=?stop_bit?&?not(parity(payload))?&?payload?&?start_bit?;
tmr_reg?<=?(others?=>'1');
elsifbaud_en='1'then
tx_reg<=?'1'?&?tx_reg(tx_reg'high?downto?tx_reg'low?+?1);
tmr_reg?<=?tmr_reg(tmr_reg'high?-?1?downto?tmr_reg'low)?&?'0';
end?if;
end?if;
end?process;
tx???????<=?tx_reg(tx_reg'low);
complete?<=?'1'?when?(tmr_reg?=?zero?and?current_state?=?wait_tx)?else?'0';
end?architecture;
library?ieee;
use?ieee.std_logic_1164.all;
use?ieee.numeric_std.all;
use?ieee.math_real.all;
package?adiuvo_uart?is
function?vector_size(clk_freq,?baud_rate?:?real)?return?integer;
function?parity?(a?:?std_logic_vector)?return?std_logic;
constant?fe_det?????:?std_logic_vector(1?downto?0)?:=?"10";
constant?start_bit??:?std_logic?:=?'0';
constant?stop_bit???:?std_logic_vector?:=?"11";
end?package;
package?body?adiuvo_uart?is
function?vector_size(clk_freq,?baud_rate?:?real)?return?integer?is
variable?div?:?real;
variable?res?:?real;
begin
div?:=?(clk_freq/baud_rate);
res?:=?CEIL(LOG(div)/LOG(2.0));
return?integer(res?-?1.0);
end;
function?parity?(a?:?std_logic_vector)?return?std_logic?is
variable?y?:?std_logic?:=?'0';
begin
for?i?in?a'range?loop
y?:=?y?xor?a(i);
end?loop;
return?y;
end?parity;
end?package?body?adiuvo_uart;

TOP模塊

LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.numeric_std.all;
entitytop_levelis
port(
clk:instd_logic;
reset:instd_logic;
rx:instd_logic;
tx:outstd_logic
);
--Declarations
endentitytop_level;

LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.numeric_std.all;
libraryUNISIM;
useUNISIM.VCOMPONENTS.ALL;
useieee.math_real.all;
architecturestructoftop_levelis
--Architecturedeclarations
--Internalsignaldeclarations
signalS_AXI_0_arready:STD_LOGIC;
signalS_AXI_0_awready:STD_LOGIC;
signalS_AXI_0_bresp:STD_LOGIC_VECTOR(1downto0);
signalS_AXI_0_bvalid:STD_LOGIC;
signalS_AXI_0_rdata:STD_LOGIC_VECTOR(31downto0);
signalS_AXI_0_rresp:STD_LOGIC_VECTOR(1downto0);
signalS_AXI_0_wready:STD_LOGIC;
signalS_AXI_0_wvalid:STD_LOGIC;
signalaxi_araddr:std_logic_vector(31downto0);
signalaxi_arprot:std_logic_vector(2downto0);
signalaxi_arvalid:std_logic;
signalaxi_awaddr:std_logic_vector(31downto0);
signalaxi_awprot:std_logic_vector(2downto0);
signalaxi_awvalid:std_logic;
signalaxi_bready:std_logic;
signalaxi_rready:std_logic;
signalaxi_rvalid:std_logic;
signalaxi_wdata:std_logic_vector(31downto0);
signalaxi_wstrb:std_logic_vector(3downto0);
signalm_axis_tdata:std_logic_vector(7downto0);
signalm_axis_tready:std_logic;
signalm_axis_tvalid:std_logic;
signals_axis_tdata:std_logic_vector(7downto0);
signals_axis_tready:std_logic;
signals_axis_tvalid:std_logic;
--ComponentDeclarations
componentaxi_protocol
generic(
G_AXIL_DATA_WIDTH:integer:=32;--WidthofAXILitedatabus
G_AXI_ADDR_WIDTH:integer:=32;--WidthofAXILiteAddressBu
G_AXI_ID_WIDTH:integer:=8;--WidthofAXIIDBus
G_AXI_AWUSER_WIDTH:integer:=1--WidthofAXIAWUserbus
);
port(
axi_arready:instd_logic;
axi_awready:instd_logic;
axi_bresp:instd_logic_vector(1downto0);
axi_bvalid:instd_logic;
axi_rdata:instd_logic_vector(31downto0);
axi_rresp:instd_logic_vector(1downto0);
axi_rvalid:instd_logic;
axi_wready:instd_logic;
clk:instd_ulogic;
m_axis_tready:instd_logic;
reset:instd_ulogic;
s_axis_tdata:instd_logic_vector(7downto0);
s_axis_tvalid:instd_logic;
axi_araddr:outstd_logic_vector(31downto0);
axi_arprot:outstd_logic_vector(2downto0);
axi_arvalid:outstd_logic;
axi_awaddr:outstd_logic_vector(31downto0);
axi_awprot:outstd_logic_vector(2downto0);
axi_awvalid:outstd_logic;
axi_bready:outstd_logic;
axi_rready:outstd_logic;
axi_wdata:outstd_logic_vector(31downto0);
axi_wstrb:outstd_logic_vector(3downto0);
axi_wvalid:outstd_logic;
m_axis_tdata:outstd_logic_vector(7downto0);
m_axis_tvalid:outstd_logic;
s_axis_tready:outstd_logic
);
endcomponentaxi_protocol;
componentdesign_1_wrapper
port(
S_AXI_0_araddr:inSTD_LOGIC_VECTOR(11downto0);
S_AXI_0_arprot:inSTD_LOGIC_VECTOR(2downto0);
S_AXI_0_arvalid:inSTD_LOGIC;
S_AXI_0_awaddr:inSTD_LOGIC_VECTOR(11downto0);
S_AXI_0_awprot:inSTD_LOGIC_VECTOR(2downto0);
S_AXI_0_awvalid:inSTD_LOGIC;
S_AXI_0_bready:inSTD_LOGIC;
S_AXI_0_rready:inSTD_LOGIC;
S_AXI_0_wdata:inSTD_LOGIC_VECTOR(31downto0);
S_AXI_0_wstrb:inSTD_LOGIC_VECTOR(3downto0);
S_AXI_0_wvalid:inSTD_LOGIC;
s_axi_aclk_0:inSTD_LOGIC;
s_axi_aresetn_0:inSTD_LOGIC;
S_AXI_0_arready:outSTD_LOGIC;
S_AXI_0_awready:outSTD_LOGIC;
S_AXI_0_bresp:outSTD_LOGIC_VECTOR(1downto0);
S_AXI_0_bvalid:outSTD_LOGIC;
S_AXI_0_rdata:outSTD_LOGIC_VECTOR(31downto0);
S_AXI_0_rresp:outSTD_LOGIC_VECTOR(1downto0);
S_AXI_0_rvalid:outSTD_LOGIC;
S_AXI_0_wready:outSTD_LOGIC
);
endcomponentdesign_1_wrapper;
componentuart
generic(
reset_level:std_logic:='0';--resetlevelwhichcausesareset
clk_freq:natural:=100_000_000;--oscillatorfrequency
baud_rate:natural:=115200--baudrate
);
port(
clk:instd_logic;
m_axis_tready:instd_logic;
reset:instd_logic;
rx:instd_logic;
s_axis_tdata:instd_logic_vector(7downto0);
s_axis_tvalid:instd_logic;
m_axis_tdata:outstd_logic_vector(7downto0);
m_axis_tvalid:outstd_logic;
s_axis_tready:outstd_logic;
tx:outstd_logic
);
endcomponentuart;
--Optionalembeddedconfigurations
--pragmasynthesis_off
forall:axi_protocoluseentitysrc.axi_protocol;
forall:design_1_wrapperuseentitysrc.design_1_wrapper;
forall:uartuseentitysrc.uart;
--pragmasynthesis_on
begin
--Instanceportmappings.
U_0:axi_protocol
genericmap(
G_AXIL_DATA_WIDTH=>32,--WidthofAXILitedatabus
G_AXI_ADDR_WIDTH=>32,--WidthofAXILiteAddressBu
G_AXI_ID_WIDTH=>1,--WidthofAXIIDBus
G_AXI_AWUSER_WIDTH=>1--WidthofAXIAWUserbus
)
portmap(
clk=>clk,
reset=>reset,
m_axis_tready=>m_axis_tready,
m_axis_tdata=>m_axis_tdata,
m_axis_tvalid=>m_axis_tvalid,
s_axis_tready=>s_axis_tready,
s_axis_tdata=>s_axis_tdata,
s_axis_tvalid=>s_axis_tvalid,
axi_awaddr=>axi_awaddr,
axi_awprot=>axi_awprot,
axi_awvalid=>axi_awvalid,
axi_wdata=>axi_wdata,
axi_wstrb=>axi_wstrb,
axi_wvalid=>S_AXI_0_wvalid,
axi_bready=>axi_bready,
axi_araddr=>axi_araddr,
axi_arprot=>axi_arprot,
axi_arvalid=>axi_arvalid,
axi_rready=>axi_rready,
axi_awready=>S_AXI_0_wready,
axi_wready=>S_AXI_0_awready,
axi_bresp=>S_AXI_0_bresp,
axi_bvalid=>S_AXI_0_bvalid,
axi_arready=>S_AXI_0_arready,
axi_rdata=>S_AXI_0_rdata,
axi_rresp=>S_AXI_0_rresp,
axi_rvalid=>axi_rvalid
);
U_1:design_1_wrapper
portmap(
S_AXI_0_araddr=>axi_araddr(11downto0),
S_AXI_0_arprot=>axi_arprot,
S_AXI_0_arready=>S_AXI_0_arready,
S_AXI_0_arvalid=>axi_arvalid,
S_AXI_0_awaddr=>axi_awaddr(11downto0),
S_AXI_0_awprot=>axi_awprot,
S_AXI_0_awready=>S_AXI_0_awready,
S_AXI_0_awvalid=>axi_awvalid,
S_AXI_0_bready=>axi_bready,
S_AXI_0_bresp=>S_AXI_0_bresp,
S_AXI_0_bvalid=>S_AXI_0_bvalid,
S_AXI_0_rdata=>S_AXI_0_rdata,
S_AXI_0_rready=>axi_rready,
S_AXI_0_rresp=>S_AXI_0_rresp,
S_AXI_0_rvalid=>axi_rvalid,
S_AXI_0_wdata=>axi_wdata,
S_AXI_0_wready=>S_AXI_0_wready,
S_AXI_0_wstrb=>axi_wstrb,
S_AXI_0_wvalid=>S_AXI_0_wvalid,
s_axi_aclk_0=>clk,
s_axi_aresetn_0=>reset
);
U_2:uart
genericmap(
reset_level=>'0',--resetlevelwhichcausesareset
clk_freq=>100_000_000,--oscillatorfrequency
baud_rate=>115200--baudrate
)
portmap(
clk=>clk,
reset=>reset,
rx=>rx,
tx=>tx,
m_axis_tready=>s_axis_tready,
m_axis_tdata=>s_axis_tdata,
m_axis_tvalid=>s_axis_tvalid,
s_axis_tready=>m_axis_tready,
s_axis_tdata=>m_axis_tdata,
s_axis_tvalid=>m_axis_tvalid
);
endarchitecturestruct;

創(chuàng)建 XDC

將要進(jìn)行的三個工程之間的唯一區(qū)別在于約束文件。需要為每個目標(biāo)板創(chuàng)建一個約束。

AMD Spartan 7

set_propertyPACKAGE_PINR2[get_portsclk]
set_propertyIOSTANDARDLVCMOS33[get_portsclk]
create_clock-period10.000-namesys_clk[get_portsclk]
set_propertyPACKAGE_PINL17[get_portsreset]
set_propertyPACKAGE_PINL18[get_portsrx]
set_propertyPACKAGE_PINM14[get_portstx]
#setI/Ostandard
set_propertyIOSTANDARDLVCMOS33[get_portsreset]
set_propertyIOSTANDARDLVCMOS33[get_portsrx]
set_propertyIOSTANDARDLVCMOS33[get_portstx]

AMD Artix 7

set_propertyPACKAGE_PINE3[get_portsclk]
set_propertyIOSTANDARDLVCMOS33[get_portsclk]
create_clock-period10.000-namesys_clk[get_portsclk]
set_propertyPACKAGE_PING13[get_portsreset]
set_propertyPACKAGE_PINB11[get_portsrx]
set_propertyPACKAGE_PINA11[get_portstx]
#setI/Ostandard
set_propertyIOSTANDARDLVCMOS33[get_portsreset]
set_propertyIOSTANDARDLVCMOS33[get_portsrx]
set_propertyIOSTANDARDLVCMOS33[get_portstx]

AMD Kintex UltraSacle

set_propertyPACKAGE_PINAF9[get_portsclk]
set_propertyIOSTANDARDLVCMOS33[get_portsclk]
create_clock-period10.000-namesys_clk[get_portsclk]
set_propertyPACKAGE_PINAE8[get_portsreset]
set_propertyPACKAGE_PINAE10[get_portsrx]
set_propertyPACKAGE_PINAD10[get_portstx]
#setI/Ostandard
set_propertyIOSTANDARDLVCMOS33[get_portsreset]
set_propertyIOSTANDARDLVCMOS33[get_portsrx]
set_propertyIOSTANDARDLVCMOS33[get_portstx]

創(chuàng)建 FuseSoC 核心

創(chuàng)建 RTL 和XDC后,下一步是創(chuàng)建.core 文件和.conf 文件。

首先要做的是創(chuàng)建.core 文件,它將被分成幾個部分,第一部分是定義 CAPI 版本和核心庫,提供其名稱和描述

CAPI=2:

name:adiuvo:0.1
description:ImplementationforHacksterProject

下一步是創(chuàng)建文件集,這些文件集被分成幾個不同的組。將其中第一個組命名為核心組,這些文件是所有工程中通用的。

對于每個文件,我們還定義了庫和文件類型,在本例中為 vhdl。

下一步是定義創(chuàng)建 IP 集成器設(shè)計的 tcl 腳本。由于三個目標(biāo)板之間的配置沒有差異。此文件在所有實現(xiàn)中也是通用的。

如果我們正在創(chuàng)建需要特定電路板配置的 Zynq 或 Zynq MPSoC 設(shè)計,我們將需要為定義 PS 配置的每個電路板提供文件的變體。

下一個文件集是 IO 約束,每個所需的目標(biāo)板都有一個文件集。

filesets:
core:
files:
-src/protocol.vhd:{logical_name:work}
-src/uart_pkg.vhd:{logical_name:work}
-src/uart.vhd:{logical_name:work}
-src/top_level.vhd:{logical_name:work}
file_type:vhdlSource

vivado_files_tcl:
files:
-src/build_ip.tcl:{file_type:tclSource}

artix_io:
files:
-constraints/artix7.xdc:{file_type:xdc}

kintex_io:
files:
-constraints/kintexus.xdc:{file_type:xdc}

spartan_io:
files:
-constraints/spartan.xdc:{file_type:xdc}

最后一步是定義目標(biāo),在這里定義一個包含核心文件集的默認(rèn)目標(biāo)。然后再定義三個目標(biāo),每個目標(biāo)板一個。對于每個目標(biāo),將工具定義為 AMD Vivado Design Suite,并附加該特定目標(biāo)所需的文件集。

在這種情況下,它是 IO 文件集和 tcl 腳本,用于演示如果每個目標(biāo)不同,如何使用 TCL 腳本。

對于每個目標(biāo),還需要在 AMD Vivado Design Suite 中定義頂層模塊,當(dāng)然還有目標(biāo)設(shè)備。

targets:
default:&default
filesets:[core]

artix7:
<<:?*default
????default_tool:?vivado
????filesets_append?:?[vivado_files_tcl,?artix_io]
????toplevel?:?top_level
????tools:
??????vivado:
????????part?:?XC7A35TI-CSG324-1L

??spartan7:
????<<:?*default
????default_tool:?vivado
????filesets_append?:?[vivado_files_tcl,?spartan_io]
????toplevel?:?top_level
????tools:
??????vivado:
????????part?:?xc7s50-csga324-1

??kintexus:
????<<:?*default
????default_tool:?vivado
????filesets_append?:?[vivado_files_tcl,?kintex_io]
????toplevel?:?top_level
????tools:
??????vivado:
????????part?:?xcku040-ffva1156-2-i

.core 文件完成后,可以仔細(xì)檢查是否能夠看到剛剛定義的庫。

下一步是定義 fusesoc.conf 文件,定義核心的位置

[library.hackster]
location=C:/hdl_projects/hackster_fusesoc
sync-uri=C:/hdl_projects/hackster_fusesoc/
sync-type=local
auto-sync=false

因為在這個例子中我們只有一個名為 Hackster 的核心庫。

我們可以使用命令來檢查

fusesoccorelist

可以得到以下輸出

cf361180-a6d0-11ef-93f3-92fbcf53809c.png

FuseSoC 結(jié)果

創(chuàng)建源代碼后,可以通過運行命令來構(gòu)建這三個工程

AMD Artix 7

fusesoc--verboserun--target=artix7--no-exporthackster

AMD Kintex UltraSacle

fusesoc--verboserun--target=kintexus--no-exporthackster

AMD Spartan 7

fusesoc--verboserun--target=spartan7--no-exporthackster

隨著項目的構(gòu)建,將看到實施過程的記錄滾動過去。

cf454330-a6d0-11ef-93f3-92fbcf53809c.jpg

一旦完成后,將看到一條消息,顯示比特流生成已完成。

cf5db1d6-a6d0-11ef-93f3-92fbcf53809c.png

總結(jié)

該項目概述了如何使用 FuseSoC 編寫 FPGA 實現(xiàn)腳本,能夠輕松簡單地定位新的 FPGA 設(shè)備。由于 FuseSoC 是一個包管理器和構(gòu)建系統(tǒng)工具,能夠輕松進(jìn)行IP管理和不同設(shè)別之間工程管理。同時該項目中構(gòu)建了很多IP可以使用。

這里還有一點,就是使用 FuseSoC 可以進(jìn)行快速驗證,因為它還支持一系列仿真工具。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1629

    文章

    21729

    瀏覽量

    602964
  • amd
    amd
    +關(guān)注

    關(guān)注

    25

    文章

    5466

    瀏覽量

    134081
  • Xilinx
    +關(guān)注

    關(guān)注

    71

    文章

    2167

    瀏覽量

    121293
  • 移植
    +關(guān)注

    關(guān)注

    1

    文章

    379

    瀏覽量

    28124

原文標(biāo)題:多平臺FPGA工程快速移植與構(gòu)建

文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術(shù)江湖】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    LabVIEW實時與FPGA助您快速構(gòu)建工業(yè)高確定性應(yīng)用

    LabVIEW實時與FPGA助您快速構(gòu)建工業(yè)高確定性應(yīng)用議程?工業(yè)高確定性應(yīng)用的解決方案–實時系統(tǒng)與FPGA?NI提供全面的解決方案–快速
    發(fā)表于 10-28 10:27

    善用Vivado工程配置文件xpr快速工程創(chuàng)建

    根據(jù)需要定制自己的移植配置文件,這對于要多次創(chuàng)建基于同一個FPGA器件平臺工程而言,非常高效。這其實也是腳本開發(fā)相對于GUI開發(fā)方式的一個主要優(yōu)勢。
    發(fā)表于 10-19 18:05

    如何利用FPGA構(gòu)建PCI Express端點器件最佳平臺?

    如何利用FPGA構(gòu)建PCI Express端點器件最佳平臺?
    發(fā)表于 04-29 06:54

    快速移植OpenHarmony到三方芯片平臺的方法

    移植概述本文面向希望將OpenHarmony移植到三方芯片平臺硬件的開發(fā)者,介紹一種借助三方芯片平臺自帶Linux內(nèi)核的現(xiàn)有能力,快速
    發(fā)表于 04-12 11:08

    賽靈思平臺Virtex-4 FPGA的性能及應(yīng)用

    賽靈思平臺Virtex-4 FPGA的性能及應(yīng)用 賽靈思(Xilinx)的Virtex-4現(xiàn)場可編程門陣列(FPGA)是首款基于ASMBL(Advanced Silicon Mod
    發(fā)表于 06-26 08:11 ?41次下載

    基于FPGA的NoC驗證平臺構(gòu)建

    針對基于軟件仿真片上網(wǎng)絡(luò)NoC(Network on Chip)效率低的問題,提出基于FPGA的NoC驗證平臺構(gòu)建方案。該平臺集成可重用的流量產(chǎn)生器TG(Traffic Generat
    發(fā)表于 01-04 16:24 ?12次下載

    基于FPGA模無線基站

    FPGA 類高性能可編程邏輯器件,正是模無線基站的最佳構(gòu)建平臺之一
    發(fā)表于 09-28 10:24 ?853次閱讀

    移植Linux到晶心平臺

    鑒于越來越多使用者將Linux移植到晶心平臺(Andes Embedded)上(AndesCore N12或N10),本文的目的在協(xié)助使用者快速、有效率的將Linux 移植到自建的
    發(fā)表于 04-11 10:10 ?933次閱讀
    <b class='flag-5'>移植</b>Linux到晶心<b class='flag-5'>平臺</b>

    FPGA為基礎(chǔ)的模無線基站

    FPGA 類高性能可編程邏輯器件,正是模無線基站的最佳構(gòu)建平臺之一。Xilinx率先發(fā)布和量產(chǎn)的65nm平臺FPGA,則以大量先進(jìn)技術(shù)和全
    發(fā)表于 07-31 09:44 ?1158次閱讀

    ucos_ii 在microblaze平臺上的移植

    Xilinx FPGA工程例子源碼:ucos_ii 在microblaze平臺上的移植
    發(fā)表于 06-07 14:41 ?12次下載

    如何快速構(gòu)建一個移動跨平臺視頻通話應(yīng)用

    今天我們就來看一下如何使用 Agora Flutter SDK 快速構(gòu)建一個簡單的移動跨平臺視頻通話應(yīng)用。
    的頭像 發(fā)表于 02-24 06:01 ?2825次閱讀
    如何<b class='flag-5'>快速</b><b class='flag-5'>構(gòu)建</b>一個移動跨<b class='flag-5'>平臺</b>視頻通話應(yīng)用

    uCOSIII系統(tǒng)移植(二)構(gòu)建多任務(wù)

    uCOSIII構(gòu)建多任務(wù)LED.CF407時鐘掛載LED.H(宏定義狂魔)APP.C完整工程下載上一節(jié)移植構(gòu)建了模板和創(chuàng)建了單任務(wù),這一節(jié)來構(gòu)建
    發(fā)表于 11-30 15:51 ?1次下載
    uCOSIII系統(tǒng)<b class='flag-5'>移植</b>(二)<b class='flag-5'>構(gòu)建</b>多任務(wù)

    FPGA知識匯集-ASIC向FPGA移植

    將ASIC設(shè)計移植FPGA芯片中,對于大部分設(shè)計團(tuán)隊來講都是巨大的挑戰(zhàn)。主要體現(xiàn)在:ASIC的設(shè)計一般都非常大,往往需要做FPGA芯片劃分;需要支持足夠的處理性能;需要保證其功能的
    的頭像 發(fā)表于 04-14 15:01 ?2140次閱讀

    如何移植FPGA的例程

    在完成EDA作業(yè)后,抽空分享一下如何移植FPGA的例程。我EDA作業(yè)用的板子型號是Zybo-Z7,然后移植的是原子哥的HDMI實現(xiàn)方塊移動例程。
    的頭像 發(fā)表于 09-05 15:12 ?1900次閱讀

    如何將這些SoC的邏輯功能原型正確的移植FPGA中?

    當(dāng)SoC的規(guī)模在一片FPGA中裝不下的時候,我們通常選擇FPGA原型驗證的平臺來承載整個SoC系統(tǒng)。
    發(fā)表于 05-10 10:15 ?330次閱讀
    RM新时代网站-首页