MyHDL VHDL 转换:没有索引值可以属于空索引范围

MyHDL VHDL conversion: no index value can belong to null index range

对于我实现并成功转换为 VHDL 的算法,我在 "Static elaboration of top level VHDL design" 期间收到此错误:

no index value can belong to null index range

我将代码归结为基本部分(您可能认识一个 cordic 处理器)。

import myhdl
from myhdl import enum, intbv, always_comb, always_seq, always, instance, Signal, ResetSignal, Simulation, delay, StopSimulation
import unittest
from unittest import TestCase


# input bit width
BIT_IN = 16

########################################################
#                  IMPLEMENTATION                      #
########################################################

def NullIndex(clk, reset):

  R2P_W = 16

  # nr of iterations equals nr of significant input bits
  R2P_N = R2P_W-1

  R2P_LIMIT = 2**(R2P_W+1)

  x = [Signal(intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT)) for _ in range(R2P_N+1)]
  y = [Signal(intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT)) for _ in range(R2P_N+1)]
  z = [Signal(intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT)) for _ in range(R2P_N+1)]

  @always_seq(clk.posedge, reset=reset)
  def processor():
      dx = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(R2P_N+1)]
      dy = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(R2P_N+1)]
      dz = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(R2P_N+1)]

      # actual algorithm
      # starting vector
      x[0].next = 42
      y[0].next = 42
      z[0].next = 0

      # connect all stages of the pipeline where stage 1 has been defined by the starting conditions above
      for i in range(0, R2P_N):
          # shifting performs the 2**(-i) operation
          dx[i+1][:] = x[i] >> i
          dy[i+1][:] = y[i] >> i
          dz[i+1][:] = 42 #don't worry, normally not a constant
          if (y[i] > 0):
              x[i+1].next = x[i] + dy[i+1]
              y[i+1].next = y[i] - dx[i+1]
              z[i+1].next = z[i] + dz[i+1]
          else:
              x[i+1].next = x[i] - dy[i+1]
              y[i+1].next = y[i] + dx[i+1]
              z[i+1].next = z[i] - dz[i+1]

  return processor



########################################################
#                      TESTS                           #
########################################################

class TestNullIndex(TestCase):

    def setUp(self):
        # input/output width
        self.m = BIT_IN
        self.limit = 2**self.m

        # signals
        self.clk = Signal(bool(0))
        self.reset = ResetSignal(0, active=1, async=True)


    def testDut(self):    
        # actual test
        def test(clk):
          for _ in range(42):
            yield clk.posedge

          raise StopSimulation

        # instances
        dut = myhdl.toVHDL( NullIndex, clk=self.clk, reset=self.reset )
        inst_test = test(self.clk)

        # clock generator
        @always(delay(1))
        def clkGen():
          self.clk.next = not self.clk

        sim = Simulation(clkGen, dut, inst_test)
        sim.run(quiet=1)




if __name__ == "__main__":
  unittest.main()

感兴趣的部分是

dx = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(R2P_N+1)]
.
.

当转换为 VHDL 时,它会为 d[x,y,z] 数组吐出类似的东西:

type t_array_dz is array(0 to -1-1) of signed(17 downto 0);
variable dz: t_array_dz;
type t_array_dx is array(0 to -1-1) of signed(17 downto 0);
variable dx: t_array_dx;
type t_array_dy is array(0 to -1-1) of signed(17 downto 0);
variable dy: t_array_dy;

这最终会导致错误,因为数组不能从 0-1-1。为什么会这样,我做错了什么?

对于变量声明,MyHDL 似乎不支持在列表理解中对 range 的调用中使用表达式(尽管它支持信号声明)。

如果你改变这个:

dx = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(R2P_N+1)]
dy = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(R2P_N+1)]
dz = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(R2P_N+1)]

对此:

dx = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(16)]
dy = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(16)]
dz = [intbv(0, min=-R2P_LIMIT, max=R2P_LIMIT) for _ in range(16)]

然后你得到预期的 VHDL 声明:

type t_array_dz is array(0 to 16-1) of signed(17 downto 0);
variable dz: t_array_dz;
type t_array_dx is array(0 to 16-1) of signed(17 downto 0);
variable dx: t_array_dx;
type t_array_dy is array(0 to 16-1) of signed(17 downto 0);
variable dy: t_array_dy;