初试高云FPGA

前言

之前一直眼馋Sipeed的Tang系列,正好遇到有工程需要高速控制并行总线,就买了NANO 9K和Primer 20K试试水
买回来先拆的贵的20k,结果发现Sipeed设计师有奇怪的脑回路:

  • 核心板没有指示灯,没有集成下载器
  • tf卡在核心板与底板中间藏着,JTAG丝印在背面
  • JTAG接口和官方下载器需要扭麻花形式连接
  • 调整供电bank需要手动拆除0R电阻。
  • 板载晶振27MHz,很奇怪的频率
    image
    image
    image

结果就是失去了调试的兴趣,随便写了个分频器输出1pps脉冲了事。

之后拆了NANO 9K,这个就比20K好用多了,板载一串LED,虽然一些板载资源占用了IO,但还是比较方便调试的。
image

Sipeed还有个问题就是,例程太少,点灯、点屏幕,没了。好在高云的手册比较多,虽然各个功能的手册是分别发布的,没有系统教程,但好在详细。摸索了一天,算是明白了这个工具要怎么用,因此先写一篇博客记录一下。

软件准备

  1. 前往高云官网下载软件和各种参考手册。推荐使用教育版,不用申请license。
  2. 安装下载好的云源软件,我安装的1.9.8.09教育版,有的教程说要另外下载programmer,该版本已自带。软件安装问题可以参考SUG501手册。
  3. 打开软件,界面功能问题可以参考SUG100手册。
  4. 新建工程,点灯测试,详见Sipeed点灯例程
  5. 综合、约束、下载之类的基础操作在例程中已有详解,这里列一下可能用到的手册
    • 综合问题在SUG550
    • 约束在SUG935和SUG940
    • 下载在SUG502
    • 其他高级功能样例在SUG918,所有功能有独立说明手册
      所以说高云手册虽然不系统,但好在很详细

IP核调用

IP核怎么调用,没有专门教程参考,仅在SUG100中放了个界面。各各IP核手册中也只是用Verilog或VHDL实例化原语,搞得我这Verilog入门菜鸟一头雾水。在此随手记录一下IP核调用方式。

项目目标

点灯教程中系统时钟来自于板载时钟27MHz,这个时钟我猜测是为了保留3M时钟基频,以便精确PLL出如21M、12M、24M等时钟(那为什么不用21M时钟,还包含7M基频)。

但是我看27MHz不顺眼,于是项目目标就是,利用GW1NR-9C自带的可编程时钟,产生一个25MHz频率,再用这个25MHz进PLL产生100MHz时钟,同时把25MHz用缓冲器输出到引脚上,以检测板子的信号完整性。最后固化到内部Flash,完成烧录与脱机运行。

这样,该项目检测了逻辑单元、IO、IO速率、PLL、CLK,只剩下DSP、SRAM和一些PHY没测试了,之后可以写一个DDS工程,测一下DSP和SRAM。

IP核配置

  1. 首先是打开IP核界面,选择时钟模型,选择OSC,双击
    image
  2. 可以看到内部可编程时钟的配置是很简单的,只需要填一个分频数就好。该IP核的详细说明见UG286,具体搭载的时钟原频率是多少,不要参考软件中IP核的说明,要参考IC的Datasheet,如GW1NR-9的DS117的晶振时钟章节
    image
    image
  3. 软件自动生成verilog文件,自己也可以仿照该文件直接在主模型文件中例化原语。
    image
  4. 在主模型文件中将该OSC模型实例化
    image
  5. 接着,在IP核管理界面选择rPLL模块,一般使用普通模式即可,填入输入时钟、输出时钟、误差容忍度,点击计算即可自动配置。需注意,有些需求时钟是不能产生的,或者它自动生成参数后综合软件认为不在VCO适用频率内,这时就需要手动凑数计算了。详细参数计算综合报错时会有,UG286也有计算方法。
    image
    image
  6. 在主文件中将该PLL实例化
    image
  7. 直接在主文件中将25M时钟连到OBUF上,输出带缓冲的clk_out
    image
  8. 对点灯例子中的一些计数值稍作修改,即可完成代码
  9. 综合约束,烧录。烧录选择烧录在内部Flash里,这样可以离线运行
    image
    image

代码如下:

module led (
    input sys_rst_n,        // reset input
    output reg [5:0] led,    // 6 LEDS pin
    output wire clk_out
);

reg [31:0] counter;
wire pll_clk;
wire sys_clk;

Gowin_OSC SYSOSC(sys_clk);
Gowin_rPLL APLL(pll_clk,sys_clk);
OBUF uut(
    .O(clk_out),
    .I(sys_clk)
);

always @(posedge pll_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        counter <= 32'd0;
    else if (counter < 32'd49_999_999)       // 0.5s delay
        counter <= counter + 1'b1;
    else
        counter <= 32'd0;
end

always @(posedge pll_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        led <= 6'b111110;
    else if (counter == 32'd49_999_999)       // 0.5s delay
        led[5:0] <= {led[4:0],led[5]};
    else
        led <= led;
end

endmodule

约束:
image

posted @ 2022-12-18 19:16  Maaaaark  阅读(1603)  评论(0编辑  收藏  举报