首页 > 其他分享 >【FPGA项目】沙盘演练——基础版报文收发

【FPGA项目】沙盘演练——基础版报文收发

时间:2023-09-14 22:56:32浏览次数:44  
标签:沙盘演练 输出 FPGA clk 报文 时序 输入 out

第1个虚拟项目

1. 前言

点灯开启了我们的FPGA之路,那么我们来继续沙盘演练。

用一个虚拟项目,来入门练习,以此步入数字逻辑的大门。

Key Words:FIFO 、SOF 、EOF、计数器、缓存、时序图、方案设计

2. 项目要求

1) 输入报文长度64~2048字节;

2) 输入报文之间最小间隔为两拍;

3) 输出报文的前两拍添加16bit报文长度信息;第1拍为报文长度高8位;第2拍为报文长度低8位;第3拍开始为输入报文;

信号

I/O

位宽

描述

系统接口信号

i_sys_clk

I

1

系统时钟,125Mhz

i_rst_n

I

1

硬复位,低有效

输入接口信号

i_sop_in

I

1

输入报文头指示信号,高有效

i_eop_in

I

1

输入报文尾指示信号,高有效

i_vld_in

I

1

输入报文数据有效信号,高有效

i_data_in

I

8

输入报文数据

输出接口信号

o_sop_out

O

1

输出报文头指示信号,高有效

o_eop_out

O

1

输出报文尾指示信号,高有效

o_vld_out

O

1

输出报文数据有效信号,高有效

o_data_out

O

8

输出报文数据

 

输入接口时序

 

 

输出接口时序

 

 

3. 项目方案设计

3.1. 项目需求

1) 输出报文;

2) 输出报文长度;

3) 报文与报文长度输出满足时序要求;

3.2. 项目方案

1) 要求输出报文,且报文输出在报文长度输出之后,所以需要先对输入报文进行缓存,根据输入报文的位宽和长度范围,此处选择合适的同步FIFO即可;(如果是IC,那么就需要自己写FIFO,可以参考本博客的FIFO介绍)

² 这里项目提出了第1个要求,掌握FIFO的使用。

2) 要求输出报文长度,所以需要对输入报文长度进行计数,并将其缓存;

² 此处有坑,若只用寄存器对长度进行缓存,存在被后续报文长度覆盖的风险,故需要第2个FIFO对报文长度进行缓存。

3) 要求先输出报文长度然后紧跟着输出报文,此处需要对时序进行设计,需要掌握FIFO的读写时序,需要理解fpga的时钟沿采样。

² 理解:时钟沿采样及数据下一时钟沿变化。

3.3. 项目代码

 

module zmj0001(
    input             sys_clk,
    input             rst_n,
    
    input            sop_in,
    input             eop_in,
    input             vld_in,
    input    [7:0]    data_in,
    
    output             sop_out,
    output            eop_out,
    output            vld_out,
    output     [7:0]     data_out
    );

 

FPGA项目沙盘演练-基础版报文收发(vivado2017.4)资源-CSDN文库

当然这不是唯一的设计方案,可以先自行考虑设计及验证。

项目重难点:

  1. FIFO的使用及时序的设计
  2. 考虑包间隔2 clk cycle
  3. 考虑长包+超短包的情况

时序设计可以用TimingDesigner软件,简单易用,需要的可以下载。

3.4. 仿真验证

可以使用计数器来产生数据源data_in;

 

`timescale 1ns / 1ps
 
module zmj0001_tb();
 
reg                    sys_clk                ;
reg                    rst_n                ;
reg     [7    :0]        data_in                ;
reg                    vld_in                ;
reg                    sop_in                ;
reg                    eop_in                ;
reg        [11    :0]        cnt                    ;                                    
wire                 sop_out              ;
wire                 eop_out             ;
wire                vld_out             ;
wire     [7:0]         data_out            ;
 
initial
begin
    sys_clk        =    0;
    rst_n        =    0;
    #100
    rst_n        =    1;
end
always #5    sys_clk    =    ~sys_clk;    //100Mhz
//用计数器来产生data_in
always @(posedge    sys_clk    or    negedge    rst_n)begin
    if(~rst_n)
        cnt                <=        12'b0;
    else if(cnt > 2048)
        cnt                <=        cnt;
    else
        cnt                <=        cnt    +    12'b1;
end
always @(posedge    sys_clk    or    negedge    rst_n)begin
    if(~rst_n)begin
        data_in            <=        8'b0;
        sop_in            <=        1'b0;
        eop_in            <=        1'b0;
        vld_in            <=        1'b0;
        end
    else begin
        data_in            <=        8'b0;
        sop_in            <=        1'b0;
        eop_in            <=        1'b0;
        vld_in            <=        1'b0;
        if((cnt > 'd10  &&   cnt  <=  'd60)|(cnt > 'd68  &&   cnt  <=  'd668))begin
            data_in        <=        data_in + 1'b1;
            vld_in        <=        1'b1;
            end
        if((cnt == 'd11)|(cnt == 'd69))
            sop_in        <=        1'b1;
        if((cnt == 'd60)|(cnt == 'd668))
            eop_in        <=        1'b1;
        if((cnt == 'd62) | (cnt == 'd63))begin  //63  66
            data_in        <=        data_in + 1'b1;
            vld_in        <=        1'b1;
            sop_in         <=         1'b1;
            eop_in         <=         1'b1;
            end
        
        end
end    
zmj0001        u_zmj0001(
    .sys_clk            (sys_clk   ),    
    .rst_n              (rst_n     ),
                                     
    .sop_in             (sop_in    ),
    .eop_in             (eop_in    ),
    .vld_in             (vld_in    ),
    .data_in            (data_in   ),
                                     
    .sop_out            (sop_out   ),
    .eop_out            (eop_out   ),
    .vld_out            (vld_out   ),
    .data_out           (data_out  )
    );
 
endmodule

 

 

具体modelsim使用及与vivado的联合仿真,脚本编写请参考其他博文,后续FPGA其他专栏再考虑写相关内容。

输入:

共4包数据,长包+超短包+超短包+长包,包间隔均为2clk cycle

data_in : 第1包:1-50的累加数;第2包:1;第3包:1;

 

 

输出:

 

 

若包间隔<2 clk?

输入:

 

 

输出:

 

 

可以看到,本设计甚至支持背靠背的超短包输入。

4. 项目收获

  1. 方案设计的重要性:任何项目都是始于方案设计,前期需要花大量的功夫去理清思路,方案设计完成,代码实现只不过是水到渠成的事情。
  2. 仿真的学习:通过本项目,完成了testbench的编写,仿真验证,是对自己设计的一次检验,是实际项目缩短调试时间的最佳利器。
  3. 对xilinx IP的使用,对datasheet的阅读学习。
  4. 对时序的理解,时钟是FPGA的心跳:任何时序操作都是发生在时钟的跳变沿。当采样发生在当前上升沿时刻,数据变化是发生在下一时刻的上升沿。
  5. 绘画时序图,TimingDesigner的使用。有了时序图,代码就很容易实现了。

 

5. 进阶考虑

本次虚拟项目旨在用最简单的例子带大家了解数字逻辑设计的一些基本概念,所以很多东西是没有考虑的。比如:

  1. 如果包间隔小于2个时钟周期怎么办? -----握手与反压
  2. 如果输入数据有错误怎么办? -----CRC校验
  3. 如果需要跨时钟域传输呢? -----CDC处理
  4. 报文只是简单转发,如果需要做处理呢?-----数据处理
  5. ...

 

所以,下一篇将沿着这个思路展开,进阶版的虚拟项目,同样可以作为公司的入职培训。

咱们下期见!

 

 

 

 

标签:沙盘演练,输出,FPGA,clk,报文,时序,输入,out
From: https://www.cnblogs.com/zimoji/p/17703739.html

相关文章

  • FPGA 设计一个以1秒频率闪烁的LED灯
    以1秒频率闪烁的LED灯的代码内容如下://设计一个以1秒频率闪烁的LED灯(亮灭各500ms)moduleled_flash(Reset_n,//复位端口,加_n是使用低电平复位Clk,//时钟端口Led,);inputClk;inputReset_n;outputregLed;reg[24:0]counter;......
  • Lattice下载器高速编程器HW-USBN-2B fpga仿真器ispdown烧录器
    1.概述       HW-USBN-2B编程烧录Lattice所有芯片,速度非常快。支持LatticeFPGA芯片在线稳定仿真、烧录、加密,支持LatticeCPLD烧录。支持外部配置FLASH、PROM配置烧录。    HW-USBN-2B,特点是很快的速度,30Mb/s,是HW-USBN-2A的下载速度10速度。并且支持I2C接口......
  • FPGA 3-8译码器
    moduledecoder_3_8_test(a,b,c,out);inputa;inputb;inputc;outputreg[7:0]out;always@(*)begincase({a,b,c})3'b000:out=8'b0000_0001;3'b001:out=8&#......
  • xilinx赛灵思下载器jtag-hs3兼容alinx仿真fpga烧录digilent高速常见问题解答
    1.概述  XJTAG-HS3是XILINX的USB转JTAG的高速仿真器,可以下载、烧录和仿真Xilinx FPGA和CPLD芯片,以及配置PROM、FLASH. XJTAG-HS3比PlatformCableUSBII下载器快10倍速度。 可以在30Mbit/秒下驱动JTAG/SPI总线,并且能实现对XilinxZYNQ平台处理器核的重置。可以支持ZYN......
  • 通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置
    1.算法理论概述       通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置是一种常见的应用场景,用于实现对显示器中目标位置的控制。该系统利用FPGA芯片作为主控制器,通过RS232串口与计算机或其他设备进行通信,接收指令并解析,然后控制显示器中目标位置的移动。该......
  • 米联客 2024 版 FPGA 课程快速入口课程-目录速览(网页版没有页码)
    目录米联客2024版FPGA课程快速入口课程    101AMDFPGAvitis-vivado软件快速入门课程    91概述    92新建VIVADO工程    93添加代码管理文件夹    124添加PLLIP核    125新建工程文件    186完善RTL代码    227添加管脚约束......
  • 为什么EDI工作流中围绕XML做EDI报文数据解析/生成?
    经常有客户问起,为什么在处理EDI文件时不一次到位,而需要使用多个端口来分次进行处理呢,是不是想要多占用几个端口好多卖钱呀?实际上,在一开始的知行EDI产品中,功能还没有这么完善,当时只支持EDI常见的传输协议,那个时候我们在做报文翻译时,还不能仅通过简单的配置来实现,需要手写代码,去读......
  • 有关交换机内部报文转发和ACL控制的原理
    交换机内部的报文在VLAN间的转发是由交换机的三层转发引擎(L3ForwardingEngine)完成的。三层转发引擎是交换机的一种功能模块,它可以根据报文的目的IP地址和交换机的路由表,选择最佳的下一跳地址,并将报文转发到相应的VLAN接口。交换机内部的报文在VLAN间的转发是否受到ACL(AccessC......
  • 基于SMQ7VX690T FPGA +FT-6678 DSP 6U VPX双FMC载板
    概要QT7041G-DSP是一款基于6UVPX架构,主体芯片采用国微SMQ7VX690T芯片作为主处理器、1片银河飞腾DSP处理器FT-6678做为协处理芯片的6UVPX标准双FMC载板。可对外部传入的数据处理分析,具备强大的运算能力。 可用于软件无线电系统,基带信号处理,无线仿真平台,高速图像采集、处理等......
  • K7 325T PXIe x8 FPGA载板
    概要QT7050是一款基于PXIe总线的3U通用载板,板载一个HPC形式的FMC连接器。板卡选用高性价比的Kintex-7系列FPGA处理芯片XC7K325T-FFG900,板载2组2GBDDR3SDRAM内存,支持1个MicroUSB转接UART口,1个MicroUSB转JTAG或者1个14pin的插针式JTAG接口,提供1个SMA形式的GPIO或者RF输入接口,一......