diff --git a/rtl/nrzi_decode.v b/rtl/nrzi_decode.v index ece1326..065cfd6 100644 --- a/rtl/nrzi_decode.v +++ b/rtl/nrzi_decode.v @@ -7,31 +7,53 @@ module nrzi_decode ( input clk, + input rst, input [1:0] nrzi, input [1:0] nrzi_valid, output reg [1:0] nrz, output reg [1:0] nrz_valid ); - reg [1:0] nrz_next; - reg nrzi_last; - reg nrzi_last_next; + reg [1:0] nrz_next, nrz_valid_next; + reg nrzi_last, nrzi_last_next, nrzi_last_valid, nrzi_last_valid_next; + initial nrz_valid = 0; + initial nrzi_last_valid = 0; always @(*) begin nrz_next[0] = nrzi[1] ^ nrzi[0]; nrz_next[1] = nrzi[1] ^ nrzi_last; nrzi_last_next = nrzi_last; - if (nrzi_valid != 0) - nrzi_last_next = nrzi[1]; - if (nrzi_valid & 2) + nrzi_last_valid_next = 1'b1; + if (nrzi_valid[1]) nrzi_last_next = nrzi[0]; + else if (nrzi_valid[0]) + nrzi_last_next = nrzi[1]; + else + nrzi_last_valid_next = nrzi_last_valid; + + nrz_valid_next = nrzi_valid; + if (!nrzi_last_valid) begin + nrz_valid_next = 0; + if (nrzi_valid[1]) begin + nrz_valid_next = 2'b1; + nrz_next[1] = nrz_next[0]; + end + end end always @(posedge clk) begin - nrzi_last <= nrzi_last_next; - nrz_valid <= nrzi_valid; - nrz <= nrz_next; + if (rst) begin + nrzi_last <= 1'bX; + nrzi_last_valid <= 1'b0; + nrz_valid <= 2'b0; + nrz <= 2'b0; + end else begin + nrzi_last <= nrzi_last_next; + nrzi_last_valid = nrzi_last_valid_next; + nrz_valid <= nrz_valid_next; + nrz <= nrz_next; + end end endmodule diff --git a/tb/nrzi_decode.py b/tb/nrzi_decode.py index 46a760b..0447236 100644 --- a/tb/nrzi_decode.py +++ b/tb/nrzi_decode.py @@ -6,9 +6,11 @@ import random import cocotb from cocotb.clock import Clock from cocotb.regression import TestFactory -from cocotb.triggers import FallingEdge, RisingEdge, Timer +from cocotb.triggers import ClockCycles, FallingEdge, RisingEdge, Timer +from cocotb.types import LogicArray -from .util import alist, async_iter, compare_lists, timeout, send_recovered_bits, with_valids +from .nrzi_encode import nrzi_encode +from .util import alist, async_iter, compare_lists, timeout, send_recovered_bits, with_valids, print_list_at async def nrzi_decode(bits): last = 1 @@ -19,8 +21,12 @@ async def nrzi_decode(bits): @timeout(10, 'us') async def test_rx(decoder, valids): decoder.nrzi_valid.value = 0 + decoder.nrzi.value = LogicArray('X', 'X') + decoder.rst.value = 1 await Timer(1) await cocotb.start(Clock(decoder.clk, 8, units='ns').start()) + await ClockCycles(decoder.clk, 1) + decoder.rst.value = 0 ins = [random.randrange(2) for _ in range(1000)] await cocotb.start(send_recovered_bits(decoder.clk, decoder.nrzi, @@ -40,6 +46,6 @@ async def test_rx(decoder, valids): outs.append(decoder.nrz[0].value) # Ignore the first bit, since it is influenced by the initial value - compare_lists((await alist(nrzi_decode(async_iter(ins))))[1:], outs[1:]) + compare_lists((await alist(nrzi_decode(async_iter(ins))))[1:], outs) with_valids(globals(), test_rx)