• FPGA杂记


    FPGA部分
    2021年10月11日
    (1)D触发器的Q是在D端数据到达后下一个时钟上升沿输出
    (2) (*ram_style="distributed"*)   reg  [0:31]  MyMem [0:7];
    定义了7个32bit长度的数组, 这里的内存可以使用FPGA的分布式 RAM实现,也可以使用BRAM来实现,取决于关键词
    distributed或者 block
    (3)可以使用`define以及`ifdef以及`endif等指令
    `define Y;
    `ifdefY
    Z=1;
    `else
    Z=0;
    `endif
    (4)clk信号的写法
    时钟激励产生方法一:50%占空比时钟
    ----------------------------------------------------------------*/
    parameter ClockPeriod=10;
    initial begin
        clk_i=0;
        forever
        #(ClockPeriod/2) clk_i=~clk_i;
    end
    /*----------------------------------------------------------------
    时钟激励产生方法二:50%占空比时钟
    ----------------------------------------------------------------*/
    initial begin
        clk_i=0;
    end
    always #(ClockPeriod/2) clk_i=~clk_i;
    /*----------------------------------------------------------------
    时钟激励产生方法三:产生固定数量的时钟脉冲
    ----------------------------------------------------------------*/
    initial begin
        clk_i=0;
        repeat(6)
        #(ClockPeriod/2) clk_i=~clk_i;
    end
    /*----------------------------------------------------------------
    时钟激励产生方法四:产生非占空比为50%的时钟
    ----------------------------------------------------------------*/
    initial begin
        clk_i=0;
        forever begin
            #((ClockPeriod/2)-2)clk_i=0;
            #((ClockPeriod/2)+2)clk_i=1;
        end
    end
    (5)复位信号怎么写
    /*----------------------------------------------------------------
    复位信号产生方法一:异步复位
    ----------------------------------------------------------------*/
    initial begin
        rst_n_i=1;
        #100;
        rst_n_i=0;
        #100;
        rst_n_i=1;
        end
    /*----------------------------------------------------------------
    复位信号产生方法二:同步复位
    ----------------------------------------------------------------*/
    initial begin
        rst_n_i=1;
        clk_i=0;
        @(negedge clk_i) rst_n_i=0;
        #100;//固定时间复位
        repeat(10) @(negedge clk_i);//固定周期数复位
        @(negedge clk_i)
        rst_n_i=1;
    end
    always #5 clk_i=~clk_i;
    /*----------------------------------------------------------------
    复位信号产生方法三:复位任务封装
    ----------------------------------------------------------------*/
    task reset;
        input [31:0] reset_time;//复位时间可调,输入复位时间
        RST_ING=0;//复位方式可调,低电平或高电平
        begin
            rst_n=RST_ING;//复位中
            #reset_time;//复位时间
            rst_n=~RST_ING;//撤销复位,复位结束
        end
    endtask
    (6)双向信号inout
        如果inout在testbench中定义为wire型变量(表示输出),使用force来进行初始化的操作。
        如果待测试文件中存在双向信号(inout)需要注意,需要一个 reg变量 来表示输入,一个 wire变量 表示输出;
    双向信号描述:强制force
    ----------------------------------------------------------------*/
    //当双向端口作为输出口时,不需要对其进行初始化,而只需开通三态门;当双向端口作为输入时,只需要对其初始化并关闭三态门,初始化赋值需
    使用wire型数据,通过force命令来对双向端口进行输入赋值
    assign dinout=(!en)din:16'hz;完成双向赋值
    initial begin
        force dinout=20;
        #200
        force dinout=dinout-1;
    end
    (7)触发的两种   @是沿出发,而wait则是电平触发的一种方式。
    //@使用沿触发
    //wait语句都是使用电平触发
    initial begin
        start=1'b1;
        wait(en==1'b1);  //wait使用电平触发的机制
        #10;
        start=1'b0;
    end
    (8)仿真控制语句及系统任务描述
    /*----------------------------------------------------------------
    仿真控制语句及系统任务描述
    ----------------------------------------------------------------*/
    $stop            //停止运行仿真,modelsim中可继续仿真
    $stop(n)         //带参数系统任务,根据参数0,1或2不同,输出仿真信息
    $finish          //结束运行仿真,不可继续仿真
    $finish(n)       //带参数系统任务,根据参数0,1或2不同,输出仿真信息
                     //0:不输出任何信息
                     //1:输出当前仿真时刻和位置
                     //2:输出当前仿真时刻、位置和仿真过程中用到的memory以及CPU时间的统计
    $random          //产生随机数
    $random%n        //产生范围-n到n之间的随机数
    {$random}%n      //产生范围0到n之间的随机数
    /*----------------------------------------------------------------
    仿真终端显示描述
    ----------------------------------------------------------------*/
    $monitor        //仿真打印输出,打印出仿真过程中的变量,使其终端显示,如果发生了变化就会输出一次
    /*
            $monitor($time,,,"clk=%d reset=%d out=%d",clk,reset,out);
    */
    $display        //终端打印字符串,显示仿真结果等
    /*
            $display(”Simulation start!");
            $display(”At time %t,input is %b %b %b,output is %b",$time,a,b,en,z);
    */
    $time         //返回64位整型时间
    $stime        //返回32位整型时间
    $realtime     //实行实型模拟时间
    /*----------------------------------------------------------------
    文本输入方式:$readmemb / $readmemh
    ----------------------------------------------------------------*/
    //激励具有复杂的数据结构
    //verilog提供了读入文本的系统函数
    $readmemb/$readmemh("<数据文件名>",<存储器名>);
    $readmemb/$readmemh("<数据文件名>",<存储器名>,<起始地址>);
    $readmemb/$readmemh("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);
    $readmemb:/*读取二进制数据,读取文件内容只能包含:空白位置,注释行,二进制数
    数据中不能包含位宽说明和格式说明,每个数字必须是二进制数字。*/
    $readmemh:/*读取十六进制数据,读取文件内容只能包含:空白位置,注释行,十六进制数
    数据中不能包含位宽说明和格式说明,每个数字必须是十六进制数字。*/
    /*当地址出现在数据文件中,格式为@hh...h,地址与数字之间不允许空白位置,可出现多个地址*/
    //例子
    module
    reg[7:0]memory[0:3];//声明4个8位存储单元
    integer i;
    initial begin
        $readmemh("D:/mem.dat",memory);//读取系统文件到存储器中的给定地址,mem.dat路径可以给出绝对地址
        //显示此时存储器内容
        for(i=0;i<4;i=i+1)
            $display("Memory[%d]=%h",i,memory[i]);
        end
    endmodule
    /*mem.dat文件内容
    @001          //到第一个地址的位置,那么默认的地址 @0000 为XX 未知态
    AB CD         //@0001 AB 
    @003          //@0002 CD
    A1            //@0003 A1
    */
    //仿真输出为
    Memory[0]=xx;
    Memory[1]=AB;
    Memory[2]=CD;
    Memory[3]=A1;
    2021年10月12日
    (9)对于zu的差分时钟原语,可以使用 IBUFGDS来产生时钟信号,它相比较于IBUFDS,是xilinx的专用时钟信号转换。
    //对差分时钟使用IBUFGDS IP核去进行转换
    IBUFGDS CLK_U(
        .I(diff_clock_clk_p),
        .IB(diff_clock_clk_n),
        .O(CLK_i)
    );
    (10)对于ZYNQUltarScale+为了减少bit文件大小,提高加载速度,在管脚约束文件中添加如下代码
    #bitcompress 比特流压缩
    set_property BITSTREAM.GENERAL.COMPRESS true[current_design]
    备注:
    如果你是 ZYNQ的FPGA,由于ZYNQ的FLASH不是通过FPGA加载的,而是通过ARM,那么只要以下几行代码:
    set_property CFGBVS VCCO [current_design]
    set_property CONFIG_VOLTAGE 3.3 [current_design]
    set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
    如果你是 ZYNQUltarScale+的FPGA,那么只要以下几行代码:
    set_property BITSTREAM.GENERAL.COMPRESS true[current_design]
    (11)怎么写XDC文件?
    set_property   IOSTANDARD   LVCMOS12        [get_ports ]
    set_property   PACKAGE_PIN                  [get_ports ]
    时钟约束的模板如下,单位为ns:
    create_clock    -name    -period      [get_ports]  
    create_clock -name sys_clk -period 8 [get_ports diff_clock_clk_p]
    set_property IOSTANDARD LVDS [get_ports diff_clock_clk_p]
    set_property IOSTANDARD LVDS [get_ports diff_clock_clk_n]
    set_property PACKAGE_PIN H9 [get_ports diff_clock_clk_p]
    set_property PACKAGE_PIN G9 [get_ports diff_clock_clk_n]
    set_property IOSTANDARD LVCMOS12 [get_ports RST_i]
    set_property PACKAGE_PIN AL10 [get_ports RST_i]
    set_property IOSTANDARD LVCMOS12 [get_ports {LED_o[0]}]
    set_property PACKAGE_PIN AL11 [get_ports {LED_o[0]}]
    set_property IOSTANDARD LVCMOS12 [get_ports {LED_o[1]}]
    set_property PACKAGE_PIN AL13 [get_ports {LED_o[1]}]
    set_property BITSTREAM.GENERAL.COMPRESS true[current_design]
    (12)程序的固化
                                                                                                                                                                                                                                                                                                                                                                                                                     
    (13)输出时钟源的种类
        DPLL时钟源     是DDR的PLL产生的
        APLL时钟源     是APU的PLL产生的
        RPLL时钟源     是RPU的PLL产生的
        IOPLL时钟源    是IO的PLL产生的
        VPLL时钟源     是DP的PLL产生的
    (14) IRQ的全称是“ Interupt ReQuest"
    如果图片上的IRQ0为1,那么在zynq的ip核上就会有一个 pl到ps的中断请求信号
    (15)vitis中,在 lscript.ld中可以看到代码、数据、堆栈运行所在的内存情况。
    (16)运行Hello world成功后的现象如下图所示
    但是会有一行  PMU-FW  is not running,certain  applications  may  not  be  supported.
    PMU(PlatformManagementUnit)的作用:  用于电源检测、错误管理、为功能安全应用程序 执行可选的软件测试库(STL)
    怎么去增加这个呢?
    (使用SD或者QSPI都会报错……)
    (17)vitis 如果需要 调试fsbl,以发现fsbl启动过程中的故障,让fsbl输出打印的调试信息,只需要修改 xfsbl_config.h 中的宏定义如下图设置为
    然后需要重新编译zu_base以及产生新的boot.bin。 (会报错……)
    (18)怎么增加代码的 ILA在线逻辑分析仪
       先在变量前加上 (*mark_debug ="true"*)
    再综合后打开逻辑分析仪
    在上面的逻辑分析仪中,可以选择 ILA Core Options设置, Sample of data depth(采样的深度)大小是2048,并且用 Capture control(以自己设置的捕获信号去捕获)
    在线逻辑分析仪的采样深度,使用的是FPGA的BRAM,以及设置Captrue control,对于这种超慢信号, XILINX的在线逻辑分析低于20M采样速度的,波形窗口就不会显示波形,这个XILINX也没有特别说明过,但是 通过设置Captrue control,可以用我们这里的en_10ms来作为扑捉控制,而采样时钟依然用系统时钟。
    Captrue mode设置为BASIC
    (BASIC是以自己设定的capture信号来捕捉的,如果是always,那么就跟这里设置的capture setup没有关系了)
    Window  data  depth为采样深度设置为2048
    Trigger position in  window设置为1024
    2021年10月13日
    (19) 3分频的本质是我们需要在每次1.5倍的时钟周期的时候实现3分频寄存器的翻转,但是我们无法直接实现1.5 倍的分频。因此采取分别采取2个计数器pos_cnt和neg_cnt,分别对上升沿和下降沿计数。计数周期是0-1-2,共 计3个时钟周期。我们取pos_cnt==2’d1的时候div3_o_r0输出高电平,neg_cnt==2’d1的时候div3_o_r1输出高电 平。由于div3_o_r0和div3_o_r1输出1个时钟的高电平,但是相位相差180°,因此只要执行div3_o=div3_o_r0| div3_o_r1运算,就能实现1.5倍周期的输出高电平,那么剩余的1.5倍源时钟周期就是输出低电平了。
    reg [1:0] pos_cnt;
    reg [1:0] neg_cnt;
    always @(posedge clk_i) begin
        if(rst_i)
            pos_cnt<=2'b00;
        else if(pos_cnt==2'd2)
            pos_cnt<=2'b00;
        else
            pos_cnt<=pos_cnt+1'b1;
    end
    always @(negedge clk_i) begin
        if(rst_i)
            neg_cnt<=2'b00;
        else if(neg_cnt==2'd2)
            neg_cnt<=2'b00;
        else
            neg_cnt<=neg_cnt+1'b1;
    end
    reg div3_o_r0;
    reg div3_o_r1;
    always @(posedge clk_i) begin
        if(rst_i)
            div3_o_r0<=1'b0;
        else if(pos_cnt<2'd1)
            div3_o_r0<=1'b1;
        else
            div3_o_r0<=1'b0;
    end
    always @(negedge clk_i) begin
        if(rst_i)
            div3_o_r1<=1'b0;
        else if(neg_cnt<2'd1)
            div3_o_r1<=1'b1;
        else
            div3_o_r1<=1'b0;
    end
    assign  div3_o = div3_o_r0 |  div3_o_r1;
    如图所示,就一个三倍频的时钟。
    (20)怎么去读取pl端的DDR4、BRAM,米联客的技术是需要 使用一个IP核 FDMA
    读取BRAM的设计如下图所示,但是 最后读取BRAM还是失败了
    2021年10月14日
    (21) IDELAYCTRL的计算
    (22)在代码里面写ila可以使用generate语句,其中DEBUG_ENABLE语句可以作为module的一个parameter来使用。
    generate if(DEBUG_ENABLE==1'b1)begin:debugcore
    //添加ilaIP,Chipscope观察信号
    ila_0 ila_debug(
        .clk(sysclk_i),//inputwireclk
        .probe0({plus_20us,pwm_o})//inputwire[1:0]probe0
    );
    end
    endgenerate
    (23) 怎么保存波形文件 一般保存为WDB(sim里面)跟WCFG
    1.点击Vivado的菜单栏中的 Flow -> Open Static simulation,然后选中之前保存的 .WDB 文件即可。
    2. 点击Vivado的菜单栏中的 File -> Open Waveform Configuration,选择我们之前保存的 .WCFG文件即可恢复上一次的仿真结果
    2021年10月18日
    (24) 用AXI-Lite来构建了数据发送以及GPIO来控制pl端的led灯去点亮都实验成功了!!!
    (25)new project summary
    xczu7ev-ffvc 1156-2-e
    (26) ILA有一种分类叫做 System ILA IP ,用这个东西可以实现对Post-implemented的设计进行分析和调试(参见ug908-page170)。按照ug908这个说明,system ila应该放到 ip block design 里面才对。
    System ILA debug可以直连AXI协议。连上AXI协议接口线之后,Waveform的窗口会显示每个接口的连线信号,事件。如果有不止一个AXI连到一个ILA上面,各个AXI会以几个不同的slot展现出来。每个slot都会显示各个AXI接线上相关的Read,Write,Address events和Data channel evets。
    (27)vitis的使用方案
    2021年10月20日
    (28)怎么使用XAPP例程
    先下载,修改启动版本,再使用vivado的tcl版本进行运行,启动GUI版本来执行代码。
    vivado -source pl_eth_sgmii.tcl
    (29)自定义的AXI4总线需要定义地址  大概在xparameters文件中的410地址的位置处。
    2021年10月21日
    (30)BRAM的IP核深度怎么去计算
    (31)AXI GPIO
    如果没有点击All  outputs,会有三个数值出现:
    如果点击了All outputs,就会只有一个数值出现。
    2021年10月22日
    (32) FDMA波形图如下图所示:
    fdma是米联客自己做的一个ip,用来读取DDR非常的方便,里面已经有封装好的ip可以去调用来使用的。
  • 相关阅读:
    [iOS]-Block
    如何安装docker,scrapingslash
    深入解析Rivest Cipher 4:理论与实践
    iic驱动oled屏幕显示温湿度基于FreeRTOS实现多任务
    AI房产户型图识别3DRender
    科普达人丨一文看懂阿里云的秘密武器“神龙架构”
    门票赠送:诚邀您参加2023百度世界大会-大模型驱动产业发展论坛
    校园论坛设计(Java)——介绍篇
    设计师必收藏的5个配色网站
    java八股文面试[数据库]——一个B+树中大概能存放多少条索引记录
  • 原文地址:https://blog.csdn.net/qq_38863842/article/details/127759892