uart_rx: Fix incorrect handshaking

AXI stream is transferred exactly on the rising edge of the clock. Use
the current value of the signals for this, instead of past values.
Simulate a slower slave to ensure this is tested.

Fixes: a549fca ("Add UART receive module")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
Sean Anderson 2023-03-04 16:41:56 -05:00
parent 10a4199381
commit 067029ad3b
2 changed files with 13 additions and 5 deletions

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-Only // SPDX-License-Identifier: AGPL-3.0-Only
/* /*
* Copyright (C) 2022 Sean Anderson <seanga2@gmail.com> * Copyright (C) 2023 Sean Anderson <seanga2@gmail.com>
* *
* 8n1@115200; no one uses anything else (and neither do I) * 8n1@115200; no one uses anything else (and neither do I)
*/ */
@ -56,7 +56,7 @@ module uart_rx (
lfsr_next = { lfsr[9:0], lfsr[10] ^ lfsr[8] }; lfsr_next = { lfsr[9:0], lfsr[10] ^ lfsr[8] };
bits_next = bits; bits_next = bits;
data_next = data; data_next = data;
valid_next = valid && !ready_last; valid_next = valid && !ready;
overflow_next = 0; overflow_next = 0;
frame_error_next = 0; frame_error_next = 0;

View File

@ -4,10 +4,12 @@
import cocotb import cocotb
from cocotb.binary import BinaryValue from cocotb.binary import BinaryValue
from cocotb.clock import Clock from cocotb.clock import Clock
from cocotb.regression import TestFactory
from cocotb.triggers import FallingEdge, Timer from cocotb.triggers import FallingEdge, Timer
from cocotb.utils import get_sim_time, get_sim_steps from cocotb.utils import get_sim_time, get_sim_steps
from .axis_replay_buffer import recv_packet from .axis_replay_buffer import recv_packet
from .util import ClockEnable, timeout
BAUD = 4e6 BAUD = 4e6
BIT_STEPS = get_sim_steps(1 / BAUD, 'sec', round_mode='round') BIT_STEPS = get_sim_steps(1 / BAUD, 'sec', round_mode='round')
@ -22,11 +24,11 @@ async def putchar(rx, c):
rx.value = bit rx.value = bit
await Timer(BIT_STEPS) await Timer(BIT_STEPS)
@cocotb.test(timeout_time=1, timeout_unit='ms') @timeout(1, 'ms')
async def test_rx(uart): async def test_rx(uart, ratio):
uart.clk.value = BinaryValue('Z') uart.clk.value = BinaryValue('Z')
uart.rst.value = 1 uart.rst.value = 1
uart.ready.value = 1 uart.ready.value = 0
uart.rx.value = 1 uart.rx.value = 1
uart.high_speed.value = 1 uart.high_speed.value = 1
@ -34,6 +36,7 @@ async def test_rx(uart):
uart.rst.value = 0 uart.rst.value = 0
await cocotb.start(Clock(uart.clk, 8, units='ns').start()) await cocotb.start(Clock(uart.clk, 8, units='ns').start())
await FallingEdge(uart.clk) await FallingEdge(uart.clk)
ce = await cocotb.start(ClockEnable(uart.clk, uart.ready, ratio))
msg = b"Hell\0" msg = b"Hell\0"
signals = { signals = {
@ -68,6 +71,7 @@ async def test_rx(uart):
assert frame_errors == 1 assert frame_errors == 1
ce.kill()
uart.ready.value = 0 uart.ready.value = 0
await putchar(uart.rx, 0xFF) await putchar(uart.rx, 0xFF)
await putchar(uart.rx, 0) await putchar(uart.rx, 0)
@ -78,3 +82,7 @@ async def test_rx(uart):
await recv_packet(signals, (0xFF,)) await recv_packet(signals, (0xFF,))
monitor.kill() monitor.kill()
uart_tests = TestFactory(test_rx)
uart_tests.add_option('ratio', (1, 4))
uart_tests.generate_tests()