700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 韦东山 IMX6ULL和正点原子_「正点原子FPGA连载」第十一章RGB LCD彩条显示(一)

韦东山 IMX6ULL和正点原子_「正点原子FPGA连载」第十一章RGB LCD彩条显示(一)

时间:2023-05-24 08:00:48

相关推荐

韦东山 IMX6ULL和正点原子_「正点原子FPGA连载」第十一章RGB LCD彩条显示(一)

1)实验平台:正点原子达芬奇FPGA开发板

2) 摘自【正点原子】达芬奇之Microblaze 开发指南

3)购买链接:/item.htm?id=624335496505

4)全套实验源码+手册+视频下载地址:/docs/boards/fpga/zdyz_dafenqi.html

5) 正点原子官方B站:/394620890

6)对正点原子FPGA感兴趣的同学可以加群讨论:876744900

第十一章RGB LCD彩条显示实验

在《达芬奇之FPGA开发指南》中“RGB_LCD彩条显示实验”介绍了如何在LCD液晶显示屏上显示彩条,本章我们将使用MicroBlaze软核处理器在RGB TFT-LCD液晶屏上显示彩条。本章包括以下几个部分:

1111.1 简介

11.2 实验任务

11.3 硬件设计

11.4 软件设计

11.5 下载验证

11.1简介

本章将通过MicroBlaze处理器实现RGB LCD的彩条显示,其实现思路是:MicroBlaze处理器产生彩条数据,并通过AXI4接口将数据写入外部DDR3中。FPGA负责读取外部DDR3中的彩条数据,然后将数据传输给内部LCD屏驱动模块,以驱动外部RGB LCD屏显示彩条。MicroBlaze只进行DDR3的写操作,而FPGA负责DDR3的读操作。我们知道,在MicroBlaze的开发中,无论是对DDR3进行写操作或者读操作,都是将数据通过AXI4接口传输到DDR3控制器,然后DDR3控制器和外部DDR3做数据交互,因此需要我们熟悉掌握AX14的接口协议和时序,才能实现对DDR3的读写操作。

AXI4接口总共有三种类型,它们分别是AXI4(AXI4-Full)、AXI4-Lite和AXI4-Stream,不同的接口类型适用于不同的应用场景,下面对这三个接口做简要说明。

AXI4-Full:最高性能的接口,适合存储器映射的通信,支持每个地址阶段最高256个数据传输周期的批量传输,最适合于更需要持久、高速性能的IP。

AXI4-Lite:AXI4-Full接口的轻量级版本,用于存储器映射的单次数据通信会话。这个版本的好处是简化了的接口占用较少的逻辑部分面积。这个版本不支持批量数据,只支持每次传输单个数据,适合于需要最小硬件消耗的较低性能的IP。

AXI4-Stream:它没有地址阶段,因此不是存储器映射。为流式数据的传输定义了单个通道,支持无数量限制的批量传输,最适合于需要持续固定数据流的应用。连接只能是从主机到从机,所以如果需要双向传输的话,两个外围设备都必须是主机/从机兼容类型的。

本次实验需要通过AXI4接口源源不断地从DDR3中读出彩条数据,因此数据量较大,由于AXI4-Lite速度稍慢,不适合本实验;AX14-Stream虽然本身占用资源不多,但是为了和AXI互联模块连接,需要接AXI DMA或者其它模块,占的资源反而更多,而达芬奇开发板资源有限,因此AXI4-Stream接口也不适合;AXI4(AXI4-Full)接口无论在资源占用还是速度方面均能满足本实验的需求,故本实验采用的接口为AXI4。

AXI4协议具有5个独立的通道,分别为:读地址通道、读数据通道、写地址通道、写数据通道和写响应通道,通道之间相互独立且存在差别。通信是由主机发起的,主机可以对从机进行数据的读或写操作。每次读或写操作都需要相应的读地址通道或写地址通道传输一个地址。数据传输使用写数据通道来实现主机到从机的写数据传输,数据传输使读数据通道用来实现从机到主机的读数据传输。下面以AXI4 IP核为例,详细介绍AXI4协议的各通道和通道接口。

在本实验中FPGA从外部DDR3中读取数据,可视为主机,所以在例化、封装IP时应选择“Master”作为主机,接口名字以m_为前缀(具体步骤会在本章中详细描述,我们先直接拿来为大家讲解相关的通道和接口)。AXI4 IP核未展时开如下图所示:

图 11.1.1 未展开时接口

上图红标1处为IP核的时钟和复位信号,红标2处M_AXI为通道接口,其他为数据验证信号。下面展开红标2处,介绍M_AXI接口,如下图所示:

图 11.1.2 展开时通道和接口

在上图中,以m_axi_aw_为前缀的接口属于写地址通道;以m_axi_w_为前缀的接口属于写数据通道;以m_axi_b_为前缀的接口属于写响应通道;以m_axi_ar_为前缀的接口属于读地址通道;以m_axi_r_为前缀的接口属于读数据通道。

写地址通道包含的信号及信号含义如下表所示:

表11.1.1 通道信号

写数据通道包含的信号及信号含义如下表所示:

表11.1.2 通道信号

写响应通道包含的信号及信号含义如下表所示:

表11.1.3 通道信号

读地址通道包含的信号及信号含义如下表所示:

表11.1.4 通道信号

表11.1.5 通道信号

在进行数据传输的过程中,传输通道均使用valid/ready信号对传输过程的地址、数据、控制信号进行握手。使用双向握手机制,valid和ready都有效的时候表示握手成功。下面将以地址通道为例介绍几种常见的握手方式。

valid在ready前有效:主机先给出数据和控制信息,同时驱动valid为高电平。一旦主机驱动valid为高,地址将保持不变,直到从机驱动ready信号为高。一旦从机驱动ready为高,则握手成功,在时钟上升沿T3时刻开始进行地址。如下图所示:

图 11.1.3 valid在ready之前

valid在ready后有效:从机在主机驱动valid前,就驱动了ready信号为高。一旦主机确定valid信号为高,则握手成功,在T3时刻开始传输地址。如下图所示:

图 11.1.4 valid在ready之后

valid和ready同时有效:主机驱动valid和从机驱动ready同时发生,在T2时刻开始传输地址。如下图所示:

图 11.1.5 valid和ready同时有效

AXI4读通道结构如下图所示:

图 11.1.6读通道结构

由上图可知,主机首先传递地址和控制信息给从机,之后从机将有效的地址上对应的读数据批量读数据发送给主机。在突发读过程中,读通道上典型的信号交互过程如下图所示:

图 11.1.7 突发读信号交互

由上图可知在读地址通道中:主机在T0时间段内先提供地址m_axi_araddr,同时将m_axi_arvalid拉高;从机在T1时间段内将m_axi_arready拉高,表明从机可以接收地址;m_axi_aradd和m_axi_arready均为高时则握手成功,在T2时钟上升沿时刻,开始传输地址。

在读数据通道中:主机在T3时间段内将m_axi_rready拉高,表明主机可以接收数据;从机在T5时间段内提供读数据同时将m_axi_rvalid拉高,表明数据D0有效可以读出;m_axi_rvalid和m_axi_rready均为高时则握手成功,在T6时钟上升沿时刻,开始传输数据D0。同理在T9、T10时钟上升沿时刻,分别输数据D1、D2。在T13时钟上升沿时刻,从机拉高m_axi_rlast,表明D3是此次突发最后一个需要传输的数据。

AXI4写通道结构如下图所示:

图 11.1.8写通道结构

由上图可知,主机首先传递地址和控制信息,再发送批量写数据给从机。从机接收完所有的数据后,从机发送一个写响应信号给主机。突发写过程中写通道上典型的信号交互过程如下图所示:

图 11.1.9 突发写信号交互

由上图可知在写地址通道中:主机在T0时间段内先提供地址m_axi_awaddr,同时将m_axi_awvalid拉高;从机在T1时间段内将m_axi_awready拉高,表明从机可以接收地址;m_axi_awaddr和m_axi_awready均为高时则握手成功,在T2时钟上升沿时刻,开始传输地址。

在写数据通道中:主机在T2时间段内先提供写数据D0,同时将m_axi_awvalid拉高,表明该数据有效;从机在T3时间段内将m_axi_wready拉高,表明从机可以接收数据;m_axi_awvalid和m_axi_wready均为高时则握手成功,T4时钟上升沿时刻,开始传输数据D0。同理,在T6、T8、T9时钟上升沿时刻,分别传输数据D1、D2、D3;

在写响应通道中:主机在T2时间段内将m_axi_bready拉高,表示主机可以接收来自从机的写响应信号;从机接收此次突发最后一个传输的写数据D3时,在T9时间段提供些响应信号OKAY,同时将m_axi_bvalid拉高,表明写响应信号有效。m_axi_bvalid和m_axi_bready均为高时则握手成功,T10时钟上升沿时刻,开始传输OKAY。注意:写响应信号必须跟随最后一次突发的写传输数据。

多个具有AXI4协议的设备或模块可以通过互联模块进行数据的交互。如下图所示:

图 11.1.10 多机互联

11.2实验任务

本章的实验任务是Microblaze处理器向DDR3中写彩条数据,然后通过自定义的带AXI接口的IP核将彩条数据从DDR3中读出来,并显示在RGB LCD液晶屏上(支持正点原子推出的所有RGB LCD屏)。

11.3硬件设计

根据简介及实验任务可知,彩条数据先由MicroBlaze写入DDR3,之后被读出并在LCD RGB液晶显示屏上以彩条的形式呈现出来。由此我们可以画出本次实验的系统框图,如下图所示:

图 11.3.1系统框图

在上图中,LCD_RGB_TOP、AXI4_DDR_READ、AXI4_Lite_COMM都是自定义的IP核。

具体的数据流走向:LCD_RGB_TOP首先识别屏幕ID(LCD_ID),MicroBlaze软核根据屏幕ID将对应的彩条数据写入DDR3中,接着AXI4_DDR_READ通过AXI4协议并根据屏幕ID将彩条数据读出至FIFO缓存,数据最后经过驱动模块LCD_RGB_TOP后在LCD屏幕上显示出彩条。

LCD_RGB_TOP模块是由《达芬奇FPGA开发指南》之“RGB_LCD彩条显示实验”的代码模块改动后封装而来,具体的修改会在之后详细说明。此模块用于识别外部接入的的RGB888 TFT-LCD屏幕产生屏幕ID,并将屏幕ID传递给AXI4_Lite_COMM模块和AXI4_DDR_READ模块;另外接收并且驱动被读出的彩条数据在屏幕上展示彩条。

AXI4_Lite_COMM是自定义的带有AXI4接口的IP核,用来传输外设的参数,在本实验中传输的是屏幕ID。AXI4_Lite_COMM可使用AXI GPIO IP核进行代替,但AXI4_Lite_COMM的优势在于今后能连接更多的外设进行更多的参数传输,不用为每一个外设都例化AXI GPIO IP核,因此可以大大减少资源使用量。考虑到达芬奇的资源量以及后续工程的开发,建议使用AXI4_Lite_COMM IP核进行参数传输。

AXI4_DDR_READ IP核是先例化一个带有AXI4接口IP核,然后根据我们的需求修改后再进行封装而成的IP核。该IP核根据屏幕ID,确定DDR3的帧缓存空间大小,通过AXI4接口读出显示数据并传输给后级FIFO。注意,因为本实验只需要读取DDR3中的彩条数据,所以在修改时只启用读功能即可,无需启用写功能。如果在后续的开发中,比如使用摄像头采集图像并将图像数据写入DDR3,最后在LCD屏显示实时图像,这时此IP核的写功能也要被启用。

在硬件环境搭建之前,先进行上述3个IP核的封装和自定义。

(1)AXI4_DDR_READ IP核的封装

首先创建axi4_ddr_read文件夹。打开Vivado软件,软件启动后在“Tasks”一栏选择“Manage IP”,然后点击“New IP Location…”,将工程定位在axi4_ddr_read下,点击“Finish”。接着在菜单栏中点击“Tools”,然后在下拉列表中选择“Create and Package New IP”,如下图所示:

图 11.3.2创建IP核

在弹出的对话框中点击“Next”,选择“Create a new AXI4 Peripheral”,点击“Next”,IP核命名为axi4_ddr_read,位置自动填充在ip_repo下,点击“Next”。如下图所示:

图 11.3.3 IP名称

将接口命名为“M_AXI”,接口类型选择“Full”(AXI4-Full),模式选择“Master”(本实验FPGA通过AXI4协议读取外部DDR3中的数据,所以选择Master作为主机),点击“Next”。如下图所示:

图 11.3.4接口设置

选择“Edit IP”,点击“Finish”。如下图所示:

图 11.3.5 Edit IP核

稍等片刻,软件就会创建一个IP核封装工程,工程包含两个具有AXI4协议完整读写功能的模块。工程如下图所示:

图 11.3.6 axi4_ddr_read IP核封装工程

工程的两个文件模块文件位置如下图所示:

图 11.3.7 模块文件位置

接下来用Notepad++打开两个文件,以便进行修改,依据实验任务可知主要修改点为:彩条数据是由MicroBlaze产生并写入DDR3中,不需要通过axi4_ddr_read写数据,因此代码可屏蔽写相关逻辑。axi4_ddr_read根据屏幕ID从DDR3读取彩条数据后并将彩条数据缓存到FIFO中,所以需要新增FIFO和屏幕ID的接口信号。本实验不再采用状态机的方式控制读功能。

为了代码的整洁和可读性,我们对源代码进行了修改和整理,只保留了突发读相关的代码。下面将解释说明修改后的AXI4协议实现读功能的逻辑。打开axi4_ddr_read_v1_0_M_AXI模块代码:

33 // Users to add ports here 34 input [15:0] lcd_id,35 input [11:0] fifo_wr_cnt, 36 output fifo_wr_en,37 output [31:0] fifo_wr_data,

如上所示,模块端口位置新增FIFO信号有fifo_wr_cnt、fifo_wr_en和fifo_wr_data,新增幕ID信号lcd_id。

570 //根据LCD ID,计算单帧图像突发的次数571 always @ (posedge M_AXI_ACLK) begin572 if(M_AXI_ARESETN == 1'b0) begin 573 burst_end_counter <= 12'd750;574 end575 else begin576 case (lcd_id) 577 16'h4342 : burst_end_counter <= 12'd255; //480*272*16/32/256 = 255 578 16'h4384 : burst_end_counter <= 12'd750; //800*480*16/32/256 = 750 579 16'h7084 : burst_end_counter <= 12'd750; //800*480*16/32/256 = 750 580 16'h7016 : burst_end_counter <= 12'd1200; //1024*600*16/32/256 = 1200 581 16'h1018 : burst_end_counter <= 12'd2000; //1280*800*16/32/256 = 2000 582 default : burst_end_counter <= 12'd750;583 endcase 584 end585 end

本段代码,实现了由屏幕ID(lcd_id)计算单帧图像对应的读突发次数的功能。不同分辨率屏幕的lcd_id不同,对应的突发次数也不同,但计算方法是一样的,如800*480*16/32/256 = 750。其中,800*480为屏幕分辨率;16为RGB565格式的彩条数据位宽;32为突发传输数据的位宽;256为每次突发要传输的数据个数;最终得出计算结果分辨率为800*480的屏幕对应的突发次数为750次。

587 //根据FIFO数据个数,产生开始突发读信号 588 always @ (posedge M_AXI_ACLK) begin589 if(M_AXI_ARESETN == 1'b0 || reads_done == 1'b1) begin 590 start_single_burst_read <= 1'b0;591 end592 else begin 593 if((~axi_arvalid) && (~burst_read_active) && (~start_single_burst_read) 594 && (fifo_wr_cnt <= 12'd256)) begin595 start_single_burst_read <= 1'b1; 596 end 597 else begin598 start_single_burst_read <= 1'b0; 599 end600 end 601 end

本段代码用于驱动突发读开始信号tart_single_burst_read,第593至596行代码表明:在读地址通道的axi_arvalid为低、未正在进行突发读数据传输、缓存FIFO非满的时将该信号拉高,此时进行突发读数据传输,往缓存FIFO中写入数据。由于每次突发读传输的数据个数为256(C_M_AXI_BURST_LEN),因此一次突发读往缓存FIFO中写入256个数据。第一次突发读写入FIFO的256个数据,被读出1个后,FIFO非满,即可允许下一次突发读,此时假设极端情况,下一次突发读的数据全部存入FIFO,因此缓存FIFO至少容纳的数据个数为256-1+256 = 511。保险起见,在后续设计例化缓存FIFO时,其深度设置为1024或更大。

613 //读数据通道axi_rready614 always @(posedge M_AXI_ACLK) 615 begin616 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 )617 begin 618 axi_rready <= 1'b0;619 end622 else if (M_AXI_RVALID) 623 begin 624 if (M_AXI_RLAST && axi_rready)625 begin626 axi_rready <= 1'b0;627 end628 else629 begin630 axi_rready <= 1'b1;631 end632 end 634 end

本段代码驱动读数据通道的主机axi_rready信号,以此表明主机是否可以接收来自从机的读数据。第622行代码表示握手信号M_AXI_RVALID在axi_rready之前有效。第624行至627行代码表明本次突发读传输最后一个数据完成后将axi_rready拉低,主机不再接收数据。第629行至631行代码表明突发传输不是最后一个数据,axi_rready一直拉高。ILA中axi_rready信号波形如下图所示:

图 11.3.8 axi_rready信号波形

由上图可知,在读数据通道上,主机在从机RVALID拉高后将RREADY拉高,数据开始突发传输,之后在突发传输最后数据标志RLAST为低的过程中,突发数据一直有效。

637 //读地址通道axi_arvalid638 always @(posedge M_AXI_ACLK) 639 begin640 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 ) 641 begin 642 axi_arvalid <= 1'b0;643 end645 else if (~axi_arvalid && start_single_burst_read) 646 begin 647 axi_arvalid <= 1'b1;648 end649 else if (M_AXI_ARREADY && axi_arvalid) 650 begin 651 axi_arvalid <= 1'b0;652 end 653 else 654 axi_arvalid <= axi_arvalid;655 end

本段代码驱动读地址通道的主机axi_arvalid信号,表明地址是是否有效。第645行至648行代码表明未进行地址传输时允许进行传输。第649行至652行代码表明地址通道握手信号握手成功后,将axi_arvalid拉低,axi_arvalid持续一个周期的高状态。在ILA中观察axi_arvalid波形如下图所示:

图 11.3.9 axi_arvalid信号波形

由上图可知,在读地址通道上,主机在从机将ERREADY拉高后将AVALID拉高,此时地址有效,地址通道突发传输地址0x85016800。

658 //Next address after ARREADY indicates previous address acceptance 659 always @(posedge M_AXI_ACLK) 660 begin661 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 ) 662 begin 663 axi_araddr <= 'b0;664 end665 else if (M_AXI_ARREADY && axi_arvalid) 666 begin 667 axi_araddr <= axi_araddr + burst_size_bytes;668 end669 else670 axi_araddr <= axi_araddr; 671 end

本段代码用来计算在地址通道上的下次突发读数据的地址。burst_size_bytes为每次突发读256个数据的总字节数。

674 assign rnext = M_AXI_RVALID && axi_rready;

675 assign fifo_wr_en = rnext;

676 assign fifo_wr_data = {M_AXI_RDATA[15:0],M_AXI_RDATA[31:16]};

本段代码驱动缓存FIFO的端口信号,功能是将突发读数据写入到外部缓存FIFO中。由第674可知,数据通道的M_AXI_RVALID与axi_rready握手成功,此时突发读数据有效,可以被写入至外部缓存FIFO。握手信号与突发读传输数据波形如下图所示:

图 11.3.10 突发读数据有效

结合上图和FIFO的端口信号可知,在读数据通道上,当从机RREADY和主机RVALD同时为高时,即可将突发数据写入到缓存FIFO中。

683 //突发次数计数 684 always @(posedge M_AXI_ACLK) 685 begin686 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 ) 687 begin 688 read_burst_counter <= 'b0;689 end690 else if (M_AXI_ARREADY && axi_arvalid) 691 begin 692 if (read_burst_counter <= burst_end_counter - 1'b1)693 begin694 read_burst_counter <= read_burst_counter + 1'b1;695 end 696 end697 else698 read_burst_counter <= read_burst_counter;699 end

本段代码用来统计已经突发的次数read_burst_counter,由第690至第696行代码可知,突发次数在地址通道握手信号握手成功时进行累加,一个有效地址对应一次突发。 704 //突发已经传输的的数据个数计数705 always @(posedge M_AXI_ACLK) 706 begin707 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 || start_single_burst_read) 708 begin 709 read_index <= 0;710 end711 else if (rnext && (read_index != C_M_AXI_BURST_LEN-1)) 712 begin 713 read_index <= read_index + 1;714 end715 else 716 read_index <= read_index;717 end

本段代码用于对一次突发传输的数据个数进行统计。由第711行至714行代码可知,数据通道上握手信号握手成功时read_index进行累加,一次突发传输的数据最大个数为256(C_M_AXI_BURST_LEN值)。

722 //突发传输有效723 always @(posedge M_AXI_ACLK) 724 begin725 if (M_AXI_ARESETN == 0 || reads_done == 1'b1 || start_single_burst_read) 726 burst_read_active <= 0; 728 else if (start_single_burst_read) 729 burst_read_active <= 1'b1;730 else if (M_AXI_RVALID && axi_rready && M_AXI_RLAST) 731 burst_read_active <= 0; 732 end

本段代码用于驱动burst_read_active信号,表明突发传输是否有效。由第728至729行代码可知,在突发读开始信号为高时将burst_read_active拉高,表明突发传输有效;由第730至731行代码可知,如果本次突发读传输的最后一个数据传输完毕,则将其拉低,表明传输无效,突发传输停止。 738 //所有次突发传输完成 739 always @(posedge M_AXI_ACLK) 740 begin741 if (M_AXI_ARESETN == 0) 742 reads_done <= 1'b0;743 else if (M_AXI_RVALID && axi_rready && (read_index == C_M_AXI_BURST_LEN-1) 744 &&(read_burst_counter == burst_end_counter)) 745 reads_done <= 1'b1;746 else 747 reads_done <= 1'b0; 748 end

本段代码用于判断所有突发次数的所有数据是否传输完成。第743行至745行代码可知,read_index == C_M_AXI_BURST_LEN-1用于判断一次突发所有数据传输完成,read_burst_counter == burst_end_counter用于判断突发的次数达到要求。比如,lcd_id为7084,需要750次突发,从第0次开始突发一直到第750次突发的第256个数据传输完成时,拉高reads_done,表明所有数据全部突发完毕。

修改完axi4_ddr_read_v1_0_M_AXI模块后注意要保存!在其例化时新增FIFO和屏幕ID的信号,屏蔽不需要的数据验证信号。顶层模块axi4_ddr_read_v1_0做对应的接口处理。修改后注意要保存!axi4_ddr_read_v1_0模块修改后如下图所示:

图 11.3.11 axi4_ddr_read_v1_0接口

至此,经过如上代码的修改,我们希望该代码能够完成只启用AXI4协议的读功能,并且将读出的数据缓存到了FIFO的功能。但是究竟能不能达到我们的理想,就需要封装该IP并且进行验证,那么接下来我们就进行IP核的封装。(注意,为避免大家在修改遗漏或错误导致后续封装的IP核不能正常使用,所以建议使用例程中的代码文件封装IP核或使用例程中封装好的IP核进行设计),例程中代码文件如下图所示:

图 11.3.12 例程中封装IP核代码文件

拷贝例程中的代码文件替换原来的文件后,回到之前的工程界面,并刷新代码,如下图所示:

图 11.3.13 刷新代码文件

此时右面的封装界面还是替换之前的代码文件对应的封装界面,需要关闭重新打开,重新打开后才是最新代码文件对应的封装界面。点击右上角Package IP红标处,关闭原来的封装界面,如下图所示:

图 11.3.14 关闭原来的封装界面

点击左侧菜单IP Catalog下的“Edit Package IP”,重新打开新代码文件对应的封装界面,如下图所示:

图 11.3.15 点击Edit Package IP

打开新的封装界面后,参考第十章IP核封装过程在Identification中设置信息、在Compatibility中设置兼容性、在File Groups更新文件组、在Customization Parameters刷新定制变量。刷新定制变量如下图所示:

图 11.3.16 刷新变量

紧接着在“Ports and interface”界面可以看到,红标1处的为通道接口;红标2处的为时钟和复位信号接口;红标3处为我们添加的屏幕ID和FIFO信号接口。如下图所示:

图 11.3.17 信号接口

在下图“Customization GUI”界面,红标1处为封装后的的IP核预览图;红标2处为IP核传递的参数,这些参数值可在例化IP核时依据具体的需求设置。

图11.3.18 IP核预览

最后在“Review and Package”界面点击“Package IP”封装IP,封装IP核完成之后,在今后的工程如果需要调用该IP核,可以直接拷贝文件夹axi4_ddr_read_1.0到工程中,并添加至工程即可。封装完成后的IP核在如下路径:

图11.3.19 IP核路径

(2)LCD_RGB_TOP IP核的封装

封装该IP核用到的模块文件如下:

图 11.3.20 模块文件

需要说明的是,这些模块是在《达芬奇之FPGA开发指南》中“RGB_LCD彩条显示实验”的模块代码文件基础上修改而来,每个模块可参考《达芬奇之FPGA开发指南》中的说明解释。

由于本实验在硬件设计是在Block Design中进行的,有些端口就会受到限制,比如双向接口lcd_rgb(LCD数据)。在Block Design中设计硬件时,双向接口会被综合程单向输出接口,所以我们就需要对lcd_rgb进行修改,由一个双向端口修改为三个接口:一个方向接口,一个输入接口和一个输出接口。修改后如下图所示:

图 11.3.21 修改后的lcd_rgb接口

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。