当前位置: 首页 > ai >正文

UDP--DDR--SFP,FPGA实现之指令监测模块实现

指令监测模块实现介绍

如下图所示,为指令监测模块的运行框图
在这里插入图片描述
将指令设置为8bytes数据,故需要一个64位寄存器进行缓存,在进行数据缓存时,数据不可以输出至下一级模块,故对数据和有效指示信号也应该进行相应延迟,指令缓存8周期,检验一周期,为了数据的稳定输出,故延迟10周期,使用shift_ram ip实现该功能即可。
当监测到头部8个数据不属于指令数据后,进行有效数据输出,而若监测到为指令数据,则在输出有效信号置0,下一级模块即不会进行数据缓存,避免数据文件缓存错误。

指令监测模块代码编写

根据上述框图的介绍,以及逻辑的梳理,本节代码可以清晰写出,其代码实现如下:

module udp_cmd_check(input               i_clk           ,input               i_rst           ,input   [7 :0]      i_udp_data      ,input               i_udp_valid     ,output  [7 :0]      o_udp_data      ,output              o_udp_valid     ,output              o_store_done    ,output              o_raddr_clear   );reg     [63:0]          r_check_data    ;
reg     [1 :0]          r_check_res     ;
reg     [1 :0]          r_clear_res     ;
reg     [1 :0]          ro_raddr_clear  ;
wire    [8 :0]          w_dly_din       ;
wire    [8 :0]          w_dly_dout      ;
wire                    w_store_done    ;
wire                    w_raddr_clear   ;assign  w_dly_din       = {i_udp_data,i_udp_valid};dly_w9d10 dly_w9d10_u0 (.D      (w_dly_din  ),.CLK    (i_clk      ),.Q      (w_dly_dout )
);assign  w_store_done = &r_check_res ? 1'b1 : 1'b0;
assign  w_raddr_clear= &r_clear_res ? 1'b1 : 1'b0;
assign  o_udp_data   = w_dly_dout[8 :1] ;
assign  o_udp_valid  = (w_store_done == 1'b1 || w_raddr_clear == 1'b1) ? 1'b0 : w_dly_dout[0];
assign  o_store_done = w_store_done     ;
assign  o_raddr_clear= w_raddr_clear    ;always @(posedge i_clk,posedge i_rst) beginif(i_rst)r_check_data <= 64'd0;else if(i_udp_valid) r_check_data <= {r_check_data[55:0],i_udp_data};
endalways @(posedge i_clk,posedge i_rst) beginif(i_rst)r_check_res <= 2'b00;else if(r_check_data[63:32] == 32'HA5A5A5A5 && r_check_data[31 :0] == 32'HBCBCBCBC) r_check_res <= 2'b11;elser_check_res <= 2'b00;
endalways @(posedge i_clk,posedge i_rst) beginif(i_rst)r_clear_res <= 2'b00;else if(r_check_data[63:32] == 32'HD5D5D5D5 && r_check_data[31 :0] == 32'HFCFCFCFC) r_clear_res <= 2'b11;else if(r_dly_valid & ~w_dly_dout[0])r_clear_res <= 2'b00;
endendmodule

实际r_check_res 和 r_clear_res 只需1bit也可,笔者之前为了降低逻辑位宽过大,曾对高32位和低32位进行分别判断,测试来看,上述代码也可以正常运转,时序不存在问题。

指令监测模块仿真

在代码编写完成后,便需要进行仿真测试,编写仿真文件,因为在之后的各个模块检验中,都需要进行udp数据接收的模拟,笔者便将udp数据发送、指令发送,编写为对应的任务块,方便进行复用,tb文件代码如下

reg                 i_udp_clk       = 1'b0;
reg                 i_udp_rst       = 1'b0;
wire    [7 :0]      w_store_udp_data    ;
wire                w_store_udp_valid   ;
wire                w_store_done        ;
wire                w_raddr_clear       ;
integer i = 0;
integer j = 0;
always #4   i_udp_clk = ~i_udp_clk;
initial begini_udp_rst = 1;i_sfp_rst = 1;i_ui_rst  = 1;#100@(i_sfp_clk) begini_udp_rst <= 1'b0;i_sfp_rst <= 1'b0;i_ui_rst  <= 1'b0;end#100/*传输擦除指令*/@(posedge i_udp_clk)udp_cmd(64'HD5D5D5D5_FCFCFCFC);/*传输32KB*/@(posedge i_udp_clk)for(i = 0;i < 32; i = i + 1) begin@(posedge i_udp_clk)udp_send(1024);#500@(posedge i_udp_clk);end/*传输完成指令*/@(posedge i_udp_clk)udp_cmd(64'HA5A5A5A5_BCBCBCBC);
/*指令监测,输出监测后数据*/
udp_cmd_check udp_cmd_check_u0(.i_clk              (i_udp_clk          ),.i_rst              (i_udp_rst          ),.i_udp_data         (i_udp_data         ),.i_udp_valid        (i_udp_valid        ),.o_udp_data         (w_store_udp_data   ),.o_udp_valid        (w_store_udp_valid  ),.o_store_done       (w_store_done       ),.o_raddr_clear      (w_raddr_clear      ));
task udp_send(input    [15:0]  byte_len);begin : datainteger i;i_udp_data   = 8'd0;i_udp_valid  = 1'd0;@(posedge i_udp_clk);for(i = 0;i < byte_len ;i = i + 1)begini_udp_data  <= i_udp_data + 1'b1;i_udp_valid <= 1'b1;@(posedge i_udp_clk);endi_udp_data   <= 8'd0;i_udp_valid  <= 1'd0;
end
endtasktask udp_cmd(input    [63:0]  i_cmd);begin : cmdinteger i;i_udp_data   = 8'd0;i_udp_valid  = 1'd0;@(posedge i_udp_clk);for(i = 0;i < 8 ;i = i + 1)begini_udp_data  <= i_cmd[63:56];i_cmd <= {i_cmd[55:0],8'h0};i_udp_valid <= 1'b1;@(posedge i_udp_clk);endi_udp_data   <= 8'd0;i_udp_valid  <= 1'd0;
end
endtask

其模拟过程即是,首先发送擦除指令,然后进行数据发送,在数据传输完成后,发送数据完成指令,在仿真过程中,就这三项测试做验证,监测模块是否成功识别指令,阻止指令数据输出,以及是否成功输出有效数据。
在这里插入图片描述
由图片可知,模块成功监测到DDR擦除指令,并将清除信号输出置高多周期,数据输出有效信号置低,在标准以太网中帧长间隔为12bytes,在仿真测试中,并未严格要求该参数,但实际模块工作可以适应这类情况。
在这里插入图片描述
由图片可知,成功对数据进行了下一级模块转发。
在这里插入图片描述
观察文件传输完成,发送结束码,模块成功监测出结束码,拉高传输完成信号,并且数据未进行有效输出,避免了错误缓存。
经过上述仿真,可以看出该模块正常工作,对于该模块的编写是较为简单的,但指令识别功能,在开发中,是十分常用的模块,有必要进行掌握。关于本节代码的问题,以及优化意见,欢迎大家在评论区指出,如果想要对应工程进行学习,欢迎大家私信。

http://www.xdnf.cn/news/5745.html

相关文章:

  • 鸿蒙北向应用开发: deveco5.0 创建开源鸿蒙项目
  • django扩展练习记录
  • 一文详解Spring Boot如何配置日志
  • 第一章 应急响应-webshell查杀
  • 【免杀】C2免杀技术(一)VS设置
  • 逆向破解:x64dbg
  • 操作系统实战——QEMU模拟器搭建【rCore 操作系统】
  • 多线程访问Servlet如何谨慎处理共享资源
  • 5.10-套接字通信 - C++
  • Spring急速入门
  • Linux系统管理与编程18:自动化部署dhcp服务
  • QML状态机制示例(State)
  • 数据知识产权质押融资风险控制
  • 前端面试每日三题 - Day 31
  • 环境扫描电镜对含水样品的观察技术与方法
  • Yolov8数据增强配置
  • 聊一聊AI对接口测试的潜在影响有哪些?
  • 【Mysql基础】一、基础入门和常见SQL语句
  • Service Mesh实战之Istio
  • 12.2.2 allocator类
  • CMake 命令行参数全解析(2025年更新版)
  • Clang实现C++文件分析,含Python实战
  • 使用webservice生成节假日/双休日/工作日信息
  • 蚁群算法赋能生鲜配送:MATLAB 实现多约束路径优化
  • PowerBI基础
  • bunsenlabs系统详解
  • java 中 DTO 和 VO 的核心区别
  • 基于SpringBoot的校园周边美食探索及分享平台【附源码+数据库+文档下载】
  • JSON 实体属性映射的最佳实践
  • 人脸识别的应用场景变化