首页 > 解决方案 > 一旦模块不需要 BRAM,如何重用它?

问题描述

我正在做一个(看似)简单的项目作为学习练习:通过 iCEstick(Lattice iCE40HX-1k FPGA)将基于 SSD1331 的 96x64 PMOD 显示器连接到 PC,这样我就可以通过 USB 发送一些 RGB565 编码的图像以显示在说显示。

问题是,SSD1331 显示器需要一个初始化程序才能进入“清除黑屏”状态。大约有 20 条命令要转移到显示控制器中;长度在 1 到 5 个字节之间变化,总共 44 个字节。

到目前为止,我pwr_on用 FSM 编写了 Verilog 模块,用于以正确的顺序将命令转换为 PMOD;命令的值定义为localparam。一切正常,但总有一个但是。我认为所有这些命令常量都存储在 LUT 中(我没有推断任何 RAM 块,所以它们还会去哪里,对吧?),并且 iCE40HX1k 中只有 1,280 个 LUT 可用,其中大约有 100 个 LUT 用于 init 过程大约 150 毫秒,并且在下一次重置之前永远不需要,这似乎是一种浪费。

现在,我可以看到以下方法来处理这个问题:

  1. 根本不要在 FPGA 中实现初始化序列;相反,通过 USB 发送这些命令。
    简单但没那么有趣;毕竟,我正在尝试学习 FPGA 编程,而不是 Linux 驱动程序。
  2. 充分利用SB_WARMBOOT和多配置。
    iCE40HX 最多可在 EEPROM 中存储 4 种配置;SB_WARMBOOT原语基本上可以让您随意在它们之间跳转。我可以在配置 0 中编写 init 过程,一旦完成,就跳转到配置 1 并支持 USB,从而获得一个干净的状态。但是,在配置之间的转换过程中,我需要保持至少 3 个显示 PMOD 引脚(pmod_enable、vcc_enable 和 pmod_rstn)为高电平。我找不到任何方法来做到这一点;如果有人知道,请向我发送正确的方向。
  3. 将命令数据存储在 BRAM 中。
    HX1K 有 16 个 RAM4K 块(每个存储 4096 位),因此即使其中一个也应该为 44 字节的命令数据提供足够的空间,而无需花费宝贵的 LUT。

选项 3 看起来很简单。但是,由于我对我的资源的贪婪,一旦完成初始化,我希望该 RAM4K 块可用于其他任务。现在,在我看来,Verilog 合成器(我正在使用 yosys)完全没有意识到当pwr_on模块将done导线拉高时,它所连接的 BRAM 单元可以在推断其他逻辑时被重用。

想到的一种解决方案是将该 BRAM 块分配到一个单独的模块中,用初始化所需的数据填充它并将其连接到pwr_on模块,然后根据需要将其重新连接到其他模块。然而,由于几个原因,这种方法看起来很难看,因此问题是:我错过了一个技巧吗?我怎么能在一个模块的SB_RAM512x8配置中使用一个 BRAM 块,然后将它重SB_RAM256x16用于另一个模块?

标签: fpgayosysice40

解决方案


将读取地址复用到用于 PMOD 配置数据的 EBR

据我所知,ice40 的 EBR 不能在运行时更改WRITE_MODEand READ_MODE(如果我错了,请纠正我)。因此,我建议在启动 PMOD后在您想要使用的配置中实例化您的 EBR 。EBR 的内容必须包括 PMOD 的配置数据,通过INIT_0通过的常用方式指定INIT_F

到 EBR 的读取地址需要是来自 FSM 控制 PMOD 启动的地址的多路复用,以及在启动后使用的地址,这只需要大约 8 个 LUT。


推荐阅读