iCEstick + yosys - 使用全局 Set/Reset (GSR)

iCEstick + yosys - using the Global Set/Reset (GSR)

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

我想指定我的设计的启动行为,互联网上的各个地方似乎都同意与通常命名的 rst 信号有关。我不清楚这样的信号来自哪里,所以我深入研究了加电顺序。目前的理解来自 this document.

中的图 2

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

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

四处寻找 ice40 family data sheet and the Lattice site, I found this document about using the Global Set/Reset signal。我确认这个 GSR 在家庭数据 sheet 中提到,在第 2-3 页 "Clock/Control Distribution Network" 下引用。似乎全局复位信号可由全局缓冲区之一 GBUF[0-7] 使用,并且可以通过 global/high-fanout 分发网络路由(最多 4 个)到所有 LUT。

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

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

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

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

另外,我用lattice tools构建了以下两个设计,生成的码流文件除了"comment field"中的时间戳外,生成的码流完全一样! (该测试是使用莱迪思 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 系列兼容?)

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

input clk;
...

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

(IceStorm 流程确实支持寄存器的任意初始化值,而 the lattice tools ignore the initialization value and simply initialize all FFs to zero。因此,如果您希望您的设计在工具之间可移植,建议仅将寄存器初始化为零。)

如果您使用 PLL,则习惯使用 PLL LOCK 输出来驱动 resetn 信号。不幸的是,"iCE40 sysCLOCK PLL Design and Usage Guide" 没有说明生成的 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 将自动路由 set/reset 信号(当不止几个 FF 使用时)在全球网络上,如果全球网络可用。