1.如果想用fpga完成一个比较复杂的网络应用,还是使sopc吧。。哪怕自己写一个所用phy片的驱动也好,当然nios这种一般都提供了phy片驱动了,官网能下到。
大概方法:发包头,发数据,发crc,完成。
假设udp包长为760,整个ip包长780,txdata为【3..0】
先说状态机,写的时候注意分开写
我是习惯2段式的,状态转换和根据状态进行的寄存器赋值分开写,加上current<=next就是三段式了,但从来没那么干过
状态机时钟为tx clk
1.idle
如果收到需要发送数据的需求,转到preamble。
否则idle
idle状太,txen<=0;
2.preamble
用于发送ip包头udp包头+
数够92个clk转到data。92个clk可以商量,看包头来定。
preamble状态下,txen=1,txdata根据clk计数值,发送udp包头
3.data clk计数.由于udp数据包一共760bit,减去udp包头8byte,共752byte,每次发送4bit,共需752*2个clk,所以752×2个clk之后,data状态结束,跳转到crc
data状态下txdata<=发送想要发送的数据,建议做一个ram/fifo,把想发送的存进去,通过4位的data输出
4.crc
数8个clk跳转到idle
输出4byte crc数据。
今天先把idle转的状态展开说说吧
有的时候会需要把不同的数据发给不同的ip/端口,那么状态跳转可以这样调整
原来是,有数据要发就preamble,然后data,crc
如果现在想把事件1发给1.1.1.1:11,事件2发给2.2.2.2:22
可以改成,事件1触发,跳转到事件一preamble,发送事件1的包头,该包头ip为1.1.1.1,端口11,之后跳转到事件1data,发送事件1数据。
事件2以此类推。
另一种做法是idle跳转到preamble的时候,根据事件来源设一个寄存器,事件触发式寄存器置位,再一次进入idle的时候寄存器复位
idle且事件一_trig的时候,将事件1_tran=1,否则=0
然后preamble,data状态下,根据事件1_tran决定发送什么东西
但这样的话等于是把状态机的转太转换和根据状态发生的寄存器赋值混到一起写了,容易混乱。
今天先回家了。。大家节日愉快
文章评论(0条评论)
登录后参与讨论