万兆以太网MAC设计(4)CRC_process模块

news2024/11/17 15:50:44

文章目录

  • 前言
  • 一、模块功能
  • 二、实现过程
  • 三、仿真
  • 总结

前言

上文介绍的MAC_RX模块当中增加了CRC校验和比对的功能,本文将根据CRC校验的结果,来决定将数据输出到上层用户还是丢弃。

一、模块功能

  1. 接收MAC_RX模块输出的AXIS数据,存入本地环形RAM当中
  2. 根据MAC_RX模块给出的CRC校验结果,来决定是否输出数据,只有正确的情况下才会从RAM当中将数据吐出,否则不输出,下一帧数据将会直接覆盖错误数据。
module CRC_process(
    input           i_clk               ,
    input           i_rst               ,

    input  [63:0]   s_axis_rdata        ,
    input  [79:0]   s_axis_ruser        ,
    input  [7 :0]   s_axis_rkeep        ,
    input           s_axis_rlast        ,
    input           s_axis_rvalid       ,
    input           i_crc_error         ,
    input           i_crc_valid         ,
    
    output [63:0]   m_axis_rdata        ,
    output [79:0]   m_axis_ruser        ,
    output [7 :0]   m_axis_rkeep        ,
    output          m_axis_rlast        ,
    output          m_axis_rvalid       
);

二、实现过程

BRAM_SD_64X256 BRAM_SD_64X256_data (
  .clka         (i_clk              ), // input wire clka
  .ena          (rs_axis_rvalid     ), // input wire ena
  .wea          (rs_axis_rvalid     ), // input wire [0 : 0] wea
  .addra        (r_ram_data_addra   ), // input wire [7 : 0] addra
  .dina         (rs_axis_rdata      ), // input wire [63 : 0] dina
  .clkb         (i_clk              ), // input wire clkb
  .enb          (r_ram_data_enb     ), // input wire enb
  .addrb        (r_ram_data_addrb   ), // input wire [7 : 0] addrb
  .doutb        (w_ram_data_doutb   )  // output wire [63 : 0] doutb
);
  
BRAM_SD_16X32 BRAM_SD_16X32_len (
  .clka         (i_clk              ), // input wire clka             
  .ena          (rs_axis_rlast      ), // input wire ena              
  .wea          (rs_axis_rlast      ), // input wire [0 : 0] wea      
  .addra        (r_ram_len_addra    ), // input wire [4 : 0] addra    
  .dina         (rs_axis_ruser[79:64]), // input wire [15 : 0] dina    
  .clkb         (i_clk              ), // input wire clkb             
  .enb          (r_ram_len_enb      ), // input wire enb              
  .addrb        (r_ram_len_addrb    ), // input wire [4 : 0] addrb    
  .doutb        (w_ram_len_doutb    )  // output wire [15 : 0] doutb  
);

BRAM_SD_8X32 BRAM_SD_8X32_keep (
  .clka         (i_clk              ),  // input wire clka            
  .ena          (rs_axis_rlast      ),  // input wire ena             
  .wea          (rs_axis_rlast      ),  // input wire [0 : 0] wea     
  .addra        (r_ram_keep_addra   ),  // input wire [4 : 0] addra   
  .dina         (rs_axis_rkeep      ),  // input wire [7 : 0] dina    
  .clkb         (i_clk              ),  // input wire clkb            
  .enb          (r_ram_keep_enb     ),  // input wire enb             
  .addrb        (r_ram_keep_addrb   ),  // input wire [4 : 0] addrb   
  .doutb        (w_ram_keep_doutb   )   // output wire [7 : 0] doutb  
);

BRAM_SD_64X32 BRAM_SD_64X32_user (
  .clka         (i_clk              ),  // input wire clka
  .ena          (rs_axis_rlast      ),  // input wire ena
  .wea          (rs_axis_rlast      ),  // input wire [0 : 0] wea
  .addra        (r_ram_user_addra   ),  // input wire [4 : 0] addra
  .dina         (rs_axis_ruser[63:0]),  // input wire [63 : 0] dina
  .clkb         (i_clk              ),  // input wire clkb
  .enb          (r_ram_user_enb     ),  // input wire enb
  .addrb        (r_ram_user_addrb   ),  // input wire [4 : 0] addrb
  .doutb        (w_ram_user_doutb   )   // output wire [63 : 0] doutb
);

通过4个简单双端口的BRAM实现:

  1. 数据、长度信息(在axis_user当中)、尾端keep以及user数据分别存入对应RAM当中。
  2. 当CRC正确时,各个RAM的地址保持不变,下一帧数据紧随其后被填充进RAM,如果CRC错误,则地址回退到上一次结束的地址,即丢弃刚刚写入的错误数据。
  3. 得到一次CRC正确数据r_recv_flag加1,输出一次数据r_send_flag加1,俩者不相等说明此时RAM里存在数据,拉高r_run
  4. r_run被拉高表示需要开始输出RAM当中的各种信息,并且通过AXIS接口形式传递给上层模块。

该部分核心代码:

//输入数据进如ram,起始地址由r_data_start_addra决定,len和keep同理
always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_ram_data_addra <= 'd0;
    else if(ri_crc_valid_1d && ri_crc_error_1d)
        r_ram_data_addra <= r_data_start_addra;//crc错误则回退到上次起始地址写入新数据
    else if(rs_axis_rvalid)
        r_ram_data_addra <= r_ram_data_addra + 1;
    else
        r_ram_data_addra <= r_ram_data_addra;
end

always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_ram_len_addra <= 'd0;
    else if(ri_crc_valid_1d && ri_crc_error_1d)
        r_ram_len_addra <= r_len_start_addra;//crc错误则回退到上次起始地址写入新数据
    else if(rs_axis_rlast)
        r_ram_len_addra <= r_ram_len_addra + 1;
    else
        r_ram_len_addra <= r_ram_len_addra;
end

always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_ram_keep_addra <= 'd0;
    else if(ri_crc_valid_1d && ri_crc_error_1d)
        r_ram_keep_addra <= r_keep_start_addra;//crc错误则回退到上次起始地址写入新数据
    else if(rs_axis_rlast)
        r_ram_keep_addra <= r_ram_keep_addra + 1;
    else
        r_ram_keep_addra <= r_ram_keep_addra;
end

always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_ram_user_addra <= 'd0;
    else if(ri_crc_valid_1d && ri_crc_error_1d)
        r_ram_user_addra <= r_user_start_addra;//crc错误则回退到上次起始地址写入新数据
    else if(rs_axis_rlast)
        r_ram_user_addra <= r_ram_user_addra + 1;
    else
        r_ram_user_addra <= r_ram_user_addra;
end

// 当数据CRC正确,那么记录此时地址,作为下一帧数据的开始地址,否则保持不变,
// 下一帧数据进来后依旧从上上帧数据结束位置开始写入,即覆盖(丢掉了)CRC错误数据
always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)begin
        r_data_start_addra <= 'd0;
        r_len_start_addra  <= 'd0;
        r_keep_start_addra <= 'd0;
        r_user_start_addra <= 'd0;
    end
    else if(ri_crc_valid && !ri_crc_error)begin
        r_data_start_addra <= r_ram_data_addra;
        r_len_start_addra  <= r_ram_len_addra ;
        r_keep_start_addra <= r_ram_keep_addra;
        r_user_start_addra <= r_ram_user_addra;
    end
    else begin
        r_data_start_addra <= r_data_start_addra;
        r_len_start_addra  <= r_len_start_addra ;
        r_keep_start_addra <= r_keep_start_addra;
        r_user_start_addra <= r_user_start_addra;
    end
end

//得到一次正确数据r_recv_flag加1,输出一次数据r_send_flag加1
//俩者不相等说明此时ram里存在数据,拉高r_run
always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_recv_flag <= 'd0;
    else if(ri_crc_valid && !ri_crc_error)
        r_recv_flag <= r_recv_flag + 'd1;
    else
        r_recv_flag <= r_recv_flag;
end

always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_send_flag <= 'd0;
    else if(rm_axis_rlast)
        r_send_flag <= r_send_flag + 'd1;
    else
        r_send_flag <= r_send_flag;
end

//r_run指示当前正在输出数据
always @(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        r_run <= 'd0;
    else if(rm_axis_rlast)
        r_run <= 'd0;
    else if((r_recv_flag != r_send_flag) && !rm_axis_rvalid)
        r_run <= 'd1;
    else
        r_run <= r_run;
end

三、仿真

黄线时刻CRC发生错误,因此并没有向上层输出AIS数据,并且地址会回退到上一次正确数据输入结束的地址,重新写入新的数据并且进行CRC判断。,
在这里插入图片描述

总结

完整代码参考:https://github.com/shun6-6/Ten_gig_eth_design

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1594944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud学习笔记:Eureka集群搭建样例

这是本人学习的总结&#xff0c;主要学习资料如下 - 马士兵教育 1、项目架构2、Dependency3、项目启动类4、application.yml5、启动项目 1、项目架构 因为这是单机模拟集群搭建&#xff0c;为了方便管理就都放在了一个项目中。这次准备搭建三个项目server1, server2, server3 …

软件杯 深度学习卷积神经网络垃圾分类系统 - 深度学习 神经网络 图像识别 垃圾分类 算法 小程序

文章目录 0 简介1 背景意义2 数据集3 数据探索4 数据增广(数据集补充)5 垃圾图像分类5.1 迁移学习5.1.1 什么是迁移学习&#xff1f;5.1.2 为什么要迁移学习&#xff1f; 5.2 模型选择5.3 训练环境5.3.1 硬件配置5.3.2 软件配置 5.4 训练过程5.5 模型分类效果(PC端) 6 构建垃圾…

vmware安装win10及ubuntu

安装win10 新建一个文件夹 选择刚才创建的文件夹 选择需要保存文件的位置&#xff0c;还是选择刚才创建的文件夹 选择自定义硬件 选择下载的win10镜像iso文件,导入后&#xff0c;点击完成即可 接下来就是下一步 没有此电脑&#xff0c;可以点击个性化-》主题-》桌面设置…

杰发科技AC7840——CAN通信简介(4)_过滤器设置

0. 简介 注意&#xff1a;过滤器最高三位用不到&#xff0c;因此最高位随意设置不影响过滤器。 1. 代码分析 注意设置过滤器数量 解释的有点看不懂 详细解释...也看不大懂 Mask的第0位是0&#xff0c;其他位都是1(就是F?)&#xff0c;那就指定了接收值就是这个数&#xff0c;…

专业140+总分410+北京理工大学826信号处理导论考研经验北理工电子信息通信工程,真题,参考书,大纲。

今年考研专业课826信号处理导论&#xff08;信号系统和数字信号处理&#xff09;140&#xff0c;总分410&#xff0c;顺利上岸&#xff01;回看去年将近一年的复习&#xff0c;还是记忆犹新&#xff0c;有不少经历想和大家分享&#xff0c;有得有失&#xff0c;希望可以对大家复…

JVM虚拟机(四)年轻代中的 S0区、S1区和 from区、to区有什么区别?

目录 一、知识回顾二、from区和 to区的交换三、总结 一、知识回顾 什么是年轻代&#xff1f; 年轻代&#xff1a;是 JVM 堆内存中专门用于存储新创建对象的部分&#xff0c;旨在高效处理大量短时间内可能被回收的对象。 年轻代有哪几部分&#xff1f; Eden区&#xff1a;年轻…

【opencv】示例-stereo_match.cpp 立体匹配:通过对左右视图图像进行处理来生成视差图和点云数据...

/** stereo_match.cpp* calibration** 创建者 Victor Eruhimov&#xff0c;日期为 2010年1月18日。* 版权所有 2010 Argus Corp.**/#include "opencv2/calib3d/calib3d.hpp" // 导入OpenCV相机标定和三维重建相关的头文件 #include "opencv2/imgproc.hpp&qu…

【机器学习300问】67、均方误差与交叉熵误差,两种损失函数的区别?

一、均方误差&#xff08;Mean Squared Error, MSE&#xff09; 假设你是一个教练&#xff0c;在指导学生射箭。每次射箭后&#xff0c;你可以测量子弹的落点距离靶心的差距&#xff08;误差&#xff09;。MSE就像是计算所以射击误差的平方后的平均值。它强调了每一次偏离靶心的…

CSS 实现视差滚动效果

一、是什么 视差滚动&#xff08;Parallax Scrolling&#xff09;是指多层背景以不同的速度移动&#xff0c;形成立体的运动效果&#xff0c;带来非常出色的视觉体验 我们可以把网页解刨成&#xff1a;背景层、内容层、悬浮层 当滚动鼠标滑轮的时候&#xff0c;各个图层以不…

python中的列表、元组、字典、集合(元组篇)

数据类型定义符号访问元素是否可变是否重复是否有序列表 [ ]索引可变可重复有序元组&#xff08;&#xff09;索引不可变可重复有序字典{key&#xff1a;value}键可变可重复无序集合{ }可变不可重复无序 在形式上&#xff0c;元组的所有元素放在一对圆括号中&#xff0c;元素之…

发布 Chrome/Edge浏览器extension扩展到应用商店

Chrom Extension发布流程 创建和发布自定义 Chrome 应用和扩展程序&#xff1a;https://support.google.com/chrome/a/answer/2714278?hlzh-Hans 在 Chrome 应用商店中发布&#xff1a;https://developer.chrome.com/docs/webstore/publish?hlzh-cn 注册开发者帐号&#…

C# Solidworks二次开发:相机访问相关API详解

大家好&#xff0c;今天要介绍的API为相机相关的API&#xff0c;这篇文章比较适合女孩子&#xff0c;学会了相机就会拍照了&#xff0c;哈哈。 下面是要介绍的API: &#xff08;1&#xff09;第一个为GetFocalDistance&#xff0c;这个API的含义为获取相机的焦距&#xff0c;…

OLTP 与 OLAP 系统说明对比和大数据经典架构 Lambda 和 Kappa 说明对比——解读大数据架构(五)

文章目录 前言OLTP 和 OLAPSMP 和 MPPlambda 架构Kappa 架构 前言 本文我们将研究不同类型的大数据架构设计&#xff0c;将讨论 OLTP 和 OLAP 的系统设计&#xff0c;以及有效处理数据的策略包括 SMP 和 MPP 等概念。然后我们将了解经典的 Lambda 架构和 Kappa 架构。 OLTP …

微信小程序 发送消息 Token校验失败,请检查确认

如上图&#xff0c;文档中说的是 开发者通过检验 signature 对请求进行校验&#xff08;下面有校验方式&#xff09;。若确认此次 GET 请求来自微信服务器&#xff0c;请原样返回 echostr 参数内容&#xff0c;则接入生效&#xff0c;成为开发者成功&#xff0c;否则接入失败。…

bugku-web-decrypt

这里的提示解密后没有什么意义 这里下载文件包 得到一个index.php文件 得到代码 <?php function encrypt($data,$key) {$key md5(ISCC);$x 0;$len strlen($data);$klen strlen($key);for ($i0; $i < $len; $i) { if ($x $klen){$x 0;}$char . $key[$x];$x1;}for…

STM32之DHT11温湿度传感器

目录 一 DHT11温湿度传感器简介 1.1 传感器特点 1.2 传感器特性 1.3 传感器引脚说明 二 测量原理及方法 2.1 典型应用电路 2.2 单线制串行简介 2.2.1 串行接口 (单线双向) 2.2.2 数据示例 2.3 通信时序 三 单片机简介 3.1 STM32F103C8T6最小系统板 四 接线说明 …

【系统分析师】计算机网络

文章目录 1、TCP/IP协议族1.1 DHCP协议1.2 DNS协议1.3网络故障诊断 2、网路规划与设计2.1逻辑网络设计2.2物理网络设计2.3 分层设计 3、网络接入3.1 接入方式3.2 IPv6地址 4、综合布线技术5、物联网5.1物联网概念与分层5.2 物联网关键技术 6、云计算7、网络存储技术&#xff08…

Unity 中消息提醒框

Tooltip 用于ui布局 using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.UI;[ExecuteInEditMode()] // 可以在编辑模式下运行public class Tooltip : MonoBehaviour {public TMP_Text header; // 头部文本publi…

【opencv】示例-stiching_detailed.cpp 使用OpenCV进行图像拼接的整体流程

#include <iostream> // 引入输入输出流库 #include <fstream> // 引入文件流库&#xff0c;用于文件输入输出 #include <string> // 引入字符串库 #include "opencv2/opencv_modules.hpp" // 引入OpenCV模块 #include <opencv2/core/utility.h…

Spring Boot(二)— 自定义Spring Boot Starter

在Spring Boot中&#xff0c;自定义Spring Boot Starter是一个常见且强大的功能&#xff0c;它允许开发者为特定的功能或库创建自己的自动配置&#xff0c;从而简化集成过程。 1 前置知识 Spring Boot的事件为应用的启动和关闭提供了详细的上下文信息&#xff0c;使得开发者能…