简体   繁体   中英

MyHDL: Can't translating Signal.intbv.max to VHDL

I'm new to python and MyHDL so I started by converting old VHDL projects to MyHDL. This project is a vga timer that can accept any width, height, and frequency (given that they actually work with monitors). It doesn't successfully convert to either VHDL or Verilog because of the statements:

h_count.val.max  # line 30
v_count.val.max  # line 33

I can print their values just fine so they definitely evaluate to integers, but if I replace them with their literal values then it properly converts. I couldn't find anything about this in the myhdl issue tracker, but I don't want to add a false issue because of a newbie's mistake. Is there a proper way to use Signal.val.max or do I just avoid it? Here's the full code:

from myhdl import Signal, intbv, always_comb, always, toVHDL


def vga_timer(clk, x, y, h_sync, v_sync, vidon, width=800, height=600, frequency=72,
          left_buffer=0, right_buffer=0, top_buffer=0, bottom_buffer=0):
    # load vga constants by resolution
    resolution = (width, height, frequency)
    supported_resolutions = {(640, 480, 60): (16, 96, 48, 10, 2, 33, 0),
                         (800, 600, 60): (40, 128, 88, 1, 4, 23, 1),
                         (800, 600, 72): (56, 120, 64, 37, 6, 23, 1),
                         (1024, 768, 60): (24, 136, 160, 3, 6, 29, 0),
                         (1280, 720, 60): (72, 80, 216, 3, 5, 22, 1),
                         (1920, 1080, 60): (88, 44, 148, 4, 5, 36, 1)}
    assert resolution in supported_resolutions, "%ix%i @ %ifps not a supported resolution" % (width, height, frequency)
    screen_constants = supported_resolutions.get(resolution)

    # h for horizontal variables and signals, v for vertical constants and signals
    h_front_porch, h_sync_width, h_back_porch, v_front_porch, v_sync_width, v_back_porch, polarity = screen_constants

    h_count = Signal(intbv(0, 0, width + h_front_porch + h_sync_width + h_back_porch))
    v_count = Signal(intbv(0, 0, height + v_front_porch + v_sync_width + v_back_porch))

    print(h_count.val.max)
    print(v_count.val.max)

    @always(clk.posedge)
    def counters():
        h_count.next = h_count + 1
        v_count.next = v_count
        if h_count == 1040 - 1:  # h_count.val.max - 1:
            h_count.next = 0
            v_count.next = v_count + 1
            if v_count == 666 - 1:  # v_count.val.max - 1:
                v_count.next = 0

    # determines h_sync and v_sync
    @always_comb
    def sync_pulses():
        h_sync_left = width - left_buffer + h_front_porch
        h_sync_right = h_sync_left + h_sync_width
        h_sync.next = polarity
        if h_sync_left <= h_count and h_count < h_sync_right:
             h_sync.next = not polarity

        v_sync_left = height - top_buffer + v_front_porch
        v_sync_right = v_sync_left + v_sync_width
        v_sync.next = polarity
        if v_sync_left <= v_count and v_count < v_sync_right:
            v_sync.next = not polarity

    @always_comb
    def blanking():
        vidon.next = 0
        if h_count < width - left_buffer - right_buffer and v_count < height - top_buffer - bottom_buffer:
            vidon.next = 1

    @always_comb
    def x_y_adjust():
        # x and y are only used when vidon = 1. during this time x = h_count and y = v_count
        x.next = h_count[len(x.val):]
        y.next = v_count[len(y.val):]

    return counters, sync_pulses, blanking, x_y_adjust

width = 800
height = 600
frequency = 72

clk = Signal(bool(0))
x = Signal(intbv(0)[(width-1).bit_length():])
y = Signal(intbv(0)[(height-1).bit_length():])
h_sync = Signal(bool(0))
v_sync = Signal(bool(0))
vidon = Signal(bool(0))

vga_timer_inst = toVHDL(vga_timer, clk, x, y, h_sync, v_sync, vidon, width, height, frequency)

Any miscellaneous advice on my code is also welcome.

You may have found this out by now, but if you want convertible code, you can't use the signal qualities (min, max, number of bits, etc.) in the combinational or sequential blocks. You can use them in constant assignments outside these blocks, though. So if you put these instead of your print statements: h_counter_max = h_count.val.max - 1 v_counter_max = v_count.val.max - 1 you can use h_counter_max and v_counter_max in your tests on line 30 and 33.

可以在最新版本中使用minmax属性。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM