- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
基于FPGA的IEEE 802.11协议帧生成器的设计
1& nbsp; 引言
[1]IEEE 802.11标准定义了能够统筹所有基于以太网的无线通信的协议。它是迄今为止最流行的无线局域网的标准。这个标准还细分了一些子标准,如802.11a, 802.11b和802.11g。这其中有些协议可使用直接序列扩频技术(DSSS)来发送无线信号,如802.11b。 无线局域网带宽窄,终端设备处理能力弱,其信号的组帧环节需要尽可能采用处理时延小,占用存储资源少的方法。本文正是以此为指导思想进行802.11协议帧的生成的。
2模块的设计与实现
2.1 全局控制模块
该模块的设计方法是采用一个9bit的计数器,以协议帧的二进制位长度为周期循环计数,在不同的时间片发出不同的使能信号,以实现对多个输出模块的控制,实现实时的串行输出。并设计有选通信号sel[1..0],以实现对输出端口的多路选择器的控制。其仿真时序波形图如图1所示。其关键代码如下:
①always@(posedge clk4)& nbsp; //初始化 & nbsp; begin if(!reset) & nbsp;begin & nbsp;& nbsp; count& lt;=0; & nbsp;end | else & nbsp; begin & nbsp;& nbsp;& nbsp; if(count==9'd472) count& lt;=0; & nbsp;& nbsp;& nbsp; else count& lt;=count+1; & nbsp;& nbsp; end end |
②always//对帧序号生成模块的控制 begin & nbsp;& nbsp;& nbsp; if(!reset)& nbsp; seqenable& lt;=0; & nbsp;& nbsp;& nbsp; if(count==9'd176)& nbsp; seqenable& lt;=1; & nbsp;& nbsp;& nbsp; if(count==9'd192)& nbsp; seqenable& lt;=0; end | ③always& nbsp; //对两个ROM单元的使能和禁止控制 & nbsp; begin & nbsp;& nbsp;& nbsp; if(!reset) & nbsp;& nbsp;& nbsp; & nbsp;begin & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; dataaddrenable& lt;=0; & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; dataromenable& lt;=0; & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; crccalenable& lt;=0; & nbsp;& nbsp;& nbsp; & nbsp;end & nbsp;& nbsp;& nbsp; if(count==9'd240)//送data & nbsp;& nbsp;& nbsp; & nbsp; begin & nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp; dataaddrenable& lt;=1; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; dataromenable& lt;=1; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; crccalenable& lt;=1; & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; end & nbsp;& nbsp;& nbsp; if(count==9'd440) & nbsp;& nbsp;& nbsp; & nbsp;begin & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; dataaddrenable& lt;=0; & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; dataromenable& lt;=0; & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; crccalenable& lt;=0; & nbsp;& nbsp;& nbsp; & nbsp; end & nbsp;& nbsp;& nbsp; end |
④always //在每帧结束时送出帧序号加1的使能信号 & nbsp; begin if(!reset)contin& lt;=0; & nbsp;if(count==9'd472) contin& lt;=1; & nbsp;& nbsp;& nbsp;if(count==1)contin& lt;=0; & nbsp; end | |
⑤always& nbsp; //对CRC校验码生成模块的控制 & nbsp; begin & nbsp;& nbsp;& nbsp; if(!reset) & nbsp;& nbsp;& nbsp; crcdoutenable& lt;=0; & nbsp;& nbsp;& nbsp; if(count==9'd440)& nbsp; //数据送完了。 & nbsp;& nbsp;& nbsp; & nbsp;crcdoutenable& lt;=1; & nbsp;& nbsp;& nbsp; if(count==9'd472) & nbsp;& nbsp;& nbsp; & nbsp;crcdoutenable& lt;=0; end |
&
nbsp;
⑥always//选通信号控制 & nbsp;& nbsp;& nbsp; begin & nbsp;& nbsp;& nbsp; & nbsp;if(!reset) sel=2'b00; & nbsp;& nbsp;& nbsp; if(count==9'd470) sel=2'b01; & nbsp;& nbsp;& nbsp; if(count==9'd173) sel=2'b00; | 续⑥if(count==9'd190) sel=2'b01; & nbsp;& nbsp;& nbsp; if(count==9'd238) sel=2'b10; & nbsp;& nbsp;& nbsp; if(count==9'd438) sel=2'b11; & nbsp;& nbsp;& nbsp; end endmodule |
图1全局控制模块仿真时序波形图 |
&
nbsp;
2.2 CRC校验码生成器模块
此模块需要的常用CRC生成多项式如下:
CRC-8:x8+x2+x+1
CRC-16:x16+x15+x2+1
CRC-32:x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
其关键代码如下。该模块CRC校验时序仿真波形如图2所示。& nbsp;
图2 CRC校验时序仿真波形图 |
always@(negedge clk)//posedge把数据送出来, & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp;& nbsp;//negedge对数据进行处理 & nbsp; begin & nbsp; & nbsp;if(calculateen)& nbsp; //flag为高时作crc的产生 & nbsp;& nbsp;& nbsp; begin & nbsp;& nbsp;& nbsp; & nbsp; dout& lt;=1'bz; & nbsp;& nbsp;& nbsp; & nbsp; D[0]& lt;=din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[1]& lt;=D[0]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[2]& lt;=D[1]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[3]& lt;=D[2]; & nbsp;& nbsp;& nbsp; & nbsp; D[4]& lt;=D[3]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[5]& lt;=D[4]^din^D[31]; & nbsp;& nbsp;& nbsp; & nbsp; D[6]& lt;=D[5]; & nbsp;& nbsp;& nbsp; & nbsp; D[7]& lt;=D[6]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[8]& lt;=D[7]^din^D[31]; & nbsp;& nbsp;& nbsp; & nbsp; D[9]& lt;=D[8]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[10]& lt;=D[9]^din^D[31]; & nbsp;& nbsp;& nbsp; & nbsp; D[11]& lt;=D[10]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[12]& lt;=D[11]^din^D[31]; & nbsp;& nbsp;& nbsp; & nbsp; for(i=12;i& lt;=14;i=i+1) & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[i+1]& lt;=D[i]; | & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D[16]& lt;=D[15]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; for(i=16;i& lt;=20;i=i+1) & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; D[i+1]& lt;=D[i]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; D[22]& lt;=D[21]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; D[23]& lt;=D[22]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; D[24]& lt;=D[23]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; D[25]& lt;=D[24]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; D[26]& lt;=D[25]^din^D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; for(i=26;i& lt;=30;i=i+1) & nbsp;& nbsp; D[i+1]& lt;=D[i]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; end & nbsp;& nbsp;& nbsp; & nbsp; else dout& lt;=1'bz; & nbsp;& nbsp;& nbsp; & nbsp; if(outputen) & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; begin & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; dout& lt;=D[31]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; D& lt;=D& lt;& lt;1; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; end & nbsp;& nbsp;& nbsp; & nbsp; else & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; dout& lt;=1'bz; & nbsp;& nbsp;& nbsp; end endmodule// |
&
nbsp;
2.3 帧序号生成模块
& nbsp;& nbsp;& nbsp; 该模块的功能是产生16bit的帧序号,由overall_ctrl在每帧结束时发出的contin信号实现计数的加一。由enable信号触发,将帧序号串行输出。其关键代码为:
①always@(negedge clk4) //产生帧序号 begin & nbsp; if(!reset) & nbsp;& nbsp;& nbsp; seqctrl[15:0]& lt;=0; & nbsp;& nbsp;& nbsp; & nbsp; if(contin) & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; begin & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; if(seqctrl[15:0]==16'hffff) & nbsp;& nbsp; seqctrl[15:0]& lt;=0; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; else seqctrl& lt;=seqctrl+1; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; end & nbsp;end | 续②& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; 4'd3:q& lt;=seqctrl[3]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd4:q& lt;=seqctrl[4]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd5:q& lt;=seqctrl[5]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd6:q& lt;=seqctrl[6]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd7:q& lt;=seqctrl[7]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd8:q& lt;=seqctrl[8]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd9:q& lt;=seqctrl[9]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd10:q& lt;=seqctrl[10]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd11:q& lt;=seqctrl[11]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd12:q& lt;=seqctrl[12]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd13:q& lt;=seqctrl[13]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd14:q& lt;=seqctrl[14]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd15:q& lt;=seqctrl[15]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; endcase& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; end & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;& nbsp;else & nbsp;& nbsp;& nbsp;& nbsp; begin & nbsp;& nbsp;& nbsp;& nbsp; & nbsp; q& lt;=1'bz; & nbsp;& nbsp;& nbsp;& nbsp; & nbsp; count& lt;=0; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;& nbsp; end & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;end & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; else q& lt;=1'bz;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp; & nbsp;end& nbsp; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp; & nbsp; endmodule |
②always@(negedge clk4) //16 bit帧序号串行输出 & nbsp; begin & nbsp;& nbsp;& nbsp; & nbsp;if(enable)//enable信号只能严格划分为十六个周期; & nbsp;& nbsp;& nbsp; & nbsp;& nbsp; begin & nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp; & nbsp; count& lt;=count+1; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp; if(count!=16) & nbsp;& nbsp; begin & nbsp;& nbsp;& nbsp;& nbsp; & nbsp; case(count) & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd0:q& lt;=seqctrl[0];& nbsp;& nbsp;& nbsp; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd1:q& lt;=seqctrl[1]; & nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; & nbsp;4'd2:q& lt;=seqctrl[2]; |
& nbsp; 图3帧序号生成模块时序仿真图 |
该模块的帧序号生成模块时序仿真图如图3所示。
2.4 IEEE 802.11协议帧生成器 系统总体结构模块
& nbsp;& nbsp;& nbsp; IEEE 802.11协议帧生成器 系统总体结构模块框图如图4所示。
图4. IEEE 802.11协议帧生成器系统总体结构框图 |
3. 结论
& nbsp;& nbsp;& nbsp; 本文以展示详尽的Verilog HDL代码、各模块时序仿真图和系统总体结构框图的方式给出了一种基于FPGA的IEEE 802.11协议帧生成器的设计实现方法。该协议帧可直接由DSSS发射机发送。本设计几乎不产生组帧延迟,实时性能好,且不占用缓冲资源,具有新颖性和实用性。
本文作者创新点:
1) 本文给出了一种以FPGA为硬件平台的IEEE 802.11协议帧生成器的设计实现方法。
2)采用该方法几乎不产生组帧延迟,实时性能好,且不占用缓冲资源,具有新颖性和实用性。
& nbsp;
& nbsp;参考文献:
1. IEEE 802.11 Wireless Local Area Networks,IEEE Communications Magazine & #8226; September 1997。
2. Advanced digital design with the verilog HDL. Michael D.ciletti.PEARSON.2004
3. Compurter networks(fourth edition)& nbsp; Andrew S.Tanebaum.Prentice Hall,PTR.
4.杨奎武,魏博,扩频通信中匹配滤波器的FPGA设计[J],微计算机信息,2005,3:117-118
本课题得到国家自然科学基金项目(60574088)的资助。