【每周一练】+盘古1K开发板+1. 流水灯实现 - FPGA开发者技术社区 - 电子技术william hill官网 - 广受欢迎的专业电子william hill官网 - 威廉希尔官方网站
分享 收藏 返回

hehung 关注 私信
[文章]

【每周一练】+盘古1K开发板+1. 流水灯实现

前言

这是本人第一次使用FPGA,感谢小眼睛科技公司以及elefans提供的每日一练和每周一练的机会,本人将借助这次机会入门FPGA,了解一下FPGA的神奇之处。

1 开发环境

官方工作人员提供了如下开发工具包:

1K2K链接:https://pan.baidu.com/s/18EBJd9TYyTuXH4MlEh2qZA
提取码:tknh

PDS软件Lite版本(免License)链接:https://pan.baidu.com/s/1hY0XZtZcntyVp87nd9HUWA
提取码:6abm

这里需要说明一点的就是,“1K2K链接”下面提供了pango Design Suite的开发包,但是是需要license的,需要向紫光同创申请,所以为了最好安装PDS软件Lite版本,用Lite版本开发,已经足够我们学习使用了。

环境安装就不多说了,直接安装“PDS软件Lite版本(免License)链接”下面提供的软件即可。

2 开发学习

参考“1K2K链接”下面提供的“MES2KG”,里面有示例代码和说明,我们可以参考这些入门。

下面就是我实现流水灯的过程。

2.1 新建工程

PDS使用教程可以参考资料包里面的文档《PDS快速使用手册.docx》。

到了如下一步之后选择如下,因为我们的板子是PGC1KG-6LPG100:
1700891138553.png

芯片型号一定要选对,不然的话烧录器是连接不上的,最开始我使用官方Demo就一直连不上烧录器JTAG,最后找了很久才发现是芯片型号不对。

2.2 软件编写

本人也是第一次使用FPGA,所以基本上还是参考官方提供的Demo来实现的,同时也为了入门FPGA。

2.2.1 代码分析

下面是对官方提供的代码的分析:


`timescale 1ns / 1ps


设置时间单位,时间单位是ns,精度是ps。

module water_led(
    input          clk,
    input          rstn,
  
    output [7:0]   led
);

上述代码定义了输入输出端口。

  • clk是时钟输入;
  • rstn是低电平有效的复位输入;
  • led是8位输出端口,连接LED。
reg [25:0] led_light_cnt;
    reg [ 7:0] led_status;
  • 定义一个26位的寄存器led_light_cnt,用来做定时计数。
  • 定义一个8位的寄存器led_status,用来记录LED点亮状态
always @(posedge clk)
    begin
        if(!rstn)
            led_light_cnt <= `UD 26'd0;
        else if(led_light_cnt == 26'd19_999_999)
            led_light_cnt <= `UD 26'd0;
        else
            led_light_cnt <= `UD led_light_cnt + 26'd1; 
    end

在时钟上升沿的时候时触发上述代码。使用led_light_cnt实现计数功能:

  • 复位时将寄存器led_light_cnt清零;
  • 当寄存器记满19999999时,将寄存器led_light_cnt清零;
  • 如果寄存器没有记满19999999,则计数值加1
always @(posedge clk)
    begin
        if(!rstn)
            led_status <= `UD 8'b0000_0001;
        else if(led_light_cnt == 25'd19_999_999)
            led_status <= `UD {led_status[6:0],led_status[7]};
    end

在始终上升沿的时候触发上述代码。

  • 复位时将寄存器led_status复位为1;
  • 当led_light_cnt计数满19999999时,将寄存器led_status向左移一位;这样就得到了LED状态的循环左移。
assign led = led_status;

最后寄存器led_status复制给led输出。

2.2.2 代码更改

按照题目要求,流水灯频率为0.5s,因为晶振频率为50MHz,所以修改计时值为24999999,并且我在此基础上增加了流水灯功能,修改为了左移流水灯移动完成之后,再直接右移,右移完成再左移,来回左右移动流水灯。

改良后的代码如下:

`timescale 1ns / 1ps

`define UD #1

module water_led(
    input          clk,
    input          rstn,
  
    output [7:0]   led
);


//==============================================================================
//reg and wire

    reg [25:0] led_light_cnt;
    reg [ 7:0] led_status;
    reg led_dir;
    reg [3:0] led_shift;
  
    //  time counter
    always @(posedge clk)
    begin
        if(!rstn)
            led_light_cnt <= `UD 26'd0;
        else if(led_light_cnt == 26'd24_999_999)
            led_light_cnt <= `UD 26'd0;
        else
            led_light_cnt <= `UD led_light_cnt + 26'd1; 
    end
  
    // led status change
    always @(posedge clk)
    begin
        if(!rstn) begin
            led_status <= `UD 8'b0000_0001;
            led_dir <= `UD 1'b1;
            led_shift <= `UD 3'd0;
        end
        else if(led_light_cnt == 25'd24_999_999) begin
            if (led_dir)
                led_status <= `UD {led_status[6:0],led_status[7]};
            else
                led_status <= `UD {led_status[0], led_status[7:1]};
            led_shift <= `UD led_shift + 3'd1;
            if (led_shift == 3'd6) begin
                led_dir <= `UD ~led_dir;
                led_shift <= `UD 3'd0;
            end
        end
    end

    assign led = led_status;
  
endmodule

2.3 代码下载

  1. 连接JTAG烧录器
    1701959415296.png

如果连接不上,可以查看一下芯片型号是否选对,芯片选择不对则也连接不上

  1. 点击菜单栏下载按钮:
    1701959141260.png

  2. 然后弹出的下载窗口中点击连接按钮:
    1701959225220.png

  3. 成功连接之后,会弹出一个文件对话框,选择编译好的sbit文件,双击即可:
    1701959506549.png

  4. 然后右键单击右窗口PANGO图标,点击Program:

1701959576751.png

3 实验效果

效果如下,经过多次调试,终于成功实现目的了:
1701966373437.gif

回帖(1)

自我清欢

2023-12-8 17:01:51
感谢大佬分享

更多回帖

×
发帖