【问题标题】:How do I cause my LEDs to light in a random fashion using $urandom_range?如何使用 $urandom_range 使我的 LED 以随机方式点亮?
【发布时间】:2021-03-09 19:48:08
【问题描述】:

我意识到这是一个非常基本的事情,但我是 systemverilog 和 FPGA 的新手,我似乎一辈子都无法让它发挥作用。我正在使用具有 16 个活动高 LED 的 FPGA,我可以将其初始化为输出逻辑 [15:0] LED,我可以通过写入 LED[x] = 1 来使其中一个 LED 点亮;其中 x 是一个介于 0 和 15 之间的数字,或者通过编写 led = 16b'abcdefghijclmnop 来点亮许多数字,其中 ' 右侧的每个字母都是 1 或 0。

但是我希望它们以随机方式点亮。

我最初尝试写作

led[0] = $urandom_range(0,1); 
led[1] = $urandom_range(0,1);
.
.
led[15] = $urandom_range(0,1);

那没有用。 然后我试着写

logic [0:0] led1 = $urandom_range(0,1);
led[0] = led1;

那没有用。

我试过了:

bit [0:0] led1 = $urandom_range(0,1);
led[0] = led1;

那没用 我尝试了位和逻辑类型:

type [0:0] led1 = $urandom_range(0,1);

if(led1)
   led[0] = 1;
else
   led[0] = 0;

我也试过了:

if (led1>0)
   led[0] = 1;
else
   led[0] = 0;

都没有成功。 我试过了:

logic [15:0] led1 = $urandom_range(0,1);

led = led1;

那没有用。

我在 initial 和 always_begin 和 always_ff 块中尝试了所有这些,并使用适当的赋值语句,但我仍然无法使用 $urandom_range() 让 LED 点亮

【问题讨论】:

  • 我不确定。我怎么知道?这是一个BASYS3。我没有收到任何综合或实施错误或警告。我正在使用 Vivado。
  • 检查综合警告和错误。
  • 哦,对不起。我的意思是我不知道董事会是否支持该命令,并且我无法找到任何有关此的文档。我在综合或实施时没有收到任何警告或错误。

标签: system-verilog


【解决方案1】:

嗯,如果系统任务$urandom$urandom_range 是可合成的,我会感到非常惊讶。

当您使用任何 HDL 来实际合成数字电路时,您需要记住您不是在“编程”,而是您实际上是在设计逻辑电路。因此,要实际创建一些随机值,您需要创建某种随机数生成器。

我建议使用某种简单的 LFSR 来实际生成一些伪随机值。或者从您正在使用的工具库中获取一个。或者您可以使用以下 sn-p 中的类似内容(但不确定它是否可合成):

module PSRG_LFSR (clock,rst_n,halfword_out);
  input clock,rst_n;
  output logic[15:0] halfword_out;

  logic new_bit;
  assign new_bit = halfword_out[9] ^ halfword_out[7] ^ halfword_out[5];

  always@(posedge clock) begin
    if ( rst_n != 1'b1 ) begin
      halfword_out = 16'hDEAD;
    end 
    else begin
      halfword_out = {halfword_out,new_bit};
    end
  end
endmodule

然后您可以实例化此 LFSR 并将其连接到代码中的 LED。不过,LFSR 需要一些适当的时钟:

...
PSRG_LFSR LFSR_i (.clock(clock),.rst_n(reset),.halfword_out(LED));
...

【讨论】:

    【解决方案2】:

    在进行综合时,VHDL 代码被转换为由逻辑门和触发器组成的网表。为此,VHDL 描述必须满足某些严格的标准,否则综合工具将拒绝它。

    您用来生成随机数的函数不能通过综合工具运行。您应该能够使用它们来分配初始值,但它们不能在 FPGA 上的硬件中运行!

    最简单的使用方法是使用线性反馈移位寄存器 (LFSR),它使用来自特定抽头的反馈来获得最大长度的重复输出序列。这是您能做的最简单的事情,而且在硬件中几乎是微不足道的。

    Xilinx 应用笔记 XAPP052 和 XAPP210 可能会在这方面为您提供帮助。它们都包含一个表格,显示了用于给定长度的 LFSR 的反馈循环中的抽头,以给出重复序列的最大长度。

    如果您想要一种更强大的方法,而 LED 肯定不需要这种方法,那么请查看这个 xoshiro / xoroshiro 生成器:

    https://prng.di.unimi.it/

    https://github.com/jorisvr/vhdl_prng

    【讨论】:

    • LFSR 是在 FPGA 中创建随机数的最简单方法。它也是最常用的方法,对于大多数应用程序来说已经足够了。我想知道投反对票的目的是什么?
    猜你喜欢
    • 2019-04-07
    • 1970-01-01
    • 2018-06-16
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多