查看: 6069|回复: 0

[Perf-V开发板试用]FPGA篇-PWM调亮度Demo&用在线逻辑分析仪测试

[复制链接]
  • TA的每日心情

    2024-10-10 16:16
  • 签到天数: 311 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2019-1-9 02:33:26 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 风之山谷 于 2019-1-9 02:33 编辑

    利用了小时间来写了一段Verilog程序,利用Perf-V开发板上四个轻触按键和四个拔码开关来控制板上四个LED灯的亮度和亮灭。控制LED灯亮度是采用了PWM调制,就是通过控制PWM波的占空比来控制LED的亮度。

    由于会Verilog并不一定能够顺利综合出对应的FPGA,因此在这个过程中调试了好一段时间。在这个程序中用到了Xilinx官方的两个IP核,一个是时钟配置IP核clk_wiz,用这个可以通过FPGA芯片内置的MMCM和PLL对内部所需时钟进行配置(在这里主要是对时钟信号整形)、以及另一个很实用的调试IP核——在线逻辑分析仪ILA(Integrated Logic Analyzer),原理就是通过FPGA内部逻辑综合出一个可以采集内部信号的记录仪,带有触发和数据采集功能,数据采集之后通过USB线把数据传回电脑,实现在线的逻辑分析仪功能。

    主要功能是:拔码开关控制LED亮灭,LED带有四级亮度,点击对应轻触开关即可切换LED亮度,轻触开关带有20ms硬件防抖。
    先贴Verilog代码:
    1. `timescale 1ns / 1ps
    2. //////////////////////////////////////////////////////////////////////////////////
    3. // Company:
    4. // Engineer:
    5. //
    6. // Create Date: 2018/12/24 01:02:35
    7. // Design Name:
    8. // Module Name: LED_PWM_TOP
    9. // Project Name:
    10. // Target Devices:
    11. // Tool Versions:
    12. // Description:
    13. //
    14. // Dependencies:
    15. //
    16. // Revision:
    17. // Revision 0.01 - File Created
    18. // Additional Comments:
    19. //
    20. //////////////////////////////////////////////////////////////////////////////////

    21. module LED_PWM_TOP(clk_in,
    22.                    rst,
    23.                    btn,
    24.                    sw,
    25.                    led
    26. );
    27.   input clk_in,rst;
    28.   input [3:0] btn;
    29.   input [3:0] sw;
    30.   output [3:0] led;
    31.   
    32.   wire clk;
    33.   wire [3:0] led;
    34.   
    35.   clk_wiz_0 U1(clk, rst, clk_in);
    36.   LED_PWM U2(clk, rst, btn, sw, led);
    37.   
    38.                     
    39. endmodule

    40. module LED_PWM(  clk,
    41.                               rst,
    42.                              btn,
    43.                              sw,
    44.                              led
    45. );

    46.         input clk, rst;
    47.         input [3:0]btn;
    48.   input [3:0]sw;
    49.   output [3:0]led;

    50.         reg [16:0] cnt_100ns;
    51.         reg clk_100ns;
    52.   reg [1:0] bri_lev0;
    53.   reg [1:0] bri_lev1;
    54.   reg [1:0] bri_lev2;
    55.   reg [1:0] bri_lev3;
    56.   reg [3:0] led;
    57.   reg [9:0] btn_cnt;
    58.         reg [3:0] btn_pressdown_state;
    59.         reg [3:0] btn_pressdown_check;
    60.         //reg btn_deal_fb;

    61.         reg [2:0] led_state;
    62.         reg [3:0] bri_lev_s1;
    63.         reg [3:0] bri_lev_s2;
    64.         reg [3:0] bri_lev_s3;
    65.   reg [3:0] led_pwm;
    66.   reg btn_sign;
    67.         parameter s0=3'b000, s1=3'b001, s2=3'b010, s3=3'b011, s4=3'b100, s5=3'b101, s6=3'b110, s7=3'b111;

    68. //ILA
    69.   ila_0 U3( .clk(clk_100ns),
    70.             .probe0(btn),
    71.             .probe1(led),
    72.             .probe2(btn_pressdown_check),
    73.             .probe3(bri_lev0)
    74.   );

    75.         //Internal 100ns system clk => clk_100ns
    76.         always@(posedge clk or negedge rst)
    77.                 if(!rst)
    78.                 begin
    79.                         clk_100ns <= 1'b0;
    80.                         cnt_100ns <= 17'b0;
    81.                 end
    82.                 else
    83.                         if( cnt_100ns >= 17'd5_000 )
    84.                         begin
    85.                     clk_100ns <= ~clk_100ns;
    86.                                 cnt_100ns <= 17'b0;
    87.                         end
    88.                         else
    89.                                 cnt_100ns <= cnt_100ns+17'b1;

    90.         //LED state machine
    91.         always@(posedge clk_100ns or negedge rst)
    92.                 if(!rst)
    93.                 begin
    94.                         led_state <= s0;
    95.                         led_pwm <= 4'b0000;
    96.                 end
    97.                 else
    98.                 begin
    99.                         case(led_state)
    100.                                 s0://State 0
    101.                                 begin
    102.                                         led_pwm <= 4'b1111;
    103.                                         led_state <= s1;
    104.                                 end

    105.                                 s1://State 1
    106.                                 begin
    107.                                         led_pwm <= bri_lev_s1;
    108.                                         led_state <= s2;
    109.                                 end

    110.                                 s2://State 2
    111.                                 begin
    112.                                         led_pwm <= bri_lev_s1;
    113.                                         led_state <= s3;
    114.                                 end

    115.                                 s3://State 3
    116.                                 begin
    117.                                         led_pwm <= bri_lev_s1;
    118.                                         led_state <= s4;
    119.                                 end
    120.                                 
    121.                                 s4://State 4
    122.         begin
    123.           led_pwm <= bri_lev_s2;
    124.           led_state <= s5;
    125.         end
    126.         
    127.         s5://State 5
    128.         begin
    129.           led_pwm <= bri_lev_s2;
    130.           led_state <= s6;
    131.         end
    132.         
    133.         s6://State 6
    134.         begin
    135.           led_pwm <= bri_lev_s3;
    136.           led_state <= s7;
    137.         end
    138.                
    139.         s7://State 7
    140.         begin
    141.           led_pwm <= bri_lev_s3;
    142.           led_state <= s0;
    143.         end        
    144.                                 default:;
    145.                         endcase
    146.                 end

    147.                 //Brightness level
    148.                 always@(bri_lev0 or bri_lev1 or bri_lev2 or bri_lev3)
    149.                 begin
    150.                         //case brighness level-0
    151.                         case(bri_lev0)
    152.                                 2'b10:
    153.                                 begin
    154.                                         bri_lev_s2[0] <= 1'b1;
    155.                                         bri_lev_s3[0] <= 1'b0;
    156.                                 end
    157.                                 2'b11:
    158.                                 begin
    159.                                         bri_lev_s2[0] <= 1'b1;
    160.                                         bri_lev_s3[0] <= 1'b1;
    161.                                 end
    162.                                 default:
    163.                                 begin
    164.                                         bri_lev_s2[0] <= 1'b0;
    165.                                         bri_lev_s3[0] <= 1'b0;
    166.                                 end
    167.                         endcase

    168.                         //case brightness level-1
    169.                         case(bri_lev1)
    170.                                 2'b10:
    171.                                 begin
    172.                                         bri_lev_s2[1] <= 1'b1;
    173.                                         bri_lev_s3[1] <= 1'b0;
    174.                                 end
    175.                                 2'b11:
    176.                                 begin
    177.                                         bri_lev_s2[1] <= 1'b1;
    178.                                         bri_lev_s3[1] <= 1'b1;
    179.                                 end
    180.                                 default:
    181.                                 begin
    182.                                         bri_lev_s2[1] <= 1'b0;
    183.                                         bri_lev_s3[1] <= 1'b0;
    184.                                 end
    185.                         endcase

    186.                         //case brightness level-2
    187.                         case(bri_lev2)
    188.                                 2'b10:
    189.                                 begin
    190.                                         bri_lev_s2[2] <= 1'b1;
    191.                                         bri_lev_s3[2] <= 1'b0;
    192.                                 end
    193.                                 2'b11:
    194.                                 begin
    195.                                         bri_lev_s2[2] <= 1'b1;
    196.                                         bri_lev_s3[2] <= 1'b1;
    197.                                 end
    198.                                 default:
    199.                                 begin
    200.                                         bri_lev_s2[2] <= 1'b0;
    201.                                         bri_lev_s3[2] <= 1'b0;
    202.                                 end
    203.                         endcase

    204.                         //case brightness level-3
    205.                         case(bri_lev3)
    206.                                 2'b10:
    207.                                 begin
    208.                                         bri_lev_s2[3] <= 1'b1;
    209.                                         bri_lev_s3[3] <= 1'b0;
    210.                                 end
    211.                                 2'b11:
    212.                                 begin
    213.                                         bri_lev_s2[3] <= 1'b1;
    214.                                         bri_lev_s3[3] <= 1'b1;
    215.                                 end
    216.                                 default:
    217.                                 begin
    218.                                         bri_lev_s2[3] <= 1'b0;
    219.                                         bri_lev_s3[3] <= 1'b0;
    220.                                 end
    221.                         endcase

    222.                         //bri_lev_s1
    223.                         bri_lev_s1[0] <= (bri_lev0[0]|bri_lev0[1]);
    224.                         bri_lev_s1[1] <= (bri_lev1[0]|bri_lev1[1]);
    225.                         bri_lev_s1[2] <= (bri_lev2[0]|bri_lev2[1]);
    226.                         bri_lev_s1[3] <= (bri_lev3[0]|bri_lev3[1]);
    227.                 end

    228.     //LED output with enable switch
    229.     always@(sw or led_pwm)
    230.       led <= ~(sw & led_pwm);

    231.     //Button press-down detect
    232.     always@(posedge clk_100ns or negedge rst)
    233.       if(!rst)
    234.       begin
    235.         btn_sign <= 1'b0;
    236.         btn_pressdown_state <= 4'b0;
    237.         btn_cnt <= 10'b0;
    238.         btn_pressdown_check <= 4'b0;
    239.       end   
    240.       else
    241.         if((~btn) && (!btn_sign))
    242.         begin
    243.           btn_sign <= 1'b1;
    244.           btn_pressdown_state <= btn;
    245.         end
    246.         else
    247.           if(btn_sign)
    248.             case(btn_cnt)
    249.               10'b01_1111_0100://20ms counter finish
    250.               begin
    251.                 btn_pressdown_check <= ~(btn | btn_pressdown_state);
    252.                 if(~(btn | btn_pressdown_state))
    253.                   btn_cnt <= 10'b01_1111_0101;
    254.                 else
    255.                 begin
    256.                   btn_sign <= 1'b0;
    257.                   btn_pressdown_state <=4'b0;
    258.                   btn_pressdown_check <= 4'b0;
    259.                   btn_cnt <= 10'b0;
    260.                 end
    261.               end
    262.               10'b01_1111_0101://reset until btn is released
    263.               if(~(btn | btn_pressdown_state))
    264.                 ;
    265.               else
    266.               begin
    267.                 btn_sign <= 1'b0;
    268.                 btn_pressdown_state <=4'b0;
    269.                 btn_pressdown_check <= 4'b0;
    270.                 btn_cnt <= 10'b0;
    271.               end
    272.               default:
    273.               begin
    274.                 btn_cnt <= btn_cnt + 10'b00_0000_0001;
    275.               end
    276.             endcase
    277.           else
    278.           begin
    279.             btn_pressdown_check <= 4'b0;
    280.             btn_cnt <= 10'b0;
    281.             btn_pressdown_state <= 4'b0;
    282.           end                        
    283.       
    284.       //Button brightness function
    285.       always@(posedge btn_pressdown_check[0] or negedge rst)
    286.         if(!rst)
    287.         begin
    288.           bri_lev0 <= 2'b00;
    289.         end
    290.         else
    291.         begin
    292.           bri_lev0 <= bri_lev0 + 2'b01;
    293.         end
    294.         
    295.       //Button brightness function
    296.       always@(posedge btn_pressdown_check[1] or negedge rst)
    297.         if(!rst)
    298.         begin
    299.           bri_lev1 <= 2'b00;
    300.         end
    301.         else
    302.         begin
    303.           bri_lev1 <= bri_lev1 + 2'b01;
    304.         end
    305.          
    306.       //Button brightness function
    307.       always@(posedge btn_pressdown_check[2] or negedge rst)
    308.         if(!rst)
    309.         begin
    310.           bri_lev2 <= 2'b00;
    311.         end
    312.         else
    313.         begin
    314.           bri_lev2 <= bri_lev2 + 2'b01;
    315.         end
    316.             
    317.       //Button brightness function
    318.       always@(posedge btn_pressdown_check[3] or negedge rst)
    319.         if(!rst)
    320.         begin
    321.           bri_lev3 <= 2'b00;
    322.         end
    323.         else
    324.         begin
    325.           bri_lev3 <= bri_lev3 + 2'b01;
    326.         end

    327. endmodule
    复制代码


    除了Verilog源代码外,还需要约束文件来配置输出管脚、配置时钟速率以及走线速率,Xilinx的约束文件为xdc。Perf-V开发板FPGA LED、轻触开关、拨码开关管脚约束文件:
    1. set_property IOSTANDARD LVCMOS33 [get_ports {btn[3]}]
    2. set_property IOSTANDARD LVCMOS33 [get_ports {btn[2]}]
    3. set_property IOSTANDARD LVCMOS33 [get_ports {btn[1]}]
    4. set_property IOSTANDARD LVCMOS33 [get_ports {btn[0]}]
    5. set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
    6. set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
    7. set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
    8. set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
    9. set_property IOSTANDARD LVCMOS33 [get_ports {sw[3]}]
    10. set_property IOSTANDARD LVCMOS33 [get_ports {sw[2]}]
    11. set_property IOSTANDARD LVCMOS33 [get_ports {sw[1]}]
    12. set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}]
    13. set_property IOSTANDARD LVCMOS33 [get_ports clk_in]
    14. set_property IOSTANDARD LVCMOS33 [get_ports rst]
    15. set_property PACKAGE_PIN R15 [get_ports {btn[3]}]
    16. set_property PACKAGE_PIN R16 [get_ports {btn[2]}]
    17. set_property PACKAGE_PIN T14 [get_ports {btn[1]}]
    18. set_property PACKAGE_PIN M15 [get_ports {btn[0]}]
    19. set_property PACKAGE_PIN K13 [get_ports {sw[3]}]
    20. set_property PACKAGE_PIN L14 [get_ports {sw[2]}]
    21. set_property PACKAGE_PIN M14 [get_ports {sw[1]}]
    22. set_property PACKAGE_PIN T15 [get_ports {sw[0]}]
    23. set_property PACKAGE_PIN N14 [get_ports clk_in]
    24. set_property PACKAGE_PIN L13 [get_ports rst]
    25. set_property PACKAGE_PIN P16 [get_ports {led[3]}]
    26. set_property PACKAGE_PIN P15 [get_ports {led[2]}]
    27. set_property PACKAGE_PIN N16 [get_ports {led[1]}]
    28. set_property PACKAGE_PIN M16 [get_ports {led[0]}]

    复制代码


    一般的FPGA开发流程是先编写Verilog源代码、调用IP核、编写约束文件、行为仿真、综合、综合后仿真、布局布线、布局后仿真、生成字节流文件、下载字节流文件、功能测试、(程序固化)。

    下面建立工程文件就不说了,先来说说怎么调用IP核:
    一、IP核调用
    在Vivado左边流程导航(Flow Navigator)中点击IP Catalog,找到ILA,点击即可添加。图形化界面,都很好设置。 Snipaste_2019-01-08_00-48-12.png

    设置探头数量和位宽,数据储存深度等等。数据储存深度是比较吃FPGA上面RAM资源的,资源比较紧缺的FPGA型号不能选得太高。
    Snipaste_2019-01-08_00-37-50.png

    这里选择四个探头来观察其逻辑。
    Snipaste_2019-01-08_00-43-02.png

    点击OK即可,这里选择单独综合IP核,点击Generate来综合IP核。稍等一下即可。
    Snipaste_2019-01-08_00-43-16.png

    等了一会之后,可以看见多了这么个东西,点击一下这个.v文件即可查看一下module接口,准备实例化这个IP核。
    Snipaste_2019-01-08_00-45-32.png

    在这个Verilog文件中可见module接口参数,只需在需要观测的module上实例化这个IP核即可在下载BitSTEAM之后可以在线查看逻辑,相当于逻辑分析仪功能。
    Snipaste_2019-01-08_00-46-04.png

    在module中实例化IP核。
    Snipaste_2019-01-09_01-10-47.png

    clock wizard也是一样的操作。
    Snipaste_2019-01-08_01-21-20.png
    由于只需要使用它对时钟信号进行整形,因此输出也选择100MHz。(晶振输入也是100MHz)点击OK即可添加。
    Snipaste_2019-01-08_01-21-31.png

    二、Vivado中仿真Verilog代码
    在编写好Verilog之后,由于综合和布局时间比较长,如果担心Verilog代码有问题,可以弄个行为仿真。一下为在Vivaodo中实现仿真功能。


    先对着.v文件点右键->Move to simulation sources。这里别忘了,仿真的时候需要有Testbench文件来给予激励信号,这里别忘了编写和添加Testbench用的Verilog代码,此处为LED_PWM_TB文件,并且设置为顶层文件,并在Testbench中实例化待调试的module。
    Snipaste_2019-01-09_00-53-41.png

    Verilog源代码文件和Testbench都就绪之后,右键sim_1,按图中所选。Vivado提供了5种仿真设置。Behavioral Simulation是行为级仿真,速度比较快,但是不考虑实际中线路长度所产生的延时问题;Post-Synthesis是综合之后的仿真,速度一般,不考虑走线延时,但是考虑寄存器等的延迟;Post-Implementation是布局布线后仿真,考虑寄存器、走线延迟,速度最慢。这里由于是低速应用,因此选择行为级仿真即可。
    Snipaste_2019-01-09_00-55-11.png

    Vivado仿真界面和Modelsim软件界面十分相识,估计是Modelsim的OEM版本。在这里点击run即可仿真,仿真步进、仿真精度都可以选择,可以自己添加关心信号,把关心信号的逻辑显示出来,可以有效调试程序。仿真这部分不是本篇文章的重点,因此不仔细讲。
    Snipaste_2019-01-09_00-52-48.png


    三、综合、布局布线、生成Bitsteam、下载、固化
    这里不仔细说,可参考前一篇文章。
    Snipaste_2019-01-09_01-11-37.png

    别忘记设置顶层文件。
    Snipaste_2019-01-09_01-11-58.png

    点击OK即可。
    Snipaste_2019-01-09_01-12-21.png

    Snipaste_2019-01-09_01-16-27.png

    RTL级原理图
    Snipaste_2019-01-09_02-17-52.png

    Snipaste_2019-01-09_01-30-56.png

    布局之后原理图:
    Snipaste_2019-01-09_02-25-28.png

    下载完成之后即可看到效果了。下载的时候别忘记把ITX调试探针文件也下载,不然在线逻辑分析仪功能不能用。
    Snipaste_2019-01-09_02-29-08.png

    下面是逻辑分析仪,可以添加之前所选的信号进入,可以自定义触发条件。十分方便在线调试,可以十分方便捕捉到内部信号,不过缺点是不一定所有信号都在综合之后保留,有些会被综合掉了,这点需要注意。
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 20:20 , Processed in 0.122996 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.