700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【GAOPS038】数据链路层PPP和HDLC协议

【GAOPS038】数据链路层PPP和HDLC协议

时间:2019-02-23 02:25:01

相关推荐

【GAOPS038】数据链路层PPP和HDLC协议

目录

概述

底层格式转换规则

上层协议包的交互

两者对比

概述

PPP帧格式与HDLC相似,不同的是PPP是面向字符也就是字节(7E),HDLC是面向位(连续的5个1)。

点对点协议(Point to Point Protocol,PPP)是数据链路层协议。替代了原来非标准的第二层协议,即 SLIP。PPP面向字节。

底层格式转换规则

PPP的帧格式

PPP采用7EH作为一帧的开始和结束标志(F);

其中地址域(A)和控制域(C)取固定值(A=FFH,C=03H) ;

协议域(两个字节)取0021H表示IP分组,取8021H表示网络控制数据,取C021H表示链路控制数据;

帧校验域(FCS)也为两个字节,它用于对信息域的校验。

若信息域中出现7EH,则转换为(7DH,5EH)两个字符。

如果0x7E出现在帧内部的话,需要出现问题,所以有两种解决方案:

在异步链路上使用字符填充(PPP),即把0x7E用0x7D5E替换

在同步链路上使用位填充(HDLC),即在连续的5个1之后填充一个0

当信息域出现7DH时,则转换为(7DH,5DH)。

若信息字段中出现ASCII码的控制字符(即数值小于0X20的字符),则该字符前面需要加入一个0x7D字节,同时将该字符的编码加以改变(+20),+20H也就是将bit5取反。例如,出现0x03,就要把它转为2字节序列(0x7D,0x23)

上层协议包的交互

简要描述,做底层的,咱也不清楚。

链路控制协议(LCP):一种扩展链路控制协议,用于建立、配置、测试和管理数据链路连接。

网络控制协议(NCP):协商该链路上所传输的数据包格式与类型,建立、配置不同的网络层协议;

为了建立点对点链路通信,PPP 链路的每一端,必须首先发送 LCP 包以便设定和测试数据链路。在链路建立,LCP 所需的可选功能被选定之后,PPP 必须发送 NCP 包以便选择和设定一个或更多的网络层协议。一旦每个被选择的网络层协议都被设定好了,来自每个网络层协议的数据报就能在链路上发送了。

两者对比

PPP协议 && HDLC协议

相同点:

(1) PPP、HDLC协议都支持全双工链路。

(2) 都可以实现透明传输。

(3) 都可以实现差错检测,但都不纠正差错。

不同点:

(1) PPP协议面向字节,HDLC协议面向比特。

(2) HDLC协议帧格式没有协议字段。

(3) PPP协议无序号和确认机制,HDLC协议有编号和确认机制。

(4) PPP协议不可靠,HDLC协议可靠。

HDLC转换例子

11110011111100111111001111110111110111110000000000000111000010010000000101011010000000001110000100000000010000010100000001110111010000001100000000000001000010010010100101100101010101101000100011111100111111001111110011111100//lsb先发送1111001111110011111100111111011111111 FF11000000 0300000011 c010000100 2110000000 0110101101 B500000000 0001110000 0E10000000 0100100000 0410100000 0500111011 DC10100000 0501100000 0600000000 0010000100 2110010100 2910110010 4D10101011 D501000100 211110 7E01111110 7E01111110 01111110

遇到一个题目:编写HDLC数据链路层的插入0模块,常规思路是用状态机,实现11111序列检测。我在想能不能将串行的实现改为并行实现。插0规则:遇到连续5个1就插入1个0。不是在连续6个1种插入1个0

1次输入8bit待转换数据,数据上次最后5bit(提供上次连续1的个数)。

并行方案1:1拍出数据。8bit数据插入最多就能插入2个0,分3种情况:插入2个0情况,插入1个0情况,插入0个0情况。这样可以实现,但是综合出来的电路路径很长,意味着时序不好。

并行方案2:2拍出结果。实现1个模块,假定输入8bit中最多只插入1个0,实现1拍去掉1个0,两拍连起来就能将2个0去掉。可以考虑电路复用,能节省部分资源。

并行方案3:2拍出结果。将8bit数据拆分为2个4bit数据,先处理低4bit,再处理高4bit ,数据位宽小,组合逻辑路径短,加上电路课复用,资源时序最好,是我目前见到的最优解。但是具体verilog代码还没实现。

`timescale 1ns / 1nsmodule insert (inputclk ,inputrst ,inputidata_vld,//本次数据有效input [7:0] idata ,//本次输入数据input [4:0] bef_data,//上个数据最后5bit,用来检查连续1的个数output [9:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定 output [4:0] last_data,//本次的高5位,留给下次用 output reg odata_vld,//本次输出数据有效output [1:0] vld_num //高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 );reg[16:0]aft_data;// {vld_num[1:0],pad[1:0],idata[7:0],bef_data[4:0]} vld[1:0]:2:pad中有两个有效;wire [12:0]com_data;assign com_data= {idata[7:0],bef_data[4:0]} ;always@(posedge clk ) odata_vld <=#1 idata_vld ;assign {vld_num[1:0], odata[9:0],last_data[4:0]} = aft_data[16:0];always@(posedge clk or posedge rst )beginif(rst) aft_data<=#1 'b0;else if(~idata_vld) aft_data<=#1 aft_data;else if(com_data[10:0] == 11'b111_1111_1111) //1aft_data <=#1 {2'd2,idata[7:5],1'b0,idata[4:0],1'b0,{idata[7:5],1'b0,idata[4]} } ;else if(com_data[12:0] == 13'b1_1111_1011_1111)//2aft_data <=#1 {2'd2,idata[7:6],1'b0,idata[5:0],1'b0,{idata[7:6],1'b0,idata[5:4]} } ;else if(com_data[11:0] == 12'b1111_1111_1110)//3aft_data <=#1 {2'd2,idata[7:6],1'b0,idata[5:1],1'b0,idata[0] ,{idata[7:6],1'b0,idata[5:4]} } ;else if(com_data[12:1] == 12'b1_1111_1111_110)//4aft_data <=#1 {2'd2,idata[7 ],1'b0,idata[6:2],1'b0,idata[1:0], {idata[7],1'b0,idata[6:4]} } ;else if(com_data[5:0] == 16'b11_1111)//只插入1个0,不放casex,因为会有覆盖aft_data <=#1 {2'd2,idata[7 ],1'b0,idata[6:2],1'b0,idata[1:0], {idata[7],1'b0,idata[6:4]} } ;elsecasex(com_data[12:0])// 13'bx_x111_1111_1111: aft_data <=#1 {idata[7:5],1'b0,idata[4:0],1'b0,{idata[7:5],1'b0,idata[4]} } ;// 13'b1_1111_1011_1111: aft_data <=#1 {idata[7:6],1'b0,idata[5:0],1'b0,{idata[7:6],1'b0,idata[5:4]} } ;// 13'bx_1111_1111_1110: aft_data <=#1 {idata[7:6],1'b0,idata[5:1],1'b0,idata[0] ,{idata[7:6],1'b0,idata[5:4]} } ;// 13'b1_1111_1111_1100: aft_data <=#1 {idata[7 ],1'b0,idata[6:2],1'b0,idata[1:0],{idata[7],1'b0,idata[6:4]}} ;13'bx_xxxx_xx11_1111: aft_data <=#1 {2'd1,1'b0,idata[7:0],1'b0,idata[7:3]} ;13'bx_xxxx_x111_1110: aft_data <=#1 {2'd1,1'b0,idata[7:1],1'b0,idata[0],idata[7:3] } ;13'bx_xxxx_1111_110x: aft_data <=#1 {2'd1,1'b0,idata[7:2],1'b0,idata[1:0],idata[7:3]} ;13'bx_xxx1_1111_10xx: aft_data <=#1 {2'd1,1'b0,idata[7:3],1'b0,idata[2:0],idata[7:3]} ;13'bx_xx11_1111_0xxx: aft_data <=#1 {2'd1,1'b0,idata[7:4],1'b0,idata[3:0],{idata[7:4],1'b0}} ;13'bx_x111_1110_xxxx: aft_data <=#1 {2'd1,1'b0,idata[7:5],1'b0,idata[4:0],{idata[7:5],1'b0,idata[4]}} ;13'bx_1111_110x_xxxx: aft_data <=#1 {2'd1,1'b0,idata[7:6],1'b0,idata[5:0],{idata[7:6],1'b0,idata[5:4]}} ;13'b1_1111_10xx_xxxx: aft_data <=#1 {2'd1,1'b0,idata[7] ,1'b0,idata[6:0],{idata[ 7],1'b0,idata[6:4]}} ;default: aft_data <=#1 {2'd0,2'd0,idata[7:0],idata[7:3]} ;endcaseendendmodule// insert u_insert (// .clk( ),//inputclk ,// .rst( ),//inputrst ,// .idata_vld( ),//inputidata_vld,//本次数据有效// .idata ( ),//input [7:0] idata ,//本次输入数据// .bef_data ( ),//input [4:0] bef_data,//上个数据最后5bit,用来检查连续1的个数// .odata ( ),//output [9:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定 // .last_data( ),//output [4:0] last_data,//本次的高5位,留给下次用 // .odata_vld( ),//output reg odata_vld,//本次输出数据有效// .vld_num ( ) //output [1:0] vld_num ,//高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 // );

`timescale 1ns / 1nsmodule insert (inputclk ,inputrst ,inputidata_vld,//本次数据有效input [7:0] idata ,//本次输入数据input [4:0] bef_data,//上个数据最后5bit,用来检查连续1的个数output [9:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定 output reg [4:0] last_data,//本次的高5位,留给下次用 output odata_vld,//本次输出数据有效output [1:0] vld_num //高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 );reg idata_vld_1d=0;reg idata_vld_2d=0;wire [16:0]com_data;wire [16:0]com_data1;reg[16:0]data_sel;reg[16:0]data_match[5:13] ;//能去参加匹配的只有0-13bitreg[13:5]match ;reg[3:0] match_sel;genvar i ;assign com_data= {2'b0,2'b0,idata[7:0],bef_data[4:0]} ;assign com_data1 = idata_vld ? com_data : data_sel ; // com_data1 D1:D0,C1:C0,B7:B0,A4:A0} [16:15] [14:13] [12:5][4:0] {vld_num[1:0],pad[1:0],idata[7:0],bef_data[4:0]}always@(posedge clk ) {idata_vld_2d , idata_vld_1d }<= #1 {idata_vld_1d , idata_vld } ;generate for(i=5;i<14;i=i+1) beginalways@(posedge clk or posedge rst )beginif(rst) begindata_match[i] <=#1 'b0;match[i] <=#1 'b0;end else if(com_data1[i-:6]==6'b11_1111) beginif(idata_vld)begindata_match[i][16:15]<=#1 {2'b01};end else if(idata_vld_1d) begindata_match[i][16:15]<=#1 {2'b10};enddata_match[i][14:0]<=#1 {com_data1[13:i],1'b0,com_data1[i-1:0]};match[i]<=#1 'b1;end else begindata_match[i]<=#1 com_data1 ;match[i]<=#1 'b0; endend end endgeneratealways@(* )begincasex(match[13:5])//8:09'Bxxxxx_xxx1:match_sel = 'd0;9'Bxxxxx_xx10:match_sel = 'd1;9'Bxxxxx_x100:match_sel = 'd2;9'Bxxxxx_1000:match_sel = 'd3;9'Bxxxx1_0000:match_sel = 'd4;9'Bxxx10_0000:match_sel = 'd5;9'Bxx100_0000:match_sel = 'd6;9'Bx1000_0000:match_sel = 'd7;9'B10000_0000:match_sel = 'd8;default:match_sel = 'd0; endcaseend always@(* )begincase(match_sel[3:0]) 4'd0:data_sel = data_match[5+0];4'd1:data_sel = data_match[5+1];4'd2:data_sel = data_match[5+2];4'd3:data_sel = data_match[5+3];4'd4:data_sel = data_match[5+4];4'd5:data_sel = data_match[5+5];4'd6:data_sel = data_match[5+6];4'd7:data_sel = data_match[5+7];4'd8:data_sel = data_match[5+8];default:data_sel = data_match[0]; endcaseend assign {vld_num[1:0],odata[9:0] } =data_sel[16:5];always@(* )begincase(vld_num[1:0]) 2'd0:last_data[4:0] = odata[7-:5];2'd1:last_data[4:0] = odata[8-:5];2'd2:last_data[4:0] = odata[9-:5];default:last_data[4:0] = odata[7-:5];endcaseendassign odata_vld =idata_vld_2d;endmodule// insert u_insert (// .clk( ),//inputclk ,// .rst( ),//inputrst ,// .idata_vld( ),//inputidata_vld,//本次数据有效// .idata ( ),//input [7:0] idata ,//本次输入数据// .bef_data ( ),//input [4:0] bef_data,//上个数据最后5bit,用来检查连续1的个数// .odata ( ),//output [9:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定 // .last_data( ),//output [4:0] last_data,//本次的高5位,留给下次用 // .odata_vld( ),//output reg odata_vld,//本次输出数据有效// .vld_num ( ) //output [1:0] vld_num ,//高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 // );

`timescale 1ns / 1nsmodule insert4bit (inputclk ,inputrst ,input [3:0] idata ,//本次输入数据bit[4]可能是无效数据,通过vld_bit4来区分input [4:0] iremain ,//上个数据最后5bit,用来检查连续1的个数inputidata_vld,//本次数据有效// inputivld_num,//0:无 ,1:1个有效 output reg [4:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定 output reg [4:0] oremain ,//本次的高5位,留给下次用 output odata_vld,//本次输出数据有效output regovld_num //高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 );reg idata_vld_1d=0;wire [8:0] com_data;wire [9:5] match ;genvar i ;assign com_data= {idata[3:0],iremain[4:0]} ;always@(posedge clk ) idata_vld_1d <= #1 idata_vld ;generate for(i=4;i<9;i=i+1) begin:aaassign match[i+1] = &com_data[i-:5];end endgeneratealways@(posedge clk or posedge rst )beginif(rst) beginodata[4:0] <=#1 'b0;ovld_num <=#1 'b0;oremain <=#1 5'b0;end else if(match[5]) begin//在bit5插入0odata[4:0] <=#1 {idata[3:0],1'b0}; ovld_num <=#1 'b1;oremain <=#1 {idata[3:0],1'b0};end else if(match[6]) begin//在bit6插入0odata[4:0] <=#1 {idata[3:1],1'b0,idata[0]}; ovld_num <=#1 'b1;oremain <=#1 {idata[3:1],1'b0,idata[0]}; end else if(match[7]) begin//在bit7插入0odata[4:0] <=#1 {idata[3:2],1'b0,idata[1:0]}; ovld_num <=#1 'b1;oremain <=#1 {idata[3:2],1'b0,idata[1:0]};end else if(match[8]) begin//在bit8插入0odata[4:0] <=#1 {idata[3],1'b0,idata[2:0]}; ovld_num <=#1 'b1;oremain <=#1 {idata[3],1'b0,idata[2:0]};end else if(match[9]) begin//在bit9插入0odata[4:0] <=#1 {1'b0,idata[3:0]}; ovld_num <=#1 'b1;oremain <=#1 {1'b0,idata[3:0]};end else beginodata[4:0] <=#1 {1'b0,idata[3:0]}; ovld_num <=#1 'b0;oremain <=#1 {idata[3:0],iremain[4]}; endendassign odata_vld =idata_vld_1d;endmodule// insert_step1 u_insert_step1 (// .clk( ),//inputclk ,// .rst( ),//inputrst ,// .idata_vld( ),//inputidata_vld,//本次数据有效// .idata ( ),//input [3:0] idata ,//本次输入数据// .bef_data ( ),//input [4:0] bef_data,//上个数据最后5bit,用来检查连续1的个数// .odata ( ),//output [5:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定// .last_data( ),//output [4:0] last_data,//本次的高5位,留给下次用 // .odata_vld( ),//output odata_vld,//本次输出数据有效// .vld_num ( ) //output [1:0] vld_num //高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 // );`timescale 1ns / 1nsmodule insert (inputclk ,inputrst ,inputidata_vld,//本次数据有效input [7:0] idata ,//本次输入数据input [4:0] iremain ,//上个数据最后5bit,用来检查连续1的个数output reg [9:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定 output reg [4:0] oremain ,//本次的高5位,留给下次用 output odata_vld,//本次输出数据有效output reg [1:0] ovld_num //高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 );reg idata_vld_1d=0;reg idata_vld_2d=0;reg idata_vld_3d=0;reg[4:0] u0_odata_1d ;reg[4:0] u0_oremain_1d ;reg u0_odata_vld_1d ;reg u0_ovld_num_1d;wire [4:0] u0_odata;wire [4:0] u0_oremain ;wireu0_odata_vld ;wireu0_ovld_num ;wire [4:0] u1_odata;wire [4:0] u1_oremain ;wireu1_odata_vld ;wireu1_ovld_num ;reg[7:0] idata_1d;always@(posedge clk ) {idata_vld_3d,idata_vld_2d , idata_vld_1d }<= #1 {idata_vld_2d,idata_vld_1d , idata_vld } ;always@(posedge clk ) idata_1d <= #1 idata ;always@(posedge clk ) u0_odata_1d<= #1 u0_odata;always@(posedge clk ) u0_oremain_1d <= #1 u0_oremain ;always@(posedge clk ) u0_odata_vld_1d <= #1 u0_odata_vld ;always@(posedge clk ) u0_ovld_num_1d <= #1 u0_ovld_num ;insert4bit u0_insert4bit(.clk(clk ),//inputclk ,.rst(rst ),//inputrst ,.idata (idata[3:0] ),//input [5:0] idata ,//本次输入数据bit[4]可能是无效数据,通过vld_bit4来区分.iremain (iremain),//input [4:0] iremain ,//上个数据最后5bit,用来检查连续1的个数.idata_vld(idata_vld ),//inputidata_vld,//本次数据有效.odata (u0_odata ),//output reg [5:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定 .oremain (u0_oremain ),//output [4:0] oremain ,//本次的高5位,留给下次用 .odata_vld(u0_odata_vld),//output odata_vld,//本次输出数据有效.ovld_num (u0_ovld_num ) //output reg [1:0] ovld_num //高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 );insert4bit u1_insert4bit(.clk(clk ),//inputclk ,.rst(rst ),//inputrst ,.idata (idata_1d[7:4] ),//input [5:0] idata ,//本次输入数据bit[4]可能是无效数据,通过vld_bit4来区分.iremain (u0_oremain ),//input [4:0] iremain ,//上个数据最后5bit,用来检查连续1的个数.idata_vld(u0_odata_vld),//inputidata_vld,//本次数据有效.odata (u1_odata ),//output reg [5:0] odata ,//输出插入0之后的数据,高2bit中的有效个数不定 .oremain (u1_oremain ),//output [4:0] oremain ,//本次的高5位,留给下次用 .odata_vld(u1_odata_vld),//output odata_vld,//本次输出数据有效.ovld_num (u1_ovld_num ) //output reg [1:0] ovld_num //高2bit中的有效个数,0:无 ,1:1个有效 ,2:两个有效 );always@(posedge clk )case({u0_ovld_num_1d,u1_ovld_num}){1'd0,1'd0} : beginodata <= #1 {2'b0,u1_odata[3:0],u0_odata_1d[3:0]};ovld_num<= #1 2'd0;oremain<= #1 {u1_odata[3:0],u0_odata_1d[3]};end{1'd0,1'd1} : beginodata <= #1 {1'b0,u1_odata[4:0],u0_odata_1d[3:0]};ovld_num<= #1 2'd1;oremain<= #1 {u1_odata[4:0]};end{1'd1,1'd1} : beginodata <= #1 {u1_odata[4:0],u0_odata_1d[4:0]};ovld_num<= #1 2'd2;oremain<= #1 {u1_odata[4:0]};end{1'd1,1'd0} : beginodata <= #1 {1'b0,u1_odata[3:0],u0_odata_1d[4:0]};ovld_num<= #1 2'd1;oremain<= #1 {u1_odata[3:0],u0_odata_1d[0]};end{1'd1,1'd2} : beginodata <= #1 {u1_odata[4:0],u0_odata_1d[4:0]};ovld_num<= #1 2'd2;oremain<= #1 {u1_odata[4:0]};enddefault: beginodata <= #1 'b0; ovld_num<= #1 2'd0;oremain<= #1 oremain; endendcaseassign odata_vld =idata_vld_3d;endmodule

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