nrzi_decode: Add reset input
Most other modules in the recieve path are reset when signal_status goes low. This one didn't, and it was difficult to test because of this. In particular, we need to ensure that this module behaves correctly when switching between different bitstreams (such as for loopback). While implementing this, I found some bugs in the way that nrzi_valid was handled: it wasn't saved from when the transfer actually happened, and the data wasn't qualified properly. Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
parent
52325f241b
commit
3b836d3ad0
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue