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

文章目录

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

前言

上文介绍的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.mfbz.cn/a/554068.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

每日两题1

文章目录 使用最小花费爬楼梯91解码方法 使用最小花费爬楼梯 class Solution { public:int minCostClimbingStairs(vector<int>& cost) {if(cost.size() 2)return min(cost[0],cost[1]);vector<int> dp;dp.reserve(cost.size()1);dp[0] 0;dp[1] 0;for(int i…

Flink KafkaSink分区配置的不同版本对比

Flink KafkaSink分区配置的不同版本对比 在不同版本的Flink中&#xff0c;KafkaSink 分区默认配置方式可能会有一些变化。以下是摘自Flink官方文档不同版本的原文&#xff1a; 1. Flink版本&#xff1a;1.12~1.19 Sink 分区 # 配置项 sink.partitioner 指定了从 Flink 分区到 …

eBay、亚马逊自养号测评如何避免风控账号关联选择合适网络IP环境

在自养号下单中选择适合的网络环境至关重要。经过多次实践与测试&#xff0c;积累了大量的经验&#xff0c;希望能够与大家分享&#xff0c;帮助大家避开陷阱&#xff0c;顺利前行。 市面上的网络环境种类繁多&#xff0c;从纯IP类的Luminati、Rola&#xff0c;到纯环境类的VM…

Redis 的数据结构和内部编码

Redis的 5 种数据类型 Redis 底层在实现上述数据结构的时候&#xff0c;会在源码层面&#xff0c;针对上述实现进行 特定的优化 &#xff0c;来达到节省时间/节省空间效果 特定的优化&#xff1a;内部的具体实现的数据结构&#xff0c;在特定场景下&#xff0c;不是其对应的标准…

ros1 C++ 输出helloworld

1、创建工作空间并初始化 mkdir -p 自定义空间名称/src cd 自定义空间名称 catkin_make运行完&#xff0c;生成文件如下图&#xff1a; 2、进入 src 创建 ros 包并添加依赖 cd src catkin_create_pkg 自定义ROS包名 roscpp rospy std_msgs这里&#xff0c;我的自定义ROS包名…

VUE 页码分页封装

VUE 页码封装组件 pagination/index.vue &#xff1a; <template><div class"pagination-contianer"><el-pagination background layout"prev, pager, next" :total"total" current-change"currentChange"> </e…

SQL255 给出employees表中排名为奇数行的first_name

题目来源&#xff1a; 给出employees表中排名为奇数行的first_name_牛客题霸_牛客网 描述 对于employees表中&#xff0c;输出first_name排名(按first_name升序排序)为奇数的first_name CREATE TABLE employees ( emp_no int(11) NOT NULL, birth_date date NOT NULL, firs…

【服务器部署篇】Linux下Redis安装

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

基于SpringBoot的幼儿园管理系统 免费获取源码

项目源码获取方式放在文章末尾处 项目技术 数据库&#xff1a;Mysql5.7 数据表&#xff1a;16张 开发语言&#xff1a;Java(jdk1.8) 开发工具&#xff1a;idea 前端技术&#xff1a;html 后端技术&#xff1a;SpringBoot 功能简介 项目获取关键字&#xff1a;幼儿园 该…

《大话数据结构》03 线性表

1. 线性表的定义 线性表&#xff1a;零个或多个数据元素的有限序列。 这里需要强调几个关键的地方。 首先它是一个序列。也就是说&#xff0c;元素之间是有顺序的&#xff0c;若元素存在多个&#xff0c;则第一个元素无前驱&#xff0c;最后一个元素无后继&#xff0c;其他每…

基于云计算技术的HIS系统,一体化云HIS、云病历、云LIS系统源码,扩展后能够应用于医联体/医共体

医院信息管理系统云HIS系统源码&#xff0c;云计算技术的HIS系统源码 开发技术&#xff1a; 前端&#xff1a;AngularNginx&#xff1b; 后台&#xff1a;JavaSpring&#xff0c;SpringBoot&#xff0c;SpringMVC&#xff0c;SpringSecurity&#xff0c;MyBatisPlus 等&…

基于ssm校园驿站全天候辅助取货管理系统的设计与实现论文

摘 要 身处网络时代&#xff0c;随着网络系统体系发展的不断成熟和完善&#xff0c;人们的生活也随之发生了很大的变化&#xff0c;人们在追求较高物质生活的同时&#xff0c;也在想着如何使自身的精神内涵得到提升&#xff0c;而读书就是人们获得精神享受非常重要的途径。为了…

DNS服务器的管理与配置

目录 一、相关知识 域名空间 DNS服务器分类 域名解析过程 资源记录 二、安装DNS服务 安装bind软件包 DNS服务的启动与停止 配置主要名称服务器 主配置文件 从例子学起&#xff1a; &#xff08;1&#xff09;建立主配置文件named.conf &#xff08;2&#xff09;…

酒店管理系统

文章目录 酒店管理系统一、项目演示二、项目介绍三、15000字论文参考四、部分功能截图五、部分代码展示六、底部获取项目源码和万字论文参考&#xff08;9.9&#xffe5;带走&#xff09; 酒店管理系统 一、项目演示 酒店管理系统 二、项目介绍 基于springbootvue前后端分离的…

亿级流量系统多级缓存架构6

亿级流量系统多级缓存架构6 服务限流 什么叫限流&#xff1f; Ab测试 yum install httpd-tools即限制流量进入 缓存&#xff0c;是用来增加系统吞吐量&#xff0c;提升访问速度提供高并发。 降级&#xff0c;是在系统某些服务组件不可用的时候、流量暴增、资源耗尽等情况…

宠物店小程序如何搭建制作?宠物店小程序核心功能有哪些?

随着宠物经济的兴起&#xff0c;宠物店的线上服务需求日益增长。微信小程序作为一种便捷的线上服务平台&#xff0c;为宠物店提供了一个与爱宠人士建立联系的新渠道。面对市场上众多的小程序开发选项&#xff0c;宠物店应该如何选择或制作一款适合自己的小程序呢&#xff1f;本…

[spring] Spring Boot REST API - CRUD 操作

Spring Boot REST API - CRUD 操作 这里主要提一下 spring boot 创建 rest api&#xff0c;并对其进行 CRUD 操作 jackson & gson 目前浏览器和服务端主流的交互方式是使用 JSON(JavaScript Object Notation)&#xff0c;但是 JSON 没有办法直接和 Java 的 POJO 创建对应…

【网络运维知识】—路由器与交换机区别

【网络运维知识】—路由器与交换机区别 一、路由器&#xff08;Router&#xff09;和交换机&#xff08;Switch&#xff09;对比1.1 功能1.2 转发方式1.3 范围1.4 处理方式 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 路由器&#xff08…

ShadowFormer:Global Context Helps Images Shadow Removal

本论文主要是对图像阴影去除工作的研究。现有工作都是针对于局部阴影或阴影部分分别进行优化&#xff0c;这就会导致在分界线上有明显不同&#xff08;光照不一致&#xff0c;伪影情况&#xff09;。因此&#xff0c;本文提出一种全局优化算法shandowFormer来解决分界不一致问题…

Springboot+Vue项目-基于Java+MySQL的企业客户管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…
最新文章