SRIO系列-仿真测试

2024-04-19 08:04
文章标签 仿真 系列 测试 srio

本文主要是介绍SRIO系列-仿真测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

前两篇已经讲述了SRIO协议的概况,以及xilinx SRIO IP核的使用方式,已经在搭建工程的过程中时钟和复位的注意事项。

二、设计框图

整个框图也是按照之前的工程进行搭建,首先时SRIO_Channel,由SRIO IP核和时钟、复位模块组成,这是在之前的工程搭建中一种采用的一种Channel结构。其次,SRIO Module是按照QPLL共享的方式去管理Channel,使得多个通道能够共享QPLL。最后,用户侧逻辑采用了一个SRIO Engine一共有4次的事务传输,分别是:

  1. 写事务。写256字节的数据。
  2. 发送Doorbell。通知写完成。
  3. 读事务。读取写入的数据
  4. 发送消息,通知读完毕。(消息包一直有负载)

三、SRIO Engine 

这部分参考FPGA奇哥的系列网课。


module SRIO_Engine(input           i_clk                     ,input           i_rst                     ,output          m_axis_ireq_tvalid        , input           m_axis_ireq_tready        , output          m_axis_ireq_tlast         , output [63:0]   m_axis_ireq_tdata         , output [7: 0]   m_axis_ireq_tkeep         , output [31:0]   m_axis_ireq_tuser         , input           s_axis_iresp_tvalid       ,output          s_axis_iresp_tready       ,input           s_axis_iresp_tlast        ,input  [63:0]   s_axis_iresp_tdata        ,input  [7: 0]   s_axis_iresp_tkeep        ,input  [31:0]   s_axis_iresp_tuser        ,input           s_axis_treq_tvalid        ,output          s_axis_treq_tready        ,input           s_axis_treq_tlast         ,input [63:0]    s_axis_treq_tdata         ,input [7: 0]    s_axis_treq_tkeep         ,input [31:0]    s_axis_treq_tuser         ,output          m_axis_tresp_tvalid       ,input           m_axis_tresp_tready       ,output          m_axis_tresp_tlast        ,output  [63:0]  m_axis_tresp_tdata        ,output  [7: 0]  m_axis_tresp_tkeep        ,output  [31:0]  m_axis_tresp_tuser        
);// assign   s_axis_iresp_tready = 0    ;
// assign   s_axis_treq_tready  = 0    ;reg                 rm_axis_ireq_tvalid               ;       
reg                 rm_axis_ireq_tlast                ;
reg  [63:0]         rm_axis_ireq_tdata                ;
reg  [7: 0]         rm_axis_ireq_tkeep                ;
reg  [31:0]         rm_axis_ireq_tuser                ;
reg                 rs_axis_iresp_tready              ;
reg                 rs_axis_treq_tready               ;
reg                 rm_axis_tresp_tvalid              ;
reg                 rm_axis_tresp_tlast               ;
reg  [63:0]         rm_axis_tresp_tdata               ;
reg  [7: 0]         rm_axis_tresp_tkeep               ;
reg  [31:0]         rm_axis_tresp_tuser               ;
reg  [15:0]         r_cnt                             ;
reg  [7: 0]         r_read_cmd                        ;
reg                 r_read_cmd_valid                  ;
reg                 r_read_triger                     ;
reg  [15:0]         r_treq_cnt                        ;
reg  [15:0]         r_read_cnt                        ;wire                w_m_axi_ireq_act                  ;
wire                w_s_axi_iresp_act                 ;
wire                w_s_axi_treq_act                  ;
wire                w_m_axi_tresp_act                 ;assign   m_axis_ireq_tvalid  = rm_axis_ireq_tvalid    ;
assign   m_axis_ireq_tlast   = rm_axis_ireq_tlast     ;
assign   m_axis_ireq_tdata   = rm_axis_ireq_tdata     ;
assign   m_axis_ireq_tkeep   = rm_axis_ireq_tkeep     ;
assign   m_axis_ireq_tuser   = rm_axis_ireq_tuser     ;
assign   s_axis_iresp_tready = rs_axis_iresp_tready   ;
assign   s_axis_treq_tready  = rs_axis_treq_tready    ;
assign   m_axis_tresp_tvalid = rm_axis_tresp_tvalid   ;
assign   m_axis_tresp_tlast  = rm_axis_tresp_tlast    ;
assign   m_axis_tresp_tdata  = rm_axis_tresp_tdata    ;
assign   m_axis_tresp_tkeep  = rm_axis_tresp_tkeep    ;
assign   m_axis_tresp_tuser  = rm_axis_tresp_tuser    ;assign   w_m_axi_ireq_act    = m_axis_ireq_tready & rm_axis_ireq_tvalid;
assign   w_s_axi_iresp_act   = s_axis_iresp_tvalid & rs_axis_iresp_tready;
assign   w_s_axi_treq_act    = s_axis_treq_tvalid & rs_axis_treq_tready;
assign   w_m_axi_tresp_act   = m_axis_tresp_tready && rm_axis_tresp_tvalid;localparam      P_ST_IDLE    = 5'b00001               ,P_ST_WRITE   = 5'b00010               ,P_ST_DB      = 5'b00100               ,P_ST_READ    = 5'b01000               ,P_ST_MESSAGE = 5'b10000               ;reg [4: 0]       r_st_nstate                          ;
reg [4: 0]       r_st_cstate                          ; 
reg [15:0]       r_st_cnt                             ;  always@(posedge i_clk,posedge i_rst)beginif(i_rst)r_st_cstate <= P_ST_IDLE; elser_st_cstate <= r_st_nstate;
endalways@(*)beginr_st_nstate = P_ST_IDLE;case(r_st_cstate)P_ST_IDLE:beginif(r_st_cnt == 1000)r_st_nstate =  P_ST_WRITE;elser_st_nstate =  P_ST_IDLE;end   P_ST_WRITE:beginif(w_m_axi_ireq_act && m_axis_ireq_tlast)r_st_nstate = P_ST_DB;elser_st_nstate = P_ST_WRITE;end  P_ST_DB:beginif(w_m_axi_ireq_act && m_axis_ireq_tlast)r_st_nstate = P_ST_READ;elser_st_nstate = P_ST_DB;            end     P_ST_READ:beginif(w_s_axi_iresp_act && s_axis_iresp_tlast)r_st_nstate = P_ST_MESSAGE;elser_st_nstate = P_ST_READ;              end   P_ST_MESSAGE:beginif(w_m_axi_ireq_act && m_axis_ireq_tlast)r_st_nstate = P_ST_IDLE;elser_st_nstate = P_ST_MESSAGE;              enddefault:beginr_st_nstate = P_ST_IDLE;endendcase    
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_st_cnt <= 'd0;elseif(r_st_cstate != r_st_nstate)r_st_cnt <= 'd0;elser_st_cnt <= r_st_cnt + 1;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_cnt <= 'd0;elseif(r_cnt == 32 && w_m_axi_ireq_act)r_cnt <= 'd0;else if(r_st_nstate == P_ST_WRITE && w_m_axi_ireq_act)//??r_cnt <= r_cnt + 1;elser_cnt <= r_cnt ;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_ireq_tdata <= 'd0;elseif(r_st_nstate == P_ST_WRITE && r_cnt == 0)rm_axis_ireq_tdata <= {8'd0,4'b0110,4'd0,1'b0,2'b00,1'b0,8'hFF,1'b0,1'b0,34'b0};//流写else if(r_st_nstate == P_ST_DB && r_cnt == 0)rm_axis_ireq_tdata <= {8'd0,4'b1010,4'd0,1'b0,2'b00,1'b0,8'h00,1'b0,1'b0,34'b0};//门铃else if(r_st_nstate == P_ST_READ && r_cnt == 0)rm_axis_ireq_tdata <= {8'd0,4'b0010,4'b0100,1'b0,2'b00,1'b0,8'hFF,1'b0,1'b0,34'b0};//读else if(r_st_nstate == P_ST_MESSAGE && r_cnt == 0)rm_axis_ireq_tdata <= {4'd0,4'd0,4'b1011,4'b0000,1'b0,2'b00,1'b0,8'd63,1'b0,1'b0,34'b0};//消息else if(w_m_axi_ireq_act)case(r_cnt)0       : rm_axis_ireq_tdata <= {4{r_cnt}}  ;default : rm_axis_ireq_tdata <= {4{r_cnt}}  ;endcaseelserm_axis_ireq_tdata <= rm_axis_ireq_tdata;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_ireq_tlast <= 'd0;elseif(rm_axis_ireq_tlast && w_m_axi_ireq_act)rm_axis_ireq_tlast <= 'd0;else if(r_st_nstate == P_ST_WRITE && r_cnt == 32 -1 )rm_axis_ireq_tlast <= 1'b1;else if(r_st_nstate == P_ST_DB && r_st_cnt == 0)rm_axis_ireq_tlast <= 1'b1;else if(r_st_nstate == P_ST_READ && r_st_cnt == 0)rm_axis_ireq_tlast <= 1'b1;else if(r_st_nstate == P_ST_MESSAGE && w_m_axi_ireq_act)rm_axis_ireq_tlast <= 1'b1;elserm_axis_ireq_tlast <= rm_axis_ireq_tlast ;endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_ireq_tvalid <= 'd0;elseif(rm_axis_ireq_tlast && w_m_axi_ireq_act)rm_axis_ireq_tvalid <= 'd0;else if(r_st_nstate == P_ST_WRITE && r_st_cnt == 0)rm_axis_ireq_tvalid <= 1'b1;else if(r_st_nstate == P_ST_DB && r_st_cnt == 0)rm_axis_ireq_tvalid <= 1'b1;else if(r_st_nstate == P_ST_READ && r_st_cnt == 0)rm_axis_ireq_tvalid <= 1'b1;else if(r_st_nstate == P_ST_MESSAGE && r_st_cnt == 0)rm_axis_ireq_tvalid <= 1'b1;elserm_axis_ireq_tvalid <= rm_axis_ireq_tvalid;endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_ireq_tkeep <= 'd0;elserm_axis_ireq_tkeep <= 8'hff;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_ireq_tuser <= 'd0;elserm_axis_ireq_tuser <= 8'h00;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_treq_cnt <= 'd0;else if(w_s_axi_treq_act && s_axis_treq_tlast)r_treq_cnt <= 'd0;else if(w_s_axi_treq_act)r_treq_cnt <= r_treq_cnt + 1;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_read_cmd <= 'd0;else if(r_treq_cnt == 0 && w_s_axi_treq_act)r_read_cmd <= s_axis_treq_tdata[55:48];else r_read_cmd <= r_read_cmd + 1;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_read_cmd_valid <= 'd0;else if(r_treq_cnt == 0 && w_s_axi_treq_act)r_read_cmd_valid <= 1'b1;else r_read_cmd_valid <= 'd0;    
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_read_triger <= 'd0;else if(r_read_cmd_valid && r_read_cmd == 8'b0010_0100)r_read_triger <= 1'b1;else r_read_triger <= 'd0;    
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_tresp_tvalid <= 'd0;elseif(rm_axis_tresp_tlast && w_m_axi_tresp_act)rm_axis_tresp_tvalid <= 'd0; else if(r_read_triger)rm_axis_tresp_tvalid <= 1'b1;elserm_axis_tresp_tvalid <= rm_axis_tresp_tvalid;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_tresp_tlast <= 'd0;elseif(rm_axis_tresp_tlast && w_m_axi_tresp_act)rm_axis_tresp_tlast <= 'd0;else if(r_read_cnt == 31)rm_axis_tresp_tlast <= 1'b1;elserm_axis_tresp_tlast <= rm_axis_tresp_tlast;
end always@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_tresp_tdata <= 'd0;elseif(r_read_triger)rm_axis_tresp_tdata <= {8'd0,4'b1101,4'b1000,1'b0,2'b0,1'b0,8'd0,1'b0,1'b0,34'd0};elserm_axis_tresp_tdata <= {4{r_read_cnt - 1}};
end always@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_tresp_tkeep <= 'd0;elserm_axis_tresp_tkeep <= 'd0;
end always@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_tresp_tuser <= 'd0;elserm_axis_tresp_tuser <= 'd0;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_read_cnt <= 'd0;elseif(r_read_cnt == 32 )r_read_cnt <= 'd0;else if(r_read_triger || w_m_axi_tresp_act)r_read_cnt <= r_read_cnt + 1;else r_read_cnt <= r_read_cnt;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rs_axis_treq_tready <= 'd1;elsers_axis_treq_tready <= 1'b1;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rs_axis_iresp_tready <= 'd1;elsers_axis_iresp_tready <= 1'b1;
endendmodule

仿真图如下:

如图在ireq端口上首先发送写事务和数据,之后发起门铃事务,在之后发起读事务。

在iresp端口上返回读过来的数据

 最后读完数据后,可以发起消息事务,通知对端已经接收到数据

四、总结

本篇文章目的在于简单的实践一下SRIO IP核,所以操作非常简单。如果真的要去用SRIO协议,需要涉及的理论还是挺多的。

这篇关于SRIO系列-仿真测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/916986

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训