diff --git a/src/timing.sv b/src/timing.sv index 6f047c3..eab7f64 100644 --- a/src/timing.sv +++ b/src/timing.sv @@ -23,8 +23,13 @@ module timing #( // Signal to trigger next counter in the chain assign next = counter >= RESOLUTION - 1 && enable; - assign sync = POLARITY ? (counter >= -SYNC_PULSE - BACK_PORCH) && (counter < -BACK_PORCH) : - ~(counter >= -SYNC_PULSE - BACK_PORCH) && (counter < -BACK_PORCH); + + // Create the sync signal + logic sync_tmp; + assign sync_tmp = (counter >= -SYNC_PULSE - BACK_PORCH) && (counter < -BACK_PORCH); + assign sync = POLARITY ? sync_tmp : ~sync_tmp; + + // Blanking assign blank = (counter >= -FRONT_PORCH - SYNC_PULSE - BACK_PORCH) && (counter < 0); // Counter logic diff --git a/src/tiny_shader_top.sv b/src/tiny_shader_top.sv index 2f8f1c8..f5ac17d 100644 --- a/src/tiny_shader_top.sv +++ b/src/tiny_shader_top.sv @@ -68,7 +68,7 @@ module tiny_shader_top ( .SYNC_PULSE (HSYNC), .BACK_PORCH (HBACK), .TOTAL (HTOTAL), - .POLARITY (1) + .POLARITY (1'b0) ) timing_hor ( .clk (clk_i), .enable (1'b1), @@ -87,7 +87,7 @@ module tiny_shader_top ( .SYNC_PULSE (VSYNC), .BACK_PORCH (VBACK), .TOTAL (VTOTAL), - .POLARITY (1) + .POLARITY (1'b0) ) timing_ver ( .clk (clk_i), .enable (next_vertical), diff --git a/test/test.py b/test/test.py index 6d857e6..044cfed 100644 --- a/test/test.py +++ b/test/test.py @@ -27,6 +27,8 @@ VSYNC = 2 VBACK = 33 +POLARITY = 0 + # Reset coroutine async def reset_dut(rst_ni, duration_ns): rst_ni.value = 0 @@ -34,6 +36,14 @@ async def reset_dut(rst_ni, duration_ns): rst_ni.value = 1 rst_ni._log.debug("Reset complete") +async def sync_frame(dut): + if POLARITY: + await FallingEdge(dut.vsync) + await FallingEdge(dut.hsync) + else: + await RisingEdge(dut.vsync) + await RisingEdge(dut.hsync) + # Draw the current frame and return it async def draw_frame(dut): screen_x = -HBACK @@ -67,8 +77,12 @@ async def draw_frame(dut): pixels[screen_x, screen_y] = (r, g, b) # Received hsync - if (dut.hsync.value == 1): - await FallingEdge(dut.hsync) + if (dut.hsync.value == POLARITY): + if POLARITY: + await FallingEdge(dut.hsync) + else: + await RisingEdge(dut.hsync) + screen_y += 1 #print(dut.timing_hor.counter.value.integer) #print(dut.timing_ver.counter.value.integer) @@ -76,16 +90,20 @@ async def draw_frame(dut): screen_x = -HBACK # Received vsync - elif (dut.vsync.value == 1): - await FallingEdge(dut.vsync) - await FallingEdge(dut.hsync) + elif (dut.vsync.value == POLARITY): + if POLARITY: + await FallingEdge(dut.vsync) + await FallingEdge(dut.hsync) + else: + await RisingEdge(dut.vsync) + await RisingEdge(dut.hsync) return image else: screen_x += 1 @cocotb.test() async def test_vga_default(dut): - """Draw one frame with the default shader""" + """Draw two frames with the default shader""" # Start the clock c = Clock(dut.clk, 10, 'ns') @@ -99,14 +117,20 @@ async def test_vga_default(dut): await reset_dut(dut.rst_n, 50) dut._log.info("Reset done") - await FallingEdge(dut.vsync) - await FallingEdge(dut.hsync) + # Sync to start of frame + await sync_frame(dut) # Start thread to draw frame task_draw_frame = await cocotb.start(draw_frame(dut)) image = await task_draw_frame.join() image.save(f"default.png") + + # Start thread to draw frame + task_draw_frame = await cocotb.start(draw_frame(dut)) + + image = await task_draw_frame.join() + image.save(f"default2.png") await ClockCycles(dut.clk, 10) @@ -165,8 +189,8 @@ async def test_vga_load(dut, shader_name='test7'): # Send new shader instructions await spi_master.write(shader, burst=True) - await FallingEdge(dut.vsync) - await FallingEdge(dut.hsync) + # Sync to start of frame + await sync_frame(dut) # Start thread to draw frame task_draw_frame = await cocotb.start(draw_frame(dut))