首页 > 其他分享 >[米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-19读写I2C接口EEPROM实验

[米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-19读写I2C接口EEPROM实验

时间:2024-07-18 18:54:17浏览次数:17  
标签:安路 FPGA DR1 地址 iic I2C 数据 EEPROM 字节

软件版本:Anlogic -TD5.9.1-DR1_ES1.1

操作系统:WIN10 64bit

硬件平台:适用安路(Anlogic)FPGA

实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

目录

1 概述

1.1 EEPROM简介

1.2 EEPROM-24C02介绍

1.3 硬件电路分析

2 用户程序设计

2.1 IIC MASTER控制器驱动

2.2 用户控制状态机

2.3 程序源码

3 FPGA工程

4 Modelsim仿真

4.1 准备工作

4.2 启动modelsim仿真

5 下载演示

5.1 硬件连接

5.2 运行结果


1 概述

前面的课程中,我们学习了I2C总线协议,以及介绍了米联客I2C Master控制器的实现原理、内部状态机、I2C时序产生、外部控制接口。本文开始,后面所涉及的I2C总线相关内容都会使用该控制器实现。本实验使用米联客的uii2c控制器实现对EEPROM的访问。

在完成本实验前,请确保已经完成前面的实验,包括已经掌握以下能力:

1:完成了TD软件安装

2:完成了modelsim安装以及TD库的编译

3:掌握了TD仿真环境的设置

4:掌握了modesim通过do文件启动仿真

1.1 EEPROM简介

EEPROM (Electrically Erasable Programmable read only memory),即带电可擦可编程只读存储器,与传统的ROM不同,EEPROM是一种特殊的只读存储器,数据可以被多次擦除和编程,而且掉电后数据不丢失。

EEPROM发展过程:

1、ROM(Read Only Memory,只读存储器)

在芯片制造过程中通过特殊的工艺在ROM内烧录数据,其中的内容只能读不能改,用户只能验证写入的资料是否正确,不能对芯片内的数据进行修改。如果ROM中的数据有错误,只能重新制作一个新的ROM。

2、PROM(Programmable ROM,可编程ROM)

芯片制作中没有向PROM内部烧录数据,用户可以用专用的编程器将自己的数据写入PROM,但是只能写入一次,如果PROM中的数据有错误,只能重新制作一个新的PROM。

3、EPROM(Erasable Programmable ROM,可擦除可编程ROM)

EPROM芯片可重复擦除和写入,解决了PROM芯片只能写入一次的弊端。用户可以用专用的编程器将自己的数据写入EPROM,,如果EPROM中的数据有错误,EPROM芯片可以通过紫外线照射正面可视的内部芯片来擦除其内的所有数据。

4、EEPROM(Electrically Erasable Programmable ROM,电可擦除可编程ROM)

EEPROM的擦除不需要借助于其它设备,用户可以通过电子信号来修改其内容的数据,而且是以字节Byte为最小修改单位,不必将数据全部擦除才能写入。

1.2 EEPROM-24C02介绍

24C02是基于I2C总线的存储器件,遵循二线制协议,它具有接口方便,体积小,数据掉电不丢失等特点。24C02是一个2Kbit的串行EEPROM存储芯片,可存储256个字节数据。工作电压范围为1.8V到6.0V,具有低功耗CMOS技术,自定时擦写周期,1000000次编程/擦除周期,可保存数据100年。通过I2C总线通讯读写芯片数据,通讯时钟频率可达400KHz。

可以通过存储IC的型号来计算芯片的存储容量是多大,比如24C02后面的02表示的是可存储2Kbit的数据,转换为字节的存储量为21024/8 = 256byte;比如24C04后面的04表示的是可存储4Kbit的数据,转换为字节的储存量为41024/8 = 512byte;以此来类推其它型号的存储空间。

引脚说明:

A0-A2:设备地址输入

SDA:串行地址和数据输入/输出

SCL:串行时钟输入,SCL同步数据传输,上升沿写入数据,下降沿读出数据

WP:硬件数据保护脚,接VCC时,写保护只读;接地时,允许数据正常的读写操作

NC:No Connect

GND:地

VCC:正电源

24LXX 芯片器件地址:

对于不同存储容量的EEPROM,具有不同的从器件地址。由于24C02为2k容量,也就是说只需要参考图中第一行的内容:前四位固定为1010,A2~A0为由管脚电平(000~111),最多级联8个同种类芯片。比如24C04参考图中第二行的内容:前四位固定为1010,A2~A1为由管脚电平(00~11),最多级联4个同种类芯片,A0(P0)为空脚,可接地。

片内地址寻址

EEPROM作为一个存储器件,其芯片内部每一个存储单元都有一个片内地址。我们可对24C02内部256字节中的任一个进行读/写操作,其寻址范围为00~FF,共256个寻址单位。

由于24C02只有256个字节的存储空间,所以只需要1个字节(00000000~11111111)就可以寻址完24C02的存储空间,但是无法寻址完更大容量的存储IC,比如24C04的存储容量是512字节,需要9个bit的地址位才能寻址完,24C04的器件地址内是没有A0参数的,也就是说24C04的A0引脚是不起作用的,这个就是24C04的第9个bit的地址位。其它存储器如24C08、24C16同理。

24C02读/写操作

模式

功能

写操作

字节写

按字节写入

页写

按页写入

读操作

当前地址读

从当前默认地址读

随机地址读

从指定的地址读

连续地址读

从起始地址连续读

写字节操作BYTE WRITE

在起始位产生后,先写器件地址,再写芯片内存地址,再写入数据,最后产生停止位,每写一个字节都要产生ACK位。主机必须用一个停止条件终止写序列。此时,EEPROM进入一个内部计时的写周期,在这个写周期中,所有输入都被禁用,EEPROM直到写完成才会响应。

页写PAGE WRITE

页写和字节写差不多,在字节写的基础上,连续写入数据,最后产生停止位。当写入数据到达页面边界时,下面的字节被放置在同一页面的开头并覆盖之前的数据。

读当前地址CURRENT ADDRESS READ

内部地址计数器保存着上次访问时最后一个地址加1的值,只要芯片有电,该地址就一直保存当读到最后页的最后字节,地址会回转到0,最后的读数据可以不需要发送ACK。读取期间的地址“翻转”是从最后一个内存页的最后一个字节到第一个页的第一个字节。

随机读RANDOM READ

随机读需先写先发送器件地址,然后发送字地址,一旦EEPROM接收器件地址和字地址并应答了ACK,主器件就产生一个重复的起始条件之后再发送器件地址并且读取数据,最后的读数据可以不需要发送ACK。

连续读SEQUENTIAL READ

可以从当前地址读和随机地址读方式启动后,连续读取,但是需要注意的时候除最后一个读数据,其他的读主机都需要发送ACK。若达到存储器最后一个字节,地址自动回转到0,仍可继续顺序读取数据。主器件发送停止条件,即可结束顺序读操作。

I2C起始停止时序

I2C时序参数

1.3 硬件电路分析

IIC通信一定要用上拉电阻(R110、R111),我们常用4.7KΩ的电阻,如果电阻越小,通信速率越大。由原理图可知,我们开发板上的EEPROM可编程地址 A2、A1、A0接地,所以24C02的器件地址为1010000。

用户程序设计

本次实验实现每次写一个字节到EEPROM,再读一个字节,并将读写的数据进行对比是否有无。实验包含两个模块,I2C MASTER控制器驱动模块、用户控制模块。以下给出系统框图,通过4位LED显示读的数据,通过1位LED显示是否读写数据发送错误。 关于IIC MASTER控制器驱动的详细描述请看前面的实验,我们主要看用户控制模块关于状态机的部分。芯片内部接收到的有效信号通过在线逻辑分析仪在线观察结果。

2.1 IIC MASTER控制器驱动

先温习下前面课程内容中关于I2C控制器的功能模块可以接口信号:

IO_sda为I2C双向数据总线

O_scl为I2C时钟

I_wr_cnt写数据字节长度,包含了器件地址,发送I_iic_req前,预设该值

I_rd_cnt读数据字节长度,仅包含读回有效部分,发送I_iic_req前,预设该值

I_wr_data写入的数据

O_rd_data读出的数据,如果是读请求,当O_iic_busy从高变低代表数据读回有效

I_iic_req I2C操作请求,根据I_rd_cnt是否大于0决定是否有读请求

I_iic_mode是否支持随机读写,发送I_iic_req前,预设该值

O_iic_busy总线忙

请求一次I2C传输的控制时序如下:

首先在O_iic_busy=0即I2C总线空闲情况下,设置I_wr_cnt,I_rd_cnt,I_wr_data,并且设置I_iic_req=1,启动I2C传输。当O_iic_busy=1说明I2C控制器开始传输,这时候可以设置I_iic_req=0,结束本次请求,并且等待O_iic_busy=0,当O_iic_busy=0代表本次传输结束.如果发送的是读请求(当I_rd_cnt>0),则此时O_rd_data有效可以读走数据。

2.2 用户控制状态机

首先进行通过复位进行数据初始化。

TS_S=0:当总线非忙,开始一次I2C数据操作(发送/写数据),将要发送的字节寄存到wr_data,并放入MASTER控制器驱动的写数据寄存器O_rd_data,我们需要写入3个BYTES数据,包含8bit器件地址、8bit片内地址、8bit数据。

TS_S=1:发送过程中,iic_busy拉高代表总线忙,重置iic_req=0,并进入到下一个状态。

TS_S=2:通过一段时间延时delay结束,确保数据数据全部写入到EEPPROM,再开始一次I2C数据操作(接收/读数据),需要写2个BYTE(1个器件地址8'b10100000,1个寄存器地址wr_data[15:8]),需要读1个BYTE数据。

TS_S=3:接收过程中,iic_busy拉高代表总线忙,重置iic_req=0,并进入到下一个状态。

TS_S=4:当总线非忙,代表前面读数据完成,对比发送和接收的数据是否有误,数据正确后地址和数据都加1。

TS_S=5:500ms使能信号拉高时,回归到TS_S=0状态,开启下一个字节地址的写数据和读数据操作。

2.程序源码

`timescale 1ns / 1ns//仿真时间间隔/精度


module eeprom_test#
(
parameter SYSCLKHZ     =  100_000_000 //定义系统时钟100MHZ
)
(
input  wire I_sysclk,//系统时钟输入
output wire O_iic_scl,// I2C SCL时钟
inout  wire IO_iic_sda,//I2C SDA数据总线
output wire [3:0]O_test_led,//测试LED
output wire O_error_led //error LED
);
  
localparam T500MS_CNT   = (SYSCLKHZ/2-1); //定义每500ms访问一次EEPROM 

reg [8 :0] 	rst_cnt   	 = 9'd0;//延迟复位计数器
reg [25:0]  t500ms_cnt	 = 26'd0;//500ms计数器
reg [19:0]  delay_cnt 	 = 20'd0;//eeprom每次读写完后,延迟操作计数器
reg [2 :0]	TS_S 	  	 = 2'd0; // 读写EEPROM状态机
reg 		iic_req 	 = 1'b0; //i2c总线,读/写请求信号
reg [31:0]	wr_data   	 = 32'd0;//写数据寄存器
reg [7 :0]	wr_cnt 	  	 = 8'd0;//写数据计数器
reg [7 :0]	rd_cnt 	  	 = 8'd0;//读数据计数器
wire 		iic_busy; // i2c总线忙信号标志
wire [31:0] rd_data;  // i2c读数据
wire		t500ms_en;// 500ms延迟到使能

wire IO_iic_sda_dg;
wire iic_bus_error;  //i2c总线错误
reg iic_error = 1'b0; //i2c 读出数据有错误
assign O_test_led  = rd_data[3:0];//测试LED输出,注意硬件上LED驱动方式
assign O_error_led = iic_error;//通过LED显示错误标志,注意硬件上LED驱动方式
assign t500ms_en = (t500ms_cnt==T500MS_CNT);//500ms 使能信号
                
//通过内部计数器实现复位
always@(posedge I_sysclk) begin
    if(!rst_cnt[8]) 
        rst_cnt <= rst_cnt + 1'b1;
end

//I2C总线延迟间隔操作,该时间约不能低于500us,否则会导致EEPROM操作失败
always@(posedge I_sysclk) begin
    if(!rst_cnt[8])
        delay_cnt <= 0;
    else if((TS_S == 3'd0 || TS_S == 3'd2 )) 
        delay_cnt <= delay_cnt + 1'b1;
    else 
        delay_cnt <= 0;
end

//每间隔500ms状态机运行一次
always@(posedge I_sysclk) begin
    if(!rst_cnt[8])
        t500ms_cnt <= 0;
    else if(t500ms_cnt == T500MS_CNT) 
        t500ms_cnt <= 0;
    else 
        t500ms_cnt <= t500ms_cnt + 1'b1;
end

//状态机实现每次写1字节到EEPROM然后再读1字节
always@(posedge I_sysclk) begin
    if(!rst_cnt[8])begin
        iic_req   <= 1'b0;
        wr_data   <= 32'd0;
        rd_cnt    <= 8'd0; 
        wr_cnt    <= 8'd0;
        iic_error <= 1'b0;
        TS_S      <= 3'd0;    
    end
    else begin
        case(TS_S)
        0:if(!iic_busy)begin//当总线非忙,可以开始一次I2C数据操作
            iic_req <= 1'b1;//请求发送数据
            wr_data <= {8'hfe,wr_data[15:8],wr_data[15:8],8'b10100000};//数据寄存器中8'b10100000代表需要写的器件地址,第一个wr_data[15:8]代表了EEPROM内存地址,第二个wr_data[15:8]代表了写入数据
            rd_cnt  <= 8'd0; //不需要读数据
            wr_cnt  <= 8'd3; //需要写入3个BYTES数据,包含1个器件地址,1个EEPROM 寄存器地址 1个数据   
            TS_S     <= 3'd1;//进入下一个状态      
        end
        1:if(iic_busy)begin 
            iic_req  <= 1'b0; //重置iic_req=0
            TS_S     <= 3'd2;
        end
        2:if(!iic_busy&&delay_cnt[19])begin //当总线非忙,可以开始一次I2C数据操作,该时间约不能低于500us,否则会导致EEPROM操作失败
            iic_req  <= 1'b1;//请求接收数据
            rd_cnt  <= 8'd1; //需要读1个BYTE
            wr_cnt  <= 8'd2; //需要些2个BYTE(1个器件地址8'b10100000,和1个寄存器地址wr_data[15:8])(I2C控制器会自定设置读写标志位)
            TS_S    <= 3'd3;  //进入下一个状态
        end     
        3:if(iic_busy)begin 
            iic_req  <= 1'b0; //重置iic_req=0
            TS_S     <= 3'd4;
        end    
        4:if(!iic_busy)begin//当总线非忙,代表前面读数据完成
            if(wr_data[23:16] != rd_data[7:0])//比对数据是否正确
                iic_error <= 1'b1;//如果有错误,设置iic_error=1
            else 
                iic_error <= 1'b0;//如果没有错误,设置iic_error=0
                wr_data[15:8] <= wr_data[15:8] + 1'b1;//wr_data[15:8]+1 地址和数据都加1
            TS_S    <= 3'd5;
        end
        5:if(t500ms_en)begin//延迟操作后进入下一个状态
            TS_S    <= 3'd0; 
        end 
        default:
            TS_S    <= 3'd0;
    endcase
   end
end

//例化I2C控制模块
uii2c#
(
.WMEN_LEN(4),//最大支持一次写入4BYTE(包含器件地址)
.RMEN_LEN(4),//最大支持一次读出4BYTE(包含器件地址)
.CLK_DIV(SYSCLKHZ/50000)//100KHZ I2C总线时钟
)
uii2c_inst
(
.I_clk(I_sysclk),//系统时钟
.I_rstn(rst_cnt[8]),//系统复位
.O_iic_scl(O_iic_scl),//I2C SCL总线时钟
.IO_iic_sda(IO_iic_sda),//I2C SDA数据总线
.I_wr_data(wr_data),//写数据寄存器
.I_wr_cnt(wr_cnt),//需要写的数据BYTES
.O_rd_data(rd_data), //读数据寄存器
.I_rd_cnt(rd_cnt),//需要读的数据BYTES
.I_iic_req(iic_req),//I2C控制器请求
.I_iic_mode(1'b1),//读模式
.O_iic_busy(iic_busy),//I2C控制器忙
.O_iic_bus_error(iic_bus_error)//总线错误信号标志
//.IO_iic_sda_dg(IO_iic_sda_dg)//debug IO_iic_sda
); 


endmodule

3 FPGA工程

fpga工程的创建过程不再重复

米联客的代码管理规范,在对应的FPGA工程路径下创建uisrc路径,并且创建以下文件夹

01_rtl:放用户编写的rtl代码

02_sim:仿真文件或者工程

03_ip:放使用到的ip文件

04_pin:放fpga的pin脚约束文件或者时序约束文件

05_boot:放编译好的bit或者bin文件(一般为空)

06_doc:放本一些相关文档(一般为空)

4 Modelsim仿真

4.1 准备工作

Modelsim仿真的创建过程不再重复,如有不清楚的请看前面实验

`define timeslice 20
module eeprom(
input scl,
inout sda);
reg out_flag;
reg [7:0] memory[2047:0];
reg[10:0] address;
reg[7:0] memory_buf;
reg [7:0] sda_buf;
reg [7:0] shift;
reg [7:0] addr_byte;
reg [7:0] ctrl_byte;
reg [1:0] State;
integer i;


// ----------------------------------------------
parameter r7=8'b10101111,w7=8'b10101110,
          r6=8'b10101101,w6=8'b10101100,
			 r5=8'b10101011,w5=8'b10101010,
			 r4=8'b10101001,w4=8'b10101000,
			 r3=8'b10100111,w3=8'b10100110,
          r2=8'b10100101,w2=8'b10100100,
			 r1=8'b10100011,w1=8'b10100010,
			 r0=8'b10100001,w0=8'b10100000;
			 
//---------------------------------------------------

assign sda= (out_flag == 1)?sda_buf[7]:1'bz;
//--------------------寄存器和存储器初始化------------------------------
initial
begin
addr_byte   =0;
ctrl_byte   =0;
out_flag    =0;
sda_buf     =0;
State       =2'b00;
memory_buf  =0;
address     =0;
shift       =0;
for(i=0;i<=2047;i=i+1)
memory[i]=0;
end

//--------------启动信号检测--------------
always @(negedge sda)
			if(scl == 1)
          	 begin
			 	State=State+1;
			 	if(State==2'b11)
				 disable write_to_eeprm;
			 end				
 /-------------------主状态机-----------------------
always @(posedge sda)
				if(scl == 1)
            	stop_W_R;
				else
				begin
				casex(State)  
				2'b01:
				begin
				read_in;
				    if(ctrl_byte == w7||ctrl_byte == w6|| ctrl_byte == w5
				    || ctrl_byte == w4 || ctrl_byte == w3 || ctrl_byte == w2 ||ctrl_byte == w1 ||ctrl_byte == w0)
					 begin
					 	State = 2'b10;
					 	write_to_eeprm;
					 end
					 else 
					 	State = 2'b00;
				end
					 
				2'b11:
					 read_from_eeprm;
					 default:
					       State=2'b00;
					 endcase
					 end

				
//--------------操作停止------------------
task stop_W_R;
       begin
		 
		 State = 2'b00;
		 addr_byte  =0;
		 ctrl_byte  =0;
		 out_flag   =0;
		 sda_buf   =0;
		 end
	endtask
//----------------读进控制字和存储单元地址-------------------
	task read_in;
	begin
	shift_in(ctrl_byte);
	shift_in(addr_byte);
	end
	endtask
	//-------------EEPROM--------------------
	task write_to_eeprm;
	begin
	shift_in(memory_buf);
	address    ={ctrl_byte[3:1],addr_byte};
	memory[address]  = memory_buf;
	$display("eeprm---memory[%0h]=%0h",address,memory[address]);
	State= 2'b00;
	end
	endtask
	
	
	//-------------EEPROM读操作_______________________
	task read_from_eeprm;
	begin
	shift_in(ctrl_byte);
	if(ctrl_byte == r7 || ctrl_byte == r6 || ctrl_byte == r5 || ctrl_byte == r4 || ctrl_byte == r3 || ctrl_byte == r2
	    || ctrl_byte == r1 || ctrl_byte == r0)
		 begin
		 address = {ctrl_byte[3:1],addr_byte};
		 sda_buf =memory [address];
		 shift_out;
		 State = 2'b00;
	end
	end
	endtask
	
	// ---SDA 数据线上的数据存入寄存器 ,数据在SCL的高电平有效------------------
	task shift_in;
	output[7:0] shift;
	begin
	@(posedge scl) shift[7]=sda;
	@(posedge scl) shift[6]=sda;
	@(posedge scl) shift[5]=sda;
	@(posedge scl) shift[4]=sda;
	@(posedge scl) shift[3]=sda;
	@(posedge scl) shift[2]=sda;
	@(posedge scl) shift[1]=sda;
	@(posedge scl) shift[0]=sda;
	@(negedge scl) //ACK
	begin
	#`timeslice;//模拟芯片的延迟输出ACK
	out_flag = 1;
	sda_buf  =0;
	end
	@(negedge scl)//结束ACK
	#`timeslice out_flag  = 0;
	end
	endtask
	//----------EEPROM存储器中的数据通过SDA数据线输出,数据在SCL低电平时变化
   task shift_out;
	begin
	out_flag= 1;
	for(i=6;i>=0;i=i-1)
	begin
	
	@(negedge scl);
	# `timeslice;
	sda_buf = sda_buf<<1;
	end
   @(negedge scl) # `timeslice sda_buf[7]=1;
	@(negedge scl) # `timeslice out_flag=0;
	end
	endtask
	endmodule 

Eeprom仿真模型

顶层调用接口仿真代码

`timescale 1ns / 1ns

module sim_top_tb();

reg  sysclk = 1;//系统时钟输入
wire iic_scl;// I2C SCL时钟
wire iic_sda;//I2C SDA数据总线


pullup( iic_sda );

eeprom_test #(
. SYSCLKHZ(1000_000)   
) eeprom_test_inst
(
.I_sysclk(sysclk),
.O_iic_scl(iic_scl),
.IO_iic_sda(iic_sda)
);
    
eeprom eeprom_inst(
.scl(iic_scl),
.sda(iic_sda)
);    

always 
    begin
        #10 sysclk = ~sysclk;
    end
 
endmodule

4.启动modelsim仿真

启动后,右击需要观察的信号,添加到波形窗口,并仿真。

放大观察I2C时序,查看写操作START和ACK位置

放大观察I2C时序,查看写读操作Repeated START

下载演示

为了方便观察结果,使用LED观察,每间隔500ms完成一次读写操作

下载程序前,先确保FPGA工程已经编译。

5.1 硬件连接

(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)

请确保下载器和开发板已经正确连接,并且开发板已经上电(注意JTAG端子不支持热插拔,而USB接口支持,所以在不通电的情况下接通好JTAG后,再插入USB到电脑,之后再上电,以免造成JTAG IO损坏)

eeprom芯片在底板背面U31位置

5.2 运行结果

(该教程为通用型教程,教程中仅展示一款示例开发板的上板现象,具体现象以所购买的开发板型号以及配套代码上板现象为准。)

通过LED观察I2C的读写结果,当 LED 5亮表示有错误,否则就是正确。

标签:安路,FPGA,DR1,地址,iic,I2C,数据,EEPROM,字节
From: https://blog.csdn.net/u011570052/article/details/140530378

相关文章

  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-19读写I2C接口EEPROM实验
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述......
  • 基于FPGA的MSK调制解调系统verilog开发,包含testbench,同步模块,高斯信道模拟模块,误
    1.算法仿真效果本程序系统是《m基于FPGA的MSK调制解调系统verilog开发,并带FPGA误码检测模块和matlab仿真程序》的的升级。 升级前原文链接 增加了完整的AWGN信道模型的FPGA实现,可以在testbench里面设置SNR,分析不同SNR对应的FPGA误码率情况。 vivado2019.2仿真结果如下(......
  • FPGA CFGBVS 管脚接法
    说明新设计了1个KU040FPGA板子,回来之后接上JTAGFPGA不识别。做如下检查:1、电源测试点均正常;2、查看贴片是否有漏焊,检查无异常,设计上NC的才NC;3、反复检查JTAG接线是否异常,贴片是否异常;上述检查均无问题,开始查看原理图,逐个对照XILINX手册进行研究。其中发现CFGBVS在设计......
  • 基于FPGA的万兆网卡实现(二)——功能测试
      本文在前文代码的基础上进行拓展,通过引入40G以太网子系统,实现万兆网卡的接口带宽要求。本文主要对功能进行实现,整体结构简化如下:  FPGA使用XilinxUltrascale+VCU128开发板,操作系统使用Ubuntu20.04,使用到的驱动代码与RHEL8.8(RedHat)兼容。本文主要介绍以太网子系统(E......
  • (138)SRAM接口--->(001)基于FPGA实现SRAM接口
    1目录(a)FPGA简介(b)IC简介(c)Verilog简介(d)基于FPGA实现SRAM接口(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电......
  • (137)SRAM接口--->(004)基于FPGA实现SRAM接口
    1目录(a)FPGA简介(b)IC简介(c)Verilog简介(d)基于FPGA实现SRAM接口(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电......
  • 基于TI Sitara系列AM5728工业开发板——FPGA视频开发案例分享
    前言 本文主要介绍FPGA视频开发案例的使用说明,适用开发环境:Windows7/1064bit、XilinxVivado2017.4、XilinxSDK2017.4。评估板简介创龙科技TL5728F-EVM是一款基于TISitara系列AM5728(双核ARMCortex-A15+浮点双核DSPC66x)+XilinxArtix-7FPGA处理器设计的高端异......
  • 基于AM62x GPMC并口的ARM+FPGA低成本通信方案
    GPMC并口简介GPMC(GeneralPurposeMemoryController)是TI处理器特有的通用存储器控制器接口,支持8/16bit数据位宽,支持128MB访问空间,最高时钟速率133MHz。GPMC是AM62x、AM64x、AM437x、AM335x、AM57x等处理器专用于与外部存储器设备的接口,如:(1)FPGA器件(2)ADC器件(3)SRAM内......
  • 【读书笔记】《深度神经网络FPGA设计与实现》(孙其功)第三章 深度神经网络基础层算子介
    深度神经网络基础层算子介绍1.卷积算子2.反卷积算子3.池化算子(1)平均池化算子:(2)最大池化算子:4.激活算子5.全连接算子6.Softmax算子7.批标准化算子8.Shortcut算子1.卷积算子基础概念(1)卷积核(Kernel)。图像处理时,对输入图像中一个小区域像素加权......
  • 基于FPGA的千兆以太网设计(1)----大白话解释什么是以太网
    1、什么是以太网?        还记得初学以太网的时候,我就被一大堆专业名词给整懵了:什么以太网,互联网,MAC,IP,局域网,万维网,网络分层模型····等等等等。慢着!我学的不是以太网吗?怎么出来这么一大堆东西?        啊!以太网究竟是什么?别急,我接下来就尽量用通俗的大白话......