发新帖本帖赏金 8.00元(功能说明)我要提问
返回列表
打印
[FPGA]

FPGA高级验证板,源码持续分享中,讨论开发经验系列(一)

[复制链接]
楼主: feihufuture
手机看帖
扫描二维码
随时随地手机跟帖
41
1993575925| | 2015-9-11 14:52 | 只看该作者 回帖奖励 |倒序浏览
美日晟公司专业生产高频变压器骨架

使用特权

评论回复
42
livelei| | 2015-9-11 16:33 | 只看该作者
ecoren 发表于 2015-9-10 15:13
88E1111是交换芯片吧,

88E1111是PHY芯片,不过功能强大,在前几年的FPGA开发板中用的比较多,MII接口可以配置为GMII,RGMII,SGMII;而且也的确可以实现交换,如果光口和电口的转换可以认为是交换的话,但这种交换应该是不涉及MAC层的。

使用特权

评论回复
43
livelei| | 2015-9-11 16:40 | 只看该作者
现在的FPGA开发板一般会配备比较新的PHY芯片,像是88E1112,88E1512之类的。

使用特权

评论回复
44
eternity1120| | 2015-9-11 16:54 | 只看该作者
虽然还没接触FPGA,不过还是顶楼主,懂得分享的人还是太少。以后请多多指教

使用特权

评论回复
45
feihufuture|  楼主 | 2015-9-11 17:56 | 只看该作者
livelei 发表于 2015-9-11 16:40
现在的FPGA开发板一般会配备比较新的PHY芯片,像是88E1112,88E1512之类的。

10年时,用过88E6095之类的交换芯片,用过88E1112之类的PHY芯片,用于接入层千兆交换机的

使用特权

评论回复
46
livelei| | 2015-9-11 18:41 | 只看该作者
看楼主前面提到想用FPGA做个类似光交换机的验证板?这个好强。楼主对以太网物理层,MAC层,甚至是UDP/TCP层的协议应该是了若指掌啊,确实是神人。

楼主打算好用什么主芯片做这个验证板了么?

使用特权

评论回复
47
studi| | 2015-9-12 14:12 | 只看该作者
支持,支持。

使用特权

评论回复
48
teenagerold| | 2015-9-12 15:42 | 只看该作者
学习一下~

使用特权

评论回复
49
greenapl1985| | 2015-9-12 21:50 | 只看该作者
看了楼主的帖子居然有想哭的感觉,可能是因为最近心情不好吧。觉得自己从11年接搞FPGA也有三四年了,水平始终提不上去。这一年里关于FPGA的工作也越来越少,主管基本安排我进行一些光学实验,说是光学实验,也就是打打杂,基本上跟专业没啥关系的活。
说说我这几年接触过的项目吧:
1.线阵CCD图像采集系统的设计
2.基于TI的D4100开发板的DDR2接口读写功能开发
3.面阵CMOS图采集系统维护
1,2是我独立完成的,3的主要工作是维护和优化。这些项目里FPGA的作用都是在实现通信协议,不涉及算法的东西。
基本上这些都是今年年初完成的了,然后一直到现在我都是在做一些与FPGA完全无关的事情。感觉很迷茫,想跳槽,面了两个公司,第一个我没准备好,第二个过了技术面,但不知为何也没了下文,我一度怀疑是不是因为我是女的,而且年龄也不少了。加上现在求职网站上关于FPGA的工作也越来越少,不知是整个经济不景气,还是FPGA行业不景气的缘故,所以最近几个月也放弃找工作了。唉,感觉自己现在好迷茫,都30岁了,还是这样混日子。

使用特权

评论回复
50
人民币的幻想| | 2015-9-12 22:16 | 只看该作者
给大哥赞一个。顺便问句:搞模拟还是搞FPGA好?我们实验室硬件目前就这两个方向

使用特权

评论回复
51
feihufuture|  楼主 | 2015-9-13 00:06 | 只看该作者
greenapl1985 发表于 2015-9-12 21:50
看了楼主的帖子居然有想哭的感觉,可能是因为最近心情不好吧。觉得自己从11年接搞FPGA也有三四年了,水平始 ...

说我几个观点吧,有错误请批评。。
1 FPGA岗位本来就少,北上广深都不是很多,我老婆搞外贸的,每天招聘前程无忧都在20页,还只是在深圳。

2 FPGA研发男性占优,加班肯定是男性多,公司有这方面的考虑。

3 多花点时间,把简历写好,让别的公司知道你会什么,做过什么,然后多花点时间找,去群里找推荐也行。。

4 你也不一定非要搞研发,累,,,女孩子就要好好保养自己的容颜,找轻松的工作,找个负责任的老公

使用特权

评论回复
52
feihufuture|  楼主 | 2015-9-13 00:07 | 只看该作者
*币的幻想 发表于 2015-9-12 22:16
给大哥赞一个。顺便问句:搞模拟还是搞FPGA好?我们实验室硬件目前就这两个方向 ...

都好,我更倾向于FPGA,会fpga肯定要学会STM32单片机、数字硬件设计等。。。

使用特权

评论回复
53
greenapl1985| | 2015-9-13 00:22 | 只看该作者
feihufuture 发表于 2015-9-13 00:06
说我几个观点吧,有错误请批评。。
1 FPGA岗位本来就少,北上广深都不是很多,我老婆搞外贸的,每天招聘 ...

很感谢您的回答,我应该还是想继续搞技术这一块,即使不搞研发,搞搞验证神马的也不错。最怕是像现在的状态,整天无所事事,天天和流程打交道。我还是好好修改简历吧,谢谢您的建议。

使用特权

评论回复
54
feihufuture|  楼主 | 2015-9-13 08:22 | 只看该作者
本帖最后由 feihufuture 于 2015-9-13 08:29 编辑

周六用了半天,终于帮别人把一个工业机器人的FPGA问题解决了,下午还去见了一个技术朋友,有时间还是多出来交流交流,见见面,在这个社会,能力是一方面,关系人脉也是很重要的一面。。。。。不啰嗦了,接着前面DDR3控制器的用户层封装,这次将代码上传完毕,大家要使用的话,将这两次的代码整合在一起,即可使用。顺便说一下,最近有人问我,“飞虎哥,你能不能将工程直接上传?”,这里我告诉你一声,我的网速超级慢,上传速度只有10KB/s左右,上传完要等到何年何月啊,等下次换住的地方就好了。


读写FIFO使能模块
assign u_wr_rdy = mcb_wr_en;// write fifo is ready
assign u_rd_rdy = mcb_rd_en;// read fifo is ready
//write fifo enable and read fifo enable
assign mcb_wr_en = (~mcb_wr_full)&&u_wr_en&&rst_n;
assign mcb_rd_en = (~mcb_rd_empty)&&u_rd_en&&rst_n;

以上代码mcb_wr_en代码写MCB FIFO使能,当mcb_wr_en为1时候数据写入MCB FIFO同时,u_wr_rdy为1通知写模块可以写数据。
以上代码mcb_rd_en代码读MCB FIFO使能,当mcb_rd_en为1时候数据从MCB FIFO读出,u_rd_rdy为1通知读模块可以读数据。
4)、u_mcb_write模块代码分析
module u_mcb_write(
input clk,
input rst_n,
input u_wr_cmd_done,//user write cmd done
input u_wr_rdy,// user write ready,data can be written in in to mcb
output reg u_wr_cmd_en,//user write cmb cmd enable
output reg u_wr_en,//user write enable
output reg [127:0]u_wr_data,//user write data
output reg [29:0]u_wr_addr,//user write address
output reg [6 :0]u_wr_len // user data len
);
(*KEEP = "TRUE" *) wire [1:0] u_wr_s_r;
(*KEEP = "TRUE" *)wire [2:0] u_wr_en_dly1;
parameter WR_IDLE = 2'd0;
parameter WR_BEGIN = 2'd1;
parameter WR_WAIT = 2'd2;
assign u_wr_s_r = u_wr_s;
reg [6 :0]u_wr_cnt; // user write counter
reg [1 :0]u_wr_s; // user write state
//when mcb write fifo more than 2 data enable write data mcb
//写命令请求
always @(posedge clk)
if(~rst_n)
begin
u_wr_cmd_en <= 1'b0;
end
else begin
if(u_wr_cmd_done) u_wr_cmd_en <= 1'b0; // clear mcb user write enable signal
else if(u_wr_cnt==40) u_wr_cmd_en <= 1'b1; // enable user mcb user cmd signal
end
//写测试数据产生
always @(posedge clk)
if(~rst_n)
begin
u_wr_data<=128'hAA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA;
end
else begin
if(u_wr_rdy) // mcb fifo is valid
u_wr_data <= ~u_wr_data; // count up data write to mcb fifo
else if(~u_wr_en)
u_wr_data<=128'hAA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA;
end
//写数据计数器
always @(posedge clk)
if(~rst_n)
begin
u_wr_cnt<=0;
end
else begin
if(u_wr_rdy) // mcb fifo is valid
u_wr_cnt <= u_wr_cnt + 1'b1; // count up data write to mcb fifo
else if(u_wr_s==WR_IDLE)
u_wr_cnt <= 7'd0;
end
reg [28:0] u_wr_addr_set;
//写数据状态机
always @(posedge clk)
if(~rst_n)
begin
u_wr_len <= 7'd64; // user write len
u_wr_addr <= 29'd0; // user write address
u_wr_en <= 1'b0; // user write enable
u_wr_s <= WR_IDLE;
end
else begin
case(u_wr_s)
WR_IDLE:
begin
u_wr_en <= 1'b0;
if(u_wr_cmd_en==1'b0) // start new write
u_wr_s <= WR_BEGIN;
end
WR_BEGIN:
begin
u_wr_len <= 7'd64;
u_wr_addr <= u_wr_addr_set;
u_wr_en <= 1'b1;
u_wr_s <= WR_WAIT;
end
WR_WAIT:
if(u_wr_cnt==(u_wr_len-1))
begin
u_wr_s <= WR_IDLE;
u_wr_en <= 1'b0;
end
endcase
end
//888888888888888888888888888888888888888888888888888888888888888888888888
//地址空间起始地址产生
parameter ADDR_INC = 12'h400;
parameter END_ADDR = 29'h10000000 - ADDR_INC;
always @(posedge clk)
if(~rst_n)
begin
u_wr_addr_set<=29'b0;
end
else begin
if(u_wr_cmd_done&&(u_wr_addr_set<END_ADDR))
u_wr_addr_set<=u_wr_addr_set+ADDR_INC;
else if(u_wr_addr_set==END_ADDR)
u_wr_addr_set<=0;
end
endmodule

从上面的程序还可以看出,如果同时有读写命令,优先处理写命令。
以上关键代码在于写命令请求的时机,当写MCB FIFO的数据非满就可以控制往MCB FIFO继续写数据。同时当FIFO有数据就可以发送控制命令往DDR把FIFO的数据搬运到DDR中。
另外地址空间的产生,MCB采用的地址空间是连续的,由于一次写入128bitX64的数据,因此一次写入的数据是1024 因此ADDR_INC = 12'h400;每次完成一次写命令地址空间增加一次。本开发板配备的内存大小为128MBX16 全地址空间为268435456B 那么最后一次的增量结束地址为
END_ADDR = 29'h10000000 - ADDR_INC
4)、u_mcb_read模块代码分析
module u_mcb_read
(
input clk,
input rst_n,
input u_rd_cmd_done, //user read cmd done
input u_rd_rdy, // user read ready,data can be written in in to mcb
output reg u_rd_cmd_en, //user read cmb cmd enable
output reg u_rd_en, //user read enable
input [127:0]u_rd_data, //user read data
output reg [29:0]u_rd_addr,//user read address
output reg [6 :0]u_rd_len // user data len
);
reg [1 :0]u_rd_s; // read state
reg [6 :0]u_rd_cnt;// user read data counter
reg read_error;
(*KEEP = "TRUE" *) wire [1:0] u_rd_s_r;// debug signal
assign u_rd_s_r = u_rd_s;
(*KEEP = "TRUE" *) wire read_error_dg;
assign read_error_dg = read_error;
parameter RD_IDLE = 2'd0;
parameter RD_BEGIN = 2'd1;
parameter RD_WAIT = 2'd2;
parameter RD_RST = 2'd3;
reg u_rd_en_dly;
always @(posedge clk)
if(~rst_n)
begin
u_rd_en_dly<=1'b0;
end
else begin
u_rd_en_dly <= u_rd_en;
end
//读命令请求
always @(posedge clk)
if(~rst_n)
begin
u_rd_cmd_en <= 1'b0;
end
else begin
if(u_rd_cmd_done) u_rd_cmd_en <= 1'b0; // clear user read mcb cmd signal
else if(u_rd_en&&(~u_rd_en_dly)) u_rd_cmd_en <= 1'b1; // enable user read mbb cmd signal
end
reg s;
//读数据比较
always @(posedge clk)
if(~rst_n)
begin
read_error<=1'b0;
s<=0;
end
else begin
if((u_rd_s==RD_WAIT)&&u_rd_rdy)// valid data
case(s)
0:
if(u_rd_data==128'hAA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA_AA) s <= 1'b1;
else read_error<=1'b1;
1:
if(u_rd_data==128'h55_55_55_55_55_55_55_55_55_55_55_55_55_55_55_55) s <= 1'b0;
else read_error<=1'b1;
endcase
else if(~u_rd_en)begin
read_error<=1'b0;
s<=0;
end
end
//读数据计数器
always @(posedge clk)
if(~rst_n)
begin
u_rd_cnt<=0;
end
else begin
if(u_rd_rdy)// valid data
u_rd_cnt<=u_rd_cnt+1'b1; // count up
else if(u_rd_s==RD_IDLE)u_rd_cnt<=7'd0; // clear counter
end
reg [28:0]u_rd_addr_set;
//读状态机
always @(posedge clk)
if(~rst_n)
begin
u_rd_len <= 7'd64; // user read length
u_rd_addr <= 29'd0; // user read address
u_rd_en <= 1'b0; // user read enable
u_rd_s <= RD_IDLE;
end
else begin
case(u_rd_s)
RD_IDLE:
begin
u_rd_en <= 1'b0;
if(u_rd_cmd_en==1'b0)// when mcb read cmd is done
u_rd_s <= RD_BEGIN;
end
RD_BEGIN://read cmd
begin
u_rd_len <= 7'd64;
u_rd_addr <= u_rd_addr_set;
u_rd_en <= 1'b1;
u_rd_s <= RD_WAIT;
end
RD_WAIT://read cmd done
if(u_rd_cnt==(u_rd_len))begin
u_rd_s <= RD_IDLE;
u_rd_en <= 1'b0;
end
endcase
end
//888888888888888888888888888888888888888888888888888888888888888888888888
//地址空间起始地址产生
parameter ADDR_INC = 12'h400;
parameter END_ADDR = 29'h10000000 - ADDR_INC;
always @(posedge clk)
if(~rst_n)
begin
u_rd_addr_set<=29'b0;
end
else begin
if(u_rd_cmd_done&&(u_rd_addr_set<END_ADDR))
u_rd_addr_set<=u_rd_addr_set+ADDR_INC;
else if(u_rd_addr_set==END_ADDR)
u_rd_addr_set<=0;
end
endmodule

以上关键代码在于读命令请求的时机,当写MCB FIFO的数据非空就可以控制从MCB FIFO继续读数据。同时当读FIFO非满数据就可以发送控制命令从DDR把数据搬运到读FIFO。
另外地址空间的产生,MCB采用的地址空间是连续的,由于一次读入128bitX64的数据,因此一次读入的数据是1024 因此ADDR_INC = 12'h400;每次完成一次读命令地址空间增加一次。本开发板配备的内存大小为128MBX16 全地址空间为268435456B 那么最后一次的增量结束地址为
END_ADDR = 29'h10000000 - ADDR_INC

MCB DDR3测试结果






使用特权

评论回复
55
人民币的幻想| | 2015-9-13 09:00 | 只看该作者
feihufuture 发表于 2015-9-13 00:07
都好,我更倾向于FPGA,会fpga肯定要学会STM32单片机、数字硬件设计等。。。 ...

好的,谢谢

使用特权

评论回复
56
chinahuangyong| | 2015-9-13 11:20 | 只看该作者
楼主,能不能来一块

使用特权

评论回复
57
feihufuture|  楼主 | 2015-9-13 12:04 | 只看该作者
chinahuangyong 发表于 2015-9-13 11:20
楼主,能不能来一块

需要请联系QQ 444363408

使用特权

评论回复
58
ecoren| | 2015-9-13 19:17 | 只看该作者
livelei 发表于 2015-9-11 16:33
88E1111是PHY芯片,不过功能强大,在前几年的FPGA开发板中用的比较多,MII接口可以配置为GMII,RGMII,SGMI ...

受教了

使用特权

评论回复
59
Ted_Chen| | 2015-9-13 19:21 | 只看该作者
求设计文件呀楼主!!!我们现在用的开发平台是4核A9三星处理器加FPGA,之前想过用Z7的,只是价格有点望而却步...

使用特权

评论回复
60
feihufuture|  楼主 | 2015-9-13 19:47 | 只看该作者
Ted_Chen 发表于 2015-9-13 19:21
求设计文件呀楼主!!!我们现在用的开发平台是4核A9三星处理器加FPGA,之前想过用Z7的,只是价格有点望而 ...

你是想要什么设计文件,原理图?
你用的4核A9三星处理器具体是什么型号,价格是多少?还有其他有什么优势?下次我选方案也可以参考参考。

使用特权

评论回复
发新帖 本帖赏金 8.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则