昨天已经写完将100个数据锁存到对应寄存器里面,下面就是解B码的过程。
- (*noprune*)reg [7:0] utc_sec;
- (*noprune*)reg [7:0] utc_min;
- (*noprune*)reg [7:0] utc_hou;
- (*noprune*)reg [9:0] utc_day;
- (*noprune*)reg [7:0] utc_yea;
-
- always@(posedge clk or negedge rst_n)
- begin
- if (rst_n == 1'b0)begin
- utc_sec <= 8'd0;
- utc_min <= 8'd0;
- utc_hou <= 8'd0;
- utc_day <= 10'd0;
- utc_yea <= 8'd0;
- end
- else if (bcodeflag == 1'b1)begin
- if(b_data_rec3 >= 4'd1)utc_sec[0] <= 1'b0;
- if(b_data_rec3 >= 4'd2)utc_sec[0] <= 1'b1;
- if(b_data_rec4 >= 4'd1)utc_sec[1] <= 1'b0;
- if(b_data_rec4 >= 4'd2)utc_sec[1] <= 1'b1;
- if(b_data_rec5 >= 4'd1)utc_sec[2] <= 1'b0;
- if(b_data_rec5 >= 4'd2)utc_sec[2] <= 1'b1;
- if(b_data_rec6 >= 4'd1)utc_sec[3] <= 1'b0;
- if(b_data_rec6 >= 4'd2)utc_sec[3] <= 1'b1;
- if(b_data_rec8 >= 4'd1)utc_sec[4] <= 1'b0;
- if(b_data_rec8 >= 4'd2)utc_sec[4] <= 1'b1;
- if(b_data_rec9 >= 4'd1)utc_sec[5] <= 1'b0;
- if(b_data_rec9 >= 4'd2)utc_sec[5] <= 1'b1;
- if(b_data_rec10 >= 4'd1)utc_sec[6] <= 1'b0;
- if(b_data_rec10 >= 4'd2)utc_sec[6] <= 1'b1;
-
- if(b_data_rec12 >= 4'd1)utc_min[0] <= 1'b0;
- if(b_data_rec12 >= 4'd2)utc_min[0] <= 1'b1;
- if(b_data_rec13 >= 4'd1)utc_min[1] <= 1'b0;
- if(b_data_rec13 >= 4'd2)utc_min[1] <= 1'b1;
- if(b_data_rec14 >= 4'd1)utc_min[2] <= 1'b0;
- if(b_data_rec14 >= 4'd2)utc_min[2] <= 1'b1;
- if(b_data_rec15 >= 4'd1)utc_min[3] <= 1'b0;
- if(b_data_rec15 >= 4'd2)utc_min[3] <= 1'b1;
- if(b_data_rec17 >= 4'd1)utc_min[4] <= 1'b0;
- if(b_data_rec17 >= 4'd2)utc_min[4] <= 1'b1;
- if(b_data_rec18 >= 4'd1)utc_min[5] <= 1'b0;
- if(b_data_rec18 >= 4'd2)utc_min[5] <= 1'b1;
- if(b_data_rec19 >= 4'd1)utc_min[6] <= 1'b0;
- if(b_data_rec19 >= 4'd2)utc_min[6] <= 1'b1;
- if(b_data_rec20 >= 4'd1)utc_min[7] <= 1'b0;
- if(b_data_rec20 >= 4'd2)utc_min[7] <= 1'b1;
-
- if(b_data_rec22 >= 4'd1)utc_hou[0] <= 1'b0;
- if(b_data_rec22 >= 4'd2)utc_hou[0] <= 1'b1;
- if(b_data_rec23 >= 4'd1)utc_hou[1] <= 1'b0;
- if(b_data_rec23 >= 4'd2)utc_hou[1] <= 1'b1;
- if(b_data_rec24 >= 4'd1)utc_hou[2] <= 1'b0;
- if(b_data_rec24 >= 4'd2)utc_hou[2] <= 1'b1;
- if(b_data_rec25 >= 4'd1)utc_hou[3] <= 1'b0;
- if(b_data_rec25 >= 4'd2)utc_hou[3] <= 1'b1;
- if(b_data_rec27 >= 4'd1)utc_hou[4] <= 1'b0;
- if(b_data_rec27 >= 4'd2)utc_hou[4] <= 1'b1;
- if(b_data_rec28 >= 4'd1)utc_hou[5] <= 1'b0;
- if(b_data_rec28 >= 4'd2)utc_hou[5] <= 1'b1;
- if(b_data_rec29 >= 4'd1)utc_hou[6] <= 1'b0;
- if(b_data_rec29 >= 4'd2)utc_hou[6] <= 1'b1;
- if(b_data_rec30 >= 4'd1)utc_hou[7] <= 1'b0;
- if(b_data_rec30 >= 4'd2)utc_hou[7] <= 1'b1;
-
- if(b_data_rec32 >= 4'd1)utc_day[0] <= 1'b0;
- if(b_data_rec32 >= 4'd2)utc_day[0] <= 1'b1;
- if(b_data_rec33 >= 4'd1)utc_day[1] <= 1'b0;
- if(b_data_rec33 >= 4'd2)utc_day[1] <= 1'b1;
- if(b_data_rec34 >= 4'd1)utc_day[2] <= 1'b0;
- if(b_data_rec34 >= 4'd2)utc_day[2] <= 1'b1;
- if(b_data_rec35 >= 4'd1)utc_day[3] <= 1'b0;
- if(b_data_rec35 >= 4'd2)utc_day[3] <= 1'b1;
- if(b_data_rec37 >= 4'd1)utc_day[4] <= 1'b0;
- if(b_data_rec37 >= 4'd2)utc_day[4] <= 1'b1;
- if(b_data_rec38 >= 4'd1)utc_day[5] <= 1'b0;
- if(b_data_rec38 >= 4'd2)utc_day[5] <= 1'b1;
- if(b_data_rec39 >= 4'd1)utc_day[6] <= 1'b0;
- if(b_data_rec39 >= 4'd2)utc_day[6] <= 1'b1;
- if(b_data_rec40 >= 4'd1)utc_day[7] <= 1'b0;
- if(b_data_rec40 >= 4'd2)utc_day[7] <= 1'b1;
- if(b_data_rec42 >= 4'd1)utc_day[8] <= 1'b0;
- if(b_data_rec42 >= 4'd2)utc_day[8] <= 1'b1;
- if(b_data_rec43 >= 4'd1)utc_day[9] <= 1'b0;
- if(b_data_rec43 >= 4'd2)utc_day[9] <= 1'b1;
-
- if(b_data_rec52 >= 4'd1)utc_yea[0] <= 1'b0;
- if(b_data_rec52 >= 4'd2)utc_yea[0] <= 1'b1;
- if(b_data_rec53 >= 4'd1)utc_yea[1] <= 1'b0;
- if(b_data_rec53 >= 4'd2)utc_yea[1] <= 1'b1;
- if(b_data_rec54 >= 4'd1)utc_yea[2] <= 1'b0;
- if(b_data_rec54 >= 4'd2)utc_yea[2] <= 1'b1;
- if(b_data_rec55 >= 4'd1)utc_yea[3] <= 1'b0;
- if(b_data_rec55 >= 4'd2)utc_yea[3] <= 1'b1;
- if(b_data_rec57 >= 4'd1)utc_yea[4] <= 1'b0;
- if(b_data_rec57 >= 4'd2)utc_yea[4] <= 1'b1;
- if(b_data_rec58 >= 4'd1)utc_yea[5] <= 1'b0;
- if(b_data_rec58 >= 4'd2)utc_yea[5] <= 1'b1;
- if(b_data_rec59 >= 4'd1)utc_yea[6] <= 1'b0;
- if(b_data_rec59 >= 4'd2)utc_yea[6] <= 1'b1;
- if(b_data_rec60 >= 4'd1)utc_yea[7] <= 1'b0;
- if(b_data_rec60 >= 4'd2)utc_yea[7] <= 1'b1;
- end
- end
前面锁存的信号为3,2,1和0信号,3代表P标志位,2代表高电平,1代表低电平。所以先将锁存器的值转化为01信号,判断完毕后,进行计算。
注意:这里用的脉冲信号为bcodeflag,这个信号在采集到101个点的时候计算,并且没有时间卡点。因为B码的最后一位是不代表信息的,所以这个就不用过多考虑锁存不锁存的问题,所有的B码都是前面99个里面。
- reg resettime3_en_d0;
- reg resettime3_en_d1;
- wire resettime3_falling_flag;
- wire resettime3_rasing_flag;
- assign resettime3_falling_flag = (~resettime3_en_d0) & resettime3_en_d1;
- assign resettime3_rasing_flag = (~resettime3_en_d1) & resettime3_en_d0;
- always @(posedge clk or negedge rst_n) begin
- if (!rst_n) begin
- resettime3_en_d0 <= 1'b0;
- resettime3_en_d1 <= 1'b0;
- end
- else begin
- resettime3_en_d0 <= bcodeflag;
- resettime3_en_d1 <= resettime3_en_d0;
- end
- end
在bcodeflag的下降沿之后顺延一个周期,即判断完01之后,进行计算。
- (*noprune*)reg [31:0] utc_SecondData;
- (*noprune*)reg [31:0] utc_MinuteData;
- (*noprune*)reg [31:0] utc_HourData;
- (*noprune*)reg [31:0] utc_DayData;
- (*noprune*)reg [31:0] utc_YearData;
- always@(posedge clk or negedge rst_n)
- begin
- if (rst_n == 1'b0)
- utc_SecondData <= 32'd0;
- else if (resettime3_falling_flag == 1'b1)begin
- utc_SecondData = utc_sec[0] + 2*utc_sec[1] + 4*utc_sec[2] + 8*utc_sec[3]
- +(utc_sec[4] + 2*utc_sec[5] + 4*utc_sec[6])*10;
-
- utc_MinuteData = utc_min[0] + 2*utc_min[1] + 4*utc_min[2] + 8*utc_min[3]
- +(utc_min[4] + 2*utc_min[5] + 4*utc_min[6] + 8*utc_min[7])*10;
-
- utc_HourData = utc_hou[0] + 2*utc_hou[1] + 4*utc_hou[2] + 8*utc_hou[3]
- +(utc_hou[4] + 2*utc_hou[5] + 4*utc_hou[6] + 8*utc_hou[7])*10;
-
- utc_DayData = utc_day[0] + 2*utc_day[1] + 4*utc_day[2] + 8*utc_day[3]
- +(utc_day[4] + 2*utc_day[5] + 4*utc_day[6] + 8*utc_day[7])*10
- +(utc_day[8] + 2*utc_day[9])*100;
-
- utc_YearData = utc_yea[0] + 2*utc_yea[1] + 4*utc_yea[2] + 8*utc_yea[3]
- +(utc_yea[4] + 2*utc_yea[5] + 4*utc_yea[6] + 8*utc_yea[7])*10;
-
- end
- end
这样在最后一个脉宽的时候计算出对应的utc时间。
接入B码后可以看出,cnt到100,然后变为101,但是在锁存之前变为0。之后再resetime3之后的下降沿,B码的秒时间可以看出是31s,而其他时间为14点28,而年对应为22,即2022年,验证后,天数为216天,即2022年8月4日。当然这仅仅验证了UTC时间的解码,其他的关键信息还没有提取出来。应该可以用同样的方法可以将其他信息放到一个寄存器中。
- always@(posedge clk or negedge rst_n)
- begin
- if (rst_n == 1'b0)
- bcodebitcnt <= 8'd0;
- else if (bpluse_falling_flag == 1)
- bcodebitcnt <= bcodebitcnt + 1'b1;
- else if (bcodereadyflag == 1)
- bcodebitcnt <= 8'd3;
- else if (bcodebitcnt == 8'd101)
- bcodebitcnt <= 0;
- else
- bcodebitcnt <= bcodebitcnt;
- end
-
- always@(posedge clk or negedge rst_n)
- begin
- if (rst_n == 1'b0)
- bcodeflag <= 1'd0;
- else if (bpluse_falling_flag == 1)
- bcodeflag <= 1'd0;
- else if (bcodebitcnt == 8'd101)
- bcodeflag <= 1'd1;
- else
- bcodeflag <= 1'd0;
- end
这段代码输出两个量,一个是cnt,也就是没有锁存时,在B码的下降沿时,从0到100,锁存之后从3到100。另一个是bcodeflag,当下降沿来时等于0,当cnt等于101时变为1。这个地方问题就是没有锁存两个B码的P标志时,cnt也会变为101,这样bcodeflag也会变为1,也即utc时间也会计算,这个就比较麻烦了。
1PPS的上升沿和2个P标志中的第二个脉宽上升沿重合,这样必须判断出来两个P帧之后,在下一个1s中的时候,第2个B码的脉宽的上升沿处输出脉冲。现在考虑两种方案:
(1)方案1:判断2个P标志之后,定时器开启,在995ms的时候输出1个flag,然后1005ms时输出0flag,然后将B码信号与这个flag与一下,那样输出的脉冲即为1PPS的上升沿。
(2)方案2:判断2个P标志之后,在1sB码的之后的下一个1s的第一个P标志之后,输出1个flag,然后输出一定宽度的flag,然后将B码信号与这个flag与一下,也可以输出对应的1PPS脉冲的上升沿。
先不考虑其他传递参数,仅仅考虑utc时间的话,在600ms左右能解出具体的utc时间,所以在下一个1pps之前,做好准备是没什么问题。
出现以下问题需要解决:
(1)B码在2个P标志位之后信号出现问题,B码在中间消失,之后B码继续出现。
(2)B码在2个P标志位之后信号出现问题,B码间隔固定时间,即之后的P帧刚好对上,B码再次出现。
所以感觉能锁存到2个P帧是关键,之后无论B码怎么消失,只要在下一个2个P帧到来时,给定高电平与B码与就行,所以选择第1个方案比较稳妥。
至于B码消失,utc时间怎么解,这个需要再次考虑。
所以按照第一个方案的思路解决1PPS的输出问题。