在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

多平臺FPGA工程快速移植與構建

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

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

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

FuseSoC 介紹

FuseSoC 是一款IP管理器和一套用于 HDL(硬件描述語言)代碼的構建工具。

其主要目的是增加 IP 核心的重用,有助于創建、構建和仿真 SoC的解決方案。

FuseSoC 具有如下功能:

重復使用現有核心

創建編譯時或運行時配置

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

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

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

FuseSoC 已成功用于構建或仿真 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

可以看到類似下面的內容

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

FuseSoC 結構

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

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

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

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

FuseSoC 的一個優點是核心可以具有依賴關系,例如,實現圖像直方圖和通過 AXI 接口的核心可以依賴于實現 AXI 接口的核心。

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

FuseSoC 構建系統時能夠解決核心依賴關系,就頂層核心而言。它可以是位于 github 或 bitbucket 上的 git repo 上的遠程庫。

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

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

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

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

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

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

使用 FuseSoC

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

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

針對以下主板:Digilent Arty S7、Digilent Arty A7、Alinx KU040進行相同的工程設計。

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

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

由于不想在 AMD Vivado Design Suite 中為不同的構建版本創建幾個不同的構建元素,所以將創建一個可由 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

該腳本將創建如下所示的框圖。

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

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

協議文件

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;

創建 XDC

將要進行的三個工程之間的唯一區別在于約束文件。需要為每個目標板創建一個約束。

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]

創建 FuseSoC 核心

創建 RTL 和XDC后,下一步是創建.core 文件和.conf 文件。

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

CAPI=2:

name:adiuvo:0.1
description:ImplementationforHacksterProject

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

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

下一步是定義創建 IP 集成器設計的 tcl 腳本。由于三個目標板之間的配置沒有差異。此文件在所有實現中也是通用的。

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

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

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}

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

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

對于每個目標,還需要在 AMD Vivado Design Suite 中定義頂層模塊,當然還有目標設備。

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 文件完成后,可以仔細檢查是否能夠看到剛剛定義的庫。

下一步是定義 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 結果

創建源代碼后,可以通過運行命令來構建這三個工程

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

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

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

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

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

總結

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

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1629

    文章

    21736

    瀏覽量

    603319
  • amd
    amd
    +關注

    關注

    25

    文章

    5468

    瀏覽量

    134149
  • Xilinx
    +關注

    關注

    71

    文章

    2167

    瀏覽量

    121401
  • 移植
    +關注

    關注

    1

    文章

    379

    瀏覽量

    28130

原文標題:多平臺FPGA工程快速移植與構建

文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術江湖】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    LabVIEW實時與FPGA助您快速構建工業高確定性應用

    LabVIEW實時與FPGA助您快速構建工業高確定性應用議程?工業高確定性應用的解決方案–實時系統與FPGA?NI提供全面的解決方案–快速
    發表于 10-28 10:27

    善用Vivado工程配置文件xpr快速工程創建

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

    如何利用FPGA構建PCI Express端點器件最佳平臺

    如何利用FPGA構建PCI Express端點器件最佳平臺
    發表于 04-29 06:54

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

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

    賽靈思平臺Virtex-4 FPGA的性能及應用

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

    基于FPGA的NoC驗證平臺構建

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

    基于FPGA模無線基站

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

    移植Linux到晶心平臺

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

    FPGA為基礎的模無線基站

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

    ucos_ii 在microblaze平臺上的移植

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

    如何快速構建一個移動跨平臺視頻通話應用

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

    uCOSIII系統移植(二)構建多任務

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

    FPGA知識匯集-ASIC向FPGA移植

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

    如何移植FPGA的例程

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

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

    當SoC的規模在一片FPGA中裝不下的時候,我們通常選擇FPGA原型驗證的平臺來承載整個SoC系統。
    發表于 05-10 10:15 ?333次閱讀
    主站蜘蛛池模板: 日本一级成人毛片免费观看| 国语一区| 夜夜橹橹网站夜夜橹橹| 日本特级视频| 夜夜操综合| 国产精品夜色7777青苹果| 亚洲成a人片在线观看中| 黑森林福利视频导航| 免费公开在线视频| 成人网中文字幕色| 久久都是精品| 九九福利| 亚洲天天做日日做天天看2018| 美国一级毛片不卡无毒| 日日草夜夜草| 综合一个色| 国产色视频在线| 在线欧美激情| 色五月激情五月| 一级片视频在线观看| 亚洲一在线| 免费人成网555www| 九九热在线精品| 网站毛片| 亚洲福利视频网址| 男女一进一出无遮挡黄| 久久99免费| 日本xxx69hd| 日本黄色免费片| 人人爱人人澡| 午夜免费影院| 亚色综合| 中文字幕va| 白嫩美女在线啪视频观看| 中文字幕一二三四区| 老司机午夜网站| 国产a一级毛片午夜剧场14| 色综合久久久久久久久五月| 天天射天天干天天色| 一色屋免费视频| 在线免费看高清视频大全|