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.
The
min
,max
attributes can be used in the latest version.