zoukankan      html  css  js  c++  java
  • Verilog-数据包检测器

    题目

    正常情况下数据包由起始码(16bit)、数据段(n byte<256)、结束码(16bit)3部分组成。起始码为0xFF00,结束码为0xFF01.在一个完整的数据包中,数据段部分不会出现起始码和结束码,请设计一个电路在码流中检测完整且有效的数据包,并输出当前数据包的有效数据长度n。

    代码

    `timescale 1ns / 1ps
    
    module data_packet_detect(
    	input clk,
    	input rstn,
    	
    	input [7:0] din,
    	input din_vld,
    	
    	output [7:0] data_cnt,
    	output data_cnt_vld
        );
    
    localparam IDLE = 0;
    localparam START = 1;
    localparam DATA = 2;
    localparam OVER = 3;
    
    reg [1:0] state,next_state;
    reg [7:0] data_cnt_reg;
    reg flag_FF;  // 此标志位为数据包将结束时收到的FF
    
    always @(posedge clk or negedge rstn) begin
    	if(!rstn) state <= IDLE;
    	else state <= next_state;
    end
    
    always @(*) begin
    	case(state)
    		IDLE:
    			begin
    				if(din_vld && din == 8'hFF) next_state = START;
    				else next_state = IDLE;
    			end
    		START:
    			begin
    				if(din_vld && din == 8'h00) next_state = DATA;
    				else next_state = IDLE;
    			end
    		DATA:
    			begin
    				if(din_vld && din == 8'h01 && flag_FF) next_state = OVER;  //收到FF01
    				else next_state = DATA;
    			end
    		OVER:
    			begin
    				next_state = IDLE;
    			end
    		default: next_state = IDLE;
    	endcase
    end
    
    always @(posedge clk or negedge rstn) begin
    	if(!rstn) data_cnt_reg <= 8'd0;
    	else begin
    		if(state == DATA) data_cnt_reg <= data_cnt_reg + 1'b1;
    		else if(state == OVER) data_cnt_reg <= 8'd0;
    		else data_cnt_reg <= data_cnt_reg;
    	end
    end
    
    always @(posedge clk or negedge rstn) begin
    	if(!rstn) flag_FF <= 1'b0;
    	else begin
    		if(din_vld && state == DATA && din == 8'hFF) flag_FF <= 1'b1;
    		else flag_FF <= 1'b0;
    	end
    end
    
    assign data_cnt_vld = (state == OVER)? 1'b1 : 1'b0;
    assign data_cnt = data_cnt_reg - 2'd2;  // 实际数据包长度需要减去结束标志位的2个字节
    
    endmodule
    
    
    

    测试激励

    `timescale 1ns / 1ps
    
    module data_packet_detect_tb;
    
    	// Inputs
    	reg clk;
    	reg rstn;
    	reg [7:0] din;
    	reg din_vld;
    
    	// Outputs
    	wire [7:0] data_cnt;
    	wire data_cnt_vld;
    
    	// Instantiate the Unit Under Test (UUT)
    	data_packet_detect uut (
    		.clk(clk), 
    		.rstn(rstn), 
    		.din(din), 
    		.din_vld(din_vld), 
    		.data_cnt(data_cnt), 
    		.data_cnt_vld(data_cnt_vld)
    	);
    
    	initial begin
    		// Initialize Inputs
    		clk = 0;
    		rstn = 0;
    		din = 0;
    		din_vld = 0;
    
    		// Wait 100 ns for global reset to finish
    		#100;
    		
    		@(negedge clk);
    		rstn = 1;
    		
    		@(negedge clk);
    		din_vld = 1;
    		din = 8'h01;
    		
    		@(posedge clk);
    		din = 8'h02;
    
    		@(posedge clk);
    		din = 8'hFF;
    
    		@(posedge clk);
    		din = 8'h03;
    
    		@(posedge clk);
    		din = 8'hFF;
    
    		@(posedge clk);
    		din = 8'h00;
    
    		@(posedge clk);
    		din = 8'h01;	
    
    		@(posedge clk);
    		din = 8'h02;
    
    		@(posedge clk);
    		din = 8'h03;
    
    		@(posedge clk);
    		din = 8'hFF;
    
    		@(posedge clk);
    		din = 8'h03;
    
    		@(posedge clk);
    		din = 8'hFF;
    
    		@(posedge clk);
    		din = 8'h01;	
    
    		@(posedge clk);
    		din_vld = 0;
            
    		// Add stimulus here
    
    	end
    	
    	always #20 clk = ~clk;
          
    endmodule
    

    波形

  • 相关阅读:
    合并两个排序的链表
    反转链表
    java网络编程之TCP通讯
    java网络编程之UDP通讯
    Java中的线程同步机制
    阿里研发工程师面试题三个小结
    Android开发的进阶之路
    获取一个字符串中每一个字母出现的次数使用map集合
    Android常见面试题目
    Java垃圾回收
  • 原文地址:https://www.cnblogs.com/wt-seu/p/12874855.html
Copyright © 2011-2022 走看看