6

这可能更像是一个 iCEstick 问题而不是一个 yosys 问题,但在这里问,因为我使用的是 Icestorm 工具链。

我想指定我的设计的启动行为,互联网上的各个地方似乎都同意与通常命名的rst信号有关。对我来说,这样的信号来自哪里并不明显,所以我深入研究了通电序列。目前的理解来自本文档中的图 2 。

CDONE被设备拉高后,所有的内部寄存器都被复位到某个初始值。现在,我找到了大量关于每种类型的触发器或硬 IP 如何接收复位信号并对其内部状态进行操作的 lattice 文档,但我仍然不太明白我如何指定这些状态是什么(或甚至只知道它们是什么,所以我可以使用它们)。

例如,如果我想在上电后(并且在上电后)将 LED 拉高 1 秒钟,我想在此复位信号(无论它是什么)禁用后启动一个计数器。

浏览ice40系列数据表和 Lattice 网站,我发现了这个关于使用 Global Set/Reset signal 的文档。我确认GSR在家庭数据表中提到了这一点,在第 2-3 页的“时钟/控制分配网络”下引用。全局复位信号似乎可由全局缓冲区之一使用,GBUF[0-7]并且可以通过全局/高扇出分布网络路由(最多 4 个)到所有 LUT。

这似乎正是我所追求的,但我找不到任何其他关于如何在我的设计中使用它的信息。使用 GSR 的文档指出,您可以像这样实例化本机 GSR 组件:

GSR GSR_INST (.GSR (<global reset sig>));

但我不知道这是否只是为了模拟。我是完全走错了方向还是只是错过了什么?我对 FPGA 和硬件非常缺乏经验,所以我的整个方法完全有可能存在缺陷。

4

1 回答 1

7

我不确定那个 GSR 文件是否真的是关于 iCE40 的。Lattice iCEcube 工具有趣地接受了 GSR 单元的实例,但它似乎只是将它们视为恒定零驱动器。在 iCE40 sim 库中也没有 GSR 单元类型的仿真模型,在 Lattice 提供的 iCE40 技术库文档中也没有描述。

此外,我使用lattice工具构建了以下两个设计,除了生成的比特流文件的“注释字段”中的时间戳之外,生成的比特流是相同的!(这个测试是使用 Lattice LSE 作为综合工具进行的,而不是 Synplify。由于某种原因,我在让 Synplify 在我的机器上运行时遇到了问题,一年多前放弃了尝试这样做。)

这是我使用的第一个测试设计:

module top (
    input clk,
    output rst,
    output reg val
);
    always @(posedge clk, posedge rst)
        if (rst)
            val = 1;
        else
            val = 0;

    GSR GSR_INST (.GSR (rst));
endmodule

这是第二个测试设计:

module top (
    input clk,
    output rst,
    output val
);
    assign val = 0, rst = 0;
endmodule

鉴于此结果,我认为可以肯定地说晶格工具只是忽略了 iCE40 设计中的 GSR 单元。(也许是为了与他们的其他 FPGA 系列兼容?)

那么如何产生第一个信号呢?resetn例如,以下是一个简单的复位发生器,它在前 15 个周期置位(拉低) :

input clk;
...

wire resetn;
reg [3:0] rststate = 0;
assign resetn = &rststate;
always @(posedge clk) rststate <= rststate + !resetn;

(IceStorm 流程确实支持寄存器的任意初始化值,而lattice 工具忽略初始化值并简单地将所有 FF 初始化为零。因此,如果您希望您的设计在工具之间可移植,建议仅将 regs 初始化为零.)

如果您使用的是 PLL,则习惯使用 PLLLOCK输出来驱动resetn信号。不幸的是,“iCE40 sysCLOCK PLL 设计和使用指南”没有说明生成的LOCK信号是否已经与生成的时钟同步,因此最好将其与时钟同步以避免亚稳态问题:

wire clk, resetn, PLL_LOCKED;
reg [3:0] PLL_LOCKED_BUF;
...

SB_PLL40_PAD #( ... ) PLL_INST (
  ...
  .PLLOUTGLOBAL(clk),
  .LOCK(PLL_LOCKED)
);

always @(posedge clk)
    PLL_LOCKED_BUF <= {PLL_LOCKED_BUF, PLL_LOCKED};

assign resetn = PLL_LOCKED_BUF[3];

关于全局网络的使用:您可以通过全局网络显式路由 resetn 信号(使用SB_GB原语),但使用 IceStorm 流程,arachne-pnr 将自动路由设置/重置信号(当不止几个 FF 使用时) 在全球网络上,如果全球网络可用。

于 2016-06-25T19:19:24.957 回答