mirror of
https://github.com/lowobservable/coax.git
synced 2026-03-05 19:20:04 +00:00
More robust coax_rx start sequence detection
This commit is contained in:
2
.github/workflows/interface2_build.yml
vendored
2
.github/workflows/interface2_build.yml
vendored
@@ -49,7 +49,7 @@ jobs:
|
||||
aws-region: us-east-1
|
||||
- name: Get bitstream source SHA
|
||||
run: |
|
||||
BITSTREAM_SOURCE_SHA=$(git log -n 1 --format=%H .)
|
||||
BITSTREAM_SOURCE_SHA=$(git log -n 1 --format=%H rtl)
|
||||
echo Bitstream source SHA is $BITSTREAM_SOURCE_SHA
|
||||
echo "BITSTREAM_SOURCE_SHA=$BITSTREAM_SOURCE_SHA" >> $GITHUB_ENV
|
||||
- name: Check bitstream cache
|
||||
|
||||
@@ -26,36 +26,31 @@ module coax_rx (
|
||||
);
|
||||
parameter CLOCKS_PER_BIT = 8;
|
||||
|
||||
localparam CLOCKS_PER_HALF_BIT = CLOCKS_PER_BIT / 2;
|
||||
localparam CLOCKS_PER_2_BIT = CLOCKS_PER_BIT * 2;
|
||||
localparam CLOCKS_PER_3_BIT = CLOCKS_PER_BIT * 3;
|
||||
localparam CLOCKS_LOSS_OF_MID_BIT_TRANSITION = CLOCKS_PER_BIT + (CLOCKS_PER_BIT / 2);
|
||||
|
||||
localparam ERROR_LOSS_OF_MID_BIT_TRANSITION = 10'b0000000001;
|
||||
localparam ERROR_PARITY = 10'b0000000010;
|
||||
localparam ERROR_INVALID_END_SEQUENCE = 10'b0000000100;
|
||||
|
||||
localparam STATE_IDLE = 0;
|
||||
localparam STATE_START_SEQUENCE_1 = 1;
|
||||
localparam STATE_START_SEQUENCE_2 = 2;
|
||||
localparam STATE_START_SEQUENCE_3 = 3;
|
||||
localparam STATE_START_SEQUENCE_4 = 4;
|
||||
localparam STATE_START_SEQUENCE_5 = 5;
|
||||
localparam STATE_START_SEQUENCE_6 = 6;
|
||||
localparam STATE_START_SEQUENCE_7 = 7;
|
||||
localparam STATE_START_SEQUENCE_8 = 8;
|
||||
localparam STATE_START_SEQUENCE_9 = 9;
|
||||
localparam STATE_SYNC_BIT = 10;
|
||||
localparam STATE_DATA_BIT = 11;
|
||||
localparam STATE_PARITY_BIT = 12;
|
||||
localparam STATE_END_SEQUENCE_1 = 13;
|
||||
localparam STATE_END_SEQUENCE_2 = 14;
|
||||
localparam STATE_ERROR = 15;
|
||||
localparam STATE_FIRST_SYNC_BIT = 1;
|
||||
localparam STATE_SYNC_BIT = 2;
|
||||
localparam STATE_DATA_BIT = 3;
|
||||
localparam STATE_PARITY_BIT = 4;
|
||||
localparam STATE_END_SEQUENCE_1 = 5;
|
||||
localparam STATE_END_SEQUENCE_2 = 6;
|
||||
localparam STATE_ERROR = 7;
|
||||
|
||||
reg [3:0] state = STATE_IDLE;
|
||||
reg [3:0] next_state;
|
||||
reg [7:0] state_counter;
|
||||
reg [7:0] next_state_counter;
|
||||
reg [2:0] state = STATE_IDLE;
|
||||
reg [2:0] next_state;
|
||||
|
||||
reg previous_rx;
|
||||
|
||||
reg bit_timer_reset = 0;
|
||||
reg next_bit_timer_reset;
|
||||
reg [$clog2(CLOCKS_PER_3_BIT):0] mid_bit_counter;
|
||||
reg [$clog2(CLOCKS_PER_3_BIT):0] next_mid_bit_counter;
|
||||
|
||||
reg [9:0] next_data;
|
||||
reg next_strobe;
|
||||
@@ -70,25 +65,23 @@ module coax_rx (
|
||||
reg next_active;
|
||||
reg next_error;
|
||||
|
||||
wire sample;
|
||||
wire synchronized;
|
||||
wire ss_detector_strobe;
|
||||
|
||||
coax_rx_bit_timer #(
|
||||
coax_rx_ss_detector #(
|
||||
.CLOCKS_PER_BIT(CLOCKS_PER_BIT)
|
||||
) bit_timer (
|
||||
) ss_detector (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.enable(state == STATE_IDLE),
|
||||
.rx(rx),
|
||||
.reset(bit_timer_reset),
|
||||
.sample(sample),
|
||||
.synchronized(synchronized)
|
||||
.strobe(ss_detector_strobe)
|
||||
);
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
next_state = state;
|
||||
next_state_counter = state_counter + 1;
|
||||
|
||||
next_bit_timer_reset = 0;
|
||||
next_mid_bit_counter = mid_bit_counter + 1;
|
||||
|
||||
next_data = data;
|
||||
next_strobe = 0;
|
||||
@@ -102,288 +95,148 @@ module coax_rx (
|
||||
case (state)
|
||||
STATE_IDLE:
|
||||
begin
|
||||
next_bit_timer_reset = 1;
|
||||
|
||||
if (!rx && previous_rx)
|
||||
if (ss_detector_strobe)
|
||||
begin
|
||||
next_state = STATE_START_SEQUENCE_1;
|
||||
next_state_counter = 0;
|
||||
// The start sequence ends with a code violation, so reset
|
||||
// the mid bit counter as if the next mid-bit transition
|
||||
// is half a bit away.
|
||||
next_mid_bit_counter = CLOCKS_PER_HALF_BIT;
|
||||
next_state = STATE_FIRST_SYNC_BIT;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_1:
|
||||
STATE_FIRST_SYNC_BIT:
|
||||
begin
|
||||
if (sample)
|
||||
// This is really the first STATE_SYNC_BIT, but we treat it
|
||||
// differently and consider it part of the start sequence as
|
||||
// it must be a 1 and we don't consider the receiver active
|
||||
// until this has been detected.
|
||||
next_bit_counter = 0;
|
||||
|
||||
if (rx != previous_rx && mid_bit_counter > CLOCKS_PER_HALF_BIT)
|
||||
begin
|
||||
if (synchronized && rx)
|
||||
next_state = STATE_START_SEQUENCE_2;
|
||||
next_mid_bit_counter = 0;
|
||||
|
||||
if (rx)
|
||||
next_state = STATE_DATA_BIT;
|
||||
else
|
||||
next_state = STATE_IDLE;
|
||||
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else if (state_counter >= (CLOCKS_PER_BIT * 2))
|
||||
else if (mid_bit_counter > CLOCKS_LOSS_OF_MID_BIT_TRANSITION)
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_2:
|
||||
STATE_SYNC_BIT:
|
||||
begin
|
||||
if (sample)
|
||||
next_active = 1;
|
||||
next_bit_counter = 0;
|
||||
|
||||
if (rx != previous_rx && mid_bit_counter > CLOCKS_PER_HALF_BIT)
|
||||
begin
|
||||
if (synchronized && rx)
|
||||
next_state = STATE_START_SEQUENCE_3;
|
||||
next_mid_bit_counter = 0;
|
||||
|
||||
if (rx)
|
||||
next_state = STATE_DATA_BIT;
|
||||
else
|
||||
next_state = STATE_IDLE;
|
||||
|
||||
next_state_counter = 0;
|
||||
next_state = STATE_END_SEQUENCE_1;
|
||||
end
|
||||
else if (mid_bit_counter > CLOCKS_LOSS_OF_MID_BIT_TRANSITION)
|
||||
begin
|
||||
next_data = ERROR_LOSS_OF_MID_BIT_TRANSITION;
|
||||
next_state = STATE_ERROR;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_3:
|
||||
STATE_DATA_BIT:
|
||||
begin
|
||||
if (sample)
|
||||
next_active = 1;
|
||||
|
||||
if (rx != previous_rx && mid_bit_counter > CLOCKS_PER_HALF_BIT)
|
||||
begin
|
||||
if (synchronized && rx)
|
||||
next_state = STATE_START_SEQUENCE_4;
|
||||
next_mid_bit_counter = 0;
|
||||
|
||||
next_input_data = { input_data[8:0], rx };
|
||||
|
||||
if (bit_counter < 9)
|
||||
next_bit_counter = bit_counter + 1;
|
||||
else
|
||||
next_state = STATE_IDLE;
|
||||
|
||||
next_state_counter = 0;
|
||||
next_state = STATE_PARITY_BIT;
|
||||
end
|
||||
else if (mid_bit_counter > CLOCKS_LOSS_OF_MID_BIT_TRANSITION)
|
||||
begin
|
||||
next_data = ERROR_LOSS_OF_MID_BIT_TRANSITION;
|
||||
next_state = STATE_ERROR;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_4:
|
||||
STATE_PARITY_BIT:
|
||||
begin
|
||||
if (sample)
|
||||
next_active = 1;
|
||||
|
||||
if (rx != previous_rx && mid_bit_counter > CLOCKS_PER_HALF_BIT)
|
||||
begin
|
||||
if (synchronized && rx)
|
||||
next_state = STATE_START_SEQUENCE_5;
|
||||
if (rx == input_data_parity)
|
||||
begin
|
||||
next_strobe = 1;
|
||||
next_data = input_data;
|
||||
next_state = STATE_SYNC_BIT;
|
||||
end
|
||||
else
|
||||
next_state = STATE_IDLE;
|
||||
begin
|
||||
next_data = ERROR_PARITY;
|
||||
next_state = STATE_ERROR;
|
||||
end
|
||||
|
||||
next_state_counter = 0;
|
||||
next_mid_bit_counter = 0;
|
||||
end
|
||||
else if (mid_bit_counter > CLOCKS_LOSS_OF_MID_BIT_TRANSITION)
|
||||
begin
|
||||
next_data = ERROR_LOSS_OF_MID_BIT_TRANSITION;
|
||||
next_state = STATE_ERROR;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_5:
|
||||
begin
|
||||
if (sample)
|
||||
begin
|
||||
if (synchronized && rx)
|
||||
next_state = STATE_START_SEQUENCE_6;
|
||||
else
|
||||
next_state = STATE_IDLE;
|
||||
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_6:
|
||||
begin
|
||||
if (!rx)
|
||||
begin
|
||||
next_state = STATE_START_SEQUENCE_7;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else if (state_counter >= CLOCKS_PER_BIT)
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_7:
|
||||
STATE_END_SEQUENCE_1:
|
||||
begin
|
||||
if (rx)
|
||||
begin
|
||||
next_state = STATE_START_SEQUENCE_8;
|
||||
next_state_counter = 0;
|
||||
next_state = STATE_END_SEQUENCE_2;
|
||||
next_mid_bit_counter = 0;
|
||||
end
|
||||
else if (state_counter >= (CLOCKS_PER_BIT * 2))
|
||||
else if (mid_bit_counter > CLOCKS_PER_BIT)
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
next_state_counter = 0;
|
||||
next_data = ERROR_INVALID_END_SEQUENCE;
|
||||
next_state = STATE_ERROR;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_8:
|
||||
STATE_END_SEQUENCE_2:
|
||||
begin
|
||||
if (!rx)
|
||||
begin
|
||||
next_bit_timer_reset = 1;
|
||||
next_state = STATE_START_SEQUENCE_9;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else if (state_counter >= (CLOCKS_PER_BIT * 2))
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else if (mid_bit_counter > CLOCKS_PER_3_BIT)
|
||||
begin
|
||||
// TODO: should this go to ERROR on timeout?
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_START_SEQUENCE_9:
|
||||
STATE_ERROR:
|
||||
begin
|
||||
// This is really the first STATE_SYNC_BIT but we treat it
|
||||
// differently and consider it part of the start
|
||||
// sequence.
|
||||
|
||||
if (sample && synchronized)
|
||||
begin
|
||||
if (rx)
|
||||
begin
|
||||
next_bit_counter = 0;
|
||||
next_state = STATE_DATA_BIT;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else if (state_counter >= CLOCKS_PER_BIT)
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_SYNC_BIT:
|
||||
begin
|
||||
next_active = 1;
|
||||
|
||||
if (sample)
|
||||
begin
|
||||
if (synchronized)
|
||||
begin
|
||||
if (rx)
|
||||
begin
|
||||
next_bit_counter = 0;
|
||||
next_state = STATE_DATA_BIT;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_state = STATE_END_SEQUENCE_1;
|
||||
end
|
||||
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_data = ERROR_LOSS_OF_MID_BIT_TRANSITION;
|
||||
next_state = STATE_ERROR;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_DATA_BIT:
|
||||
begin
|
||||
next_active = 1;
|
||||
|
||||
if (sample)
|
||||
begin
|
||||
if (synchronized)
|
||||
begin
|
||||
next_input_data = { input_data[8:0], rx };
|
||||
|
||||
if (bit_counter < 9)
|
||||
begin
|
||||
next_bit_counter = bit_counter + 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_state = STATE_PARITY_BIT;
|
||||
end
|
||||
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_data = ERROR_LOSS_OF_MID_BIT_TRANSITION;
|
||||
next_state = STATE_ERROR;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_PARITY_BIT:
|
||||
begin
|
||||
next_active = 1;
|
||||
|
||||
if (sample)
|
||||
begin
|
||||
if (synchronized)
|
||||
begin
|
||||
if (rx == input_data_parity)
|
||||
begin
|
||||
next_strobe = 1;
|
||||
next_data = input_data;
|
||||
next_state = STATE_SYNC_BIT;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_data = ERROR_PARITY;
|
||||
next_state = STATE_ERROR;
|
||||
end
|
||||
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_data = ERROR_LOSS_OF_MID_BIT_TRANSITION;
|
||||
next_state = STATE_ERROR;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_END_SEQUENCE_1:
|
||||
begin
|
||||
if (rx)
|
||||
begin
|
||||
next_state = STATE_END_SEQUENCE_2;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else if (state_counter >= CLOCKS_PER_BIT)
|
||||
begin
|
||||
next_data = ERROR_INVALID_END_SEQUENCE;
|
||||
next_state = STATE_ERROR;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_END_SEQUENCE_2:
|
||||
begin
|
||||
// TODO: should this go to ERROR on timeout?
|
||||
if (!rx)
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
else if (state_counter >= (CLOCKS_PER_BIT * 2))
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
next_state_counter = 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_ERROR:
|
||||
begin
|
||||
next_error = 1;
|
||||
end
|
||||
next_error = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
state <= next_state;
|
||||
state_counter <= next_state_counter;
|
||||
|
||||
bit_timer_reset <= next_bit_timer_reset;
|
||||
mid_bit_counter <= next_mid_bit_counter;
|
||||
|
||||
data <= next_data;
|
||||
strobe <= next_strobe;
|
||||
@@ -400,8 +253,6 @@ module coax_rx (
|
||||
|
||||
if (reset)
|
||||
begin
|
||||
bit_timer_reset <= 1;
|
||||
|
||||
state <= STATE_IDLE;
|
||||
|
||||
strobe <= 0;
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
// Copyright (c) 2020, Andrew Kay
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module coax_rx_bit_timer (
|
||||
input clk,
|
||||
input rx,
|
||||
input reset,
|
||||
output reg sample,
|
||||
output reg synchronized
|
||||
);
|
||||
parameter CLOCKS_PER_BIT = 8;
|
||||
|
||||
localparam IDLE = 0;
|
||||
localparam SYNCHRONIZED = 1;
|
||||
localparam UNSYNCHRONIZED = 2;
|
||||
|
||||
reg [1:0] state = IDLE;
|
||||
reg [1:0] next_state;
|
||||
|
||||
reg previous_rx;
|
||||
|
||||
reg [$clog2(CLOCKS_PER_BIT*2):0] transition_counter = 0;
|
||||
reg [$clog2(CLOCKS_PER_BIT*2):0] next_transition_counter;
|
||||
reg [$clog2(CLOCKS_PER_BIT):0] bit_counter = 0;
|
||||
reg [$clog2(CLOCKS_PER_BIT):0] next_bit_counter;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
next_state = state;
|
||||
|
||||
sample = 0;
|
||||
synchronized = 0;
|
||||
|
||||
next_transition_counter = transition_counter;
|
||||
next_bit_counter = bit_counter;
|
||||
|
||||
case (state)
|
||||
IDLE:
|
||||
begin
|
||||
if (rx != previous_rx)
|
||||
begin
|
||||
next_transition_counter = 0;
|
||||
next_bit_counter = CLOCKS_PER_BIT / 2;
|
||||
|
||||
next_state = SYNCHRONIZED;
|
||||
end
|
||||
end
|
||||
|
||||
SYNCHRONIZED:
|
||||
begin
|
||||
if (transition_counter < (CLOCKS_PER_BIT + (CLOCKS_PER_BIT / 4)))
|
||||
next_transition_counter = transition_counter + 1;
|
||||
else
|
||||
next_state = UNSYNCHRONIZED;
|
||||
|
||||
synchronized = 1;
|
||||
|
||||
if (bit_counter < CLOCKS_PER_BIT)
|
||||
next_bit_counter = bit_counter + 1;
|
||||
else
|
||||
next_bit_counter = 0;
|
||||
|
||||
if (rx != previous_rx && transition_counter > (CLOCKS_PER_BIT / 2))
|
||||
begin
|
||||
next_transition_counter = 0;
|
||||
next_bit_counter = CLOCKS_PER_BIT / 2;
|
||||
end
|
||||
|
||||
if (bit_counter == ((CLOCKS_PER_BIT / 4) * 3))
|
||||
sample = 1;
|
||||
end
|
||||
|
||||
UNSYNCHRONIZED:
|
||||
begin
|
||||
if (bit_counter < CLOCKS_PER_BIT)
|
||||
next_bit_counter = bit_counter + 1;
|
||||
else
|
||||
next_bit_counter = 0;
|
||||
|
||||
if (bit_counter == ((CLOCKS_PER_BIT / 4) * 3))
|
||||
sample = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
state <= next_state;
|
||||
|
||||
transition_counter <= next_transition_counter;
|
||||
bit_counter <= next_bit_counter;
|
||||
|
||||
if (reset)
|
||||
state <= IDLE;
|
||||
|
||||
previous_rx <= rx;
|
||||
end
|
||||
endmodule
|
||||
137
interface2/fpga/rtl/coax_rx_ss_detector.v
Normal file
137
interface2/fpga/rtl/coax_rx_ss_detector.v
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright (c) 2021, Andrew Kay
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module coax_rx_ss_detector (
|
||||
input clk,
|
||||
input reset,
|
||||
input enable,
|
||||
input rx,
|
||||
output reg strobe = 0
|
||||
);
|
||||
parameter CLOCKS_PER_BIT = 8;
|
||||
|
||||
localparam CLOCKS_PER_1_5_BIT = CLOCKS_PER_BIT + (CLOCKS_PER_BIT / 2);
|
||||
localparam CLOCKS_PER_2_BIT = CLOCKS_PER_BIT * 2;
|
||||
localparam CLOCKS_PER_2_5_BIT = (CLOCKS_PER_BIT * 2) + (CLOCKS_PER_BIT / 2);
|
||||
localparam CLOCKS_PER_3_5_BIT = (CLOCKS_PER_BIT * 3) + (CLOCKS_PER_BIT / 2);
|
||||
|
||||
// Number of pulses (or "bits") required before the code violation.
|
||||
localparam PULSE_COUNT = 5;
|
||||
|
||||
localparam STATE_IDLE = 0;
|
||||
localparam STATE_PULSE = 1;
|
||||
localparam STATE_CODE_VIOLATION_FIRST_HALF = 2;
|
||||
localparam STATE_CODE_VIOLATION_SECOND_HALF = 3;
|
||||
|
||||
reg [1:0] state = STATE_IDLE;
|
||||
reg [1:0] next_state;
|
||||
|
||||
reg next_strobe;
|
||||
|
||||
reg [$clog2(CLOCKS_PER_3_5_BIT):0] rx_negedge_counter;
|
||||
reg [$clog2(CLOCKS_PER_3_5_BIT):0] next_rx_negedge_counter;
|
||||
|
||||
reg [$clog2(PULSE_COUNT-1):0] pulse_counter;
|
||||
reg [$clog2(PULSE_COUNT-1):0] next_pulse_counter;
|
||||
|
||||
reg previous_rx;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
next_state = state;
|
||||
|
||||
next_strobe = 0;
|
||||
|
||||
// Count the clocks since the last negedge.
|
||||
next_rx_negedge_counter = rx_negedge_counter + 1;
|
||||
|
||||
if (!rx && previous_rx)
|
||||
next_rx_negedge_counter = 0;
|
||||
|
||||
next_pulse_counter = pulse_counter;
|
||||
|
||||
case (state)
|
||||
STATE_IDLE:
|
||||
begin
|
||||
if (!rx && previous_rx)
|
||||
next_state = STATE_PULSE;
|
||||
|
||||
// Consider this the first pulse.
|
||||
next_pulse_counter = 1;
|
||||
end
|
||||
|
||||
STATE_PULSE:
|
||||
begin
|
||||
if (!rx && previous_rx)
|
||||
begin
|
||||
if (pulse_counter == (PULSE_COUNT - 1))
|
||||
next_state = STATE_CODE_VIOLATION_FIRST_HALF;
|
||||
else
|
||||
next_pulse_counter = pulse_counter + 1;
|
||||
end
|
||||
else if (rx_negedge_counter > CLOCKS_PER_1_5_BIT)
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_CODE_VIOLATION_FIRST_HALF:
|
||||
begin
|
||||
if (rx && !previous_rx && rx_negedge_counter > CLOCKS_PER_BIT)
|
||||
next_state = STATE_CODE_VIOLATION_SECOND_HALF;
|
||||
else if (rx_negedge_counter > CLOCKS_PER_2_BIT)
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
|
||||
STATE_CODE_VIOLATION_SECOND_HALF:
|
||||
begin
|
||||
// Although this is a negedge, the negedge_counter will not
|
||||
// reset until the next clock cycle so this comparison is valid.
|
||||
if (!rx && rx_negedge_counter > CLOCKS_PER_2_5_BIT)
|
||||
begin
|
||||
next_strobe = 1;
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
else if (rx_negedge_counter > CLOCKS_PER_3_5_BIT)
|
||||
begin
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
state <= next_state;
|
||||
|
||||
strobe <= next_strobe;
|
||||
|
||||
rx_negedge_counter <= next_rx_negedge_counter;
|
||||
pulse_counter <= next_pulse_counter;
|
||||
|
||||
if (reset || !enable)
|
||||
begin
|
||||
state <= STATE_IDLE;
|
||||
|
||||
strobe <= 0;
|
||||
|
||||
rx_negedge_counter <= 0;
|
||||
pulse_counter <= 0;
|
||||
end
|
||||
|
||||
previous_rx <= rx;
|
||||
end
|
||||
endmodule
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
add_file -verilog -lib work "coax_buffered_rx.v"
|
||||
add_file -verilog -lib work "coax_rx.v"
|
||||
add_file -verilog -lib work "coax_rx_bit_timer.v"
|
||||
add_file -verilog -lib work "coax_rx_ss_detector.v"
|
||||
add_file -verilog -lib work "coax_tx.v"
|
||||
add_file -verilog -lib work "coax_tx_bit_timer.v"
|
||||
add_file -verilog -lib work "coax_tx_distorter.v"
|
||||
|
||||
@@ -6,14 +6,14 @@ TESTS = $(patsubst %.v,%,$(wildcard *_tb.v))
|
||||
all: test
|
||||
|
||||
coax_buffer_tb: coax_buffer_tb.v $(RTL)/coax_buffer.v $(RTL)/third_party/*.v
|
||||
coax_buffered_rx_tb: coax_buffered_rx_tb.v $(RTL)/coax_buffered_rx.v $(RTL)/coax_rx.v $(RTL)/coax_rx_bit_timer.v $(RTL)/coax_buffer.v $(RTL)/third_party/*.v
|
||||
coax_buffered_rx_tb: coax_buffered_rx_tb.v $(RTL)/coax_buffered_rx.v $(RTL)/coax_rx.v $(RTL)/coax_rx_ss_detector.v $(RTL)/coax_buffer.v $(RTL)/third_party/*.v
|
||||
coax_buffered_tx_tb: coax_buffered_tx_tb.v $(RTL)/coax_buffered_tx.v $(RTL)/coax_tx.v $(RTL)/coax_tx_bit_timer.v $(RTL)/coax_buffer.v $(RTL)/third_party/*.v
|
||||
coax_rx_bit_timer_tb: coax_rx_bit_timer_tb.v $(RTL)/coax_rx_bit_timer.v
|
||||
coax_rx_tb: coax_rx_tb.v $(RTL)/coax_rx.v $(RTL)/coax_rx_bit_timer.v
|
||||
coax_rx_tb: coax_rx_tb.v $(RTL)/coax_rx.v $(RTL)/coax_rx_ss_detector.v
|
||||
coax_tx_bit_timer_tb: coax_tx_bit_timer_tb.v $(RTL)/coax_tx_bit_timer.v
|
||||
coax_tx_distorter_tb: coax_tx_distorter_tb.v $(RTL)/coax_tx_distorter.v
|
||||
coax_tx_tb: coax_tx_tb.v $(RTL)/coax_tx.v $(RTL)/coax_tx_bit_timer.v
|
||||
control_tb: control_tb.v $(RTL)/control.v $(RTL)/coax_buffered_tx.v $(RTL)/coax_tx.v $(RTL)/coax_tx_bit_timer.v $(RTL)/coax_buffer.v $(RTL)/third_party/*.v
|
||||
regression_memorex_tb: regression_memorex_tb.v $(RTL)/coax_rx.v $(RTL)/coax_rx_ss_detector.v
|
||||
|
||||
test: $(TESTS)
|
||||
./run_tests.sh
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
`default_nettype none
|
||||
|
||||
`include "mock_tx.v"
|
||||
|
||||
module coax_rx_bit_timer_tb;
|
||||
reg clk = 0;
|
||||
|
||||
initial
|
||||
begin
|
||||
forever
|
||||
begin
|
||||
#1 clk <= ~clk;
|
||||
end
|
||||
end
|
||||
|
||||
wire rx;
|
||||
|
||||
mock_tx mock_tx (
|
||||
.tx(rx)
|
||||
);
|
||||
|
||||
reg reset = 0;
|
||||
wire sample;
|
||||
wire synchronized;
|
||||
|
||||
coax_rx_bit_timer #(
|
||||
.CLOCKS_PER_BIT(8)
|
||||
) dut (
|
||||
.clk(clk),
|
||||
.rx(rx),
|
||||
.reset(reset),
|
||||
.sample(sample),
|
||||
.synchronized(synchronized)
|
||||
);
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("coax_rx_bit_timer_tb.vcd");
|
||||
$dumpvars(0, coax_rx_bit_timer_tb);
|
||||
|
||||
// Idle
|
||||
#32;
|
||||
|
||||
// Perfect
|
||||
mock_tx.tx_bit(1);
|
||||
mock_tx.tx_bit(0);
|
||||
mock_tx.tx_bit(1);
|
||||
|
||||
// Delayed
|
||||
mock_tx.tx_bit_custom(0, 9, 8);
|
||||
|
||||
// Shortened
|
||||
mock_tx.tx_bit_custom(0, 6, 7);
|
||||
|
||||
// Stuck
|
||||
mock_tx.tx_bit_custom(1, 24, 8);
|
||||
|
||||
// Reset
|
||||
dut_reset;
|
||||
|
||||
mock_tx.tx_bit(1);
|
||||
|
||||
#32;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
task dut_reset;
|
||||
begin
|
||||
reset = 1;
|
||||
#2;
|
||||
reset = 0;
|
||||
end
|
||||
endtask
|
||||
endmodule
|
||||
@@ -36,29 +36,28 @@ module coax_rx_tb;
|
||||
$dumpfile("coax_rx_tb.vcd");
|
||||
$dumpvars(0, coax_rx_tb);
|
||||
|
||||
test_1;
|
||||
test_2;
|
||||
test_3;
|
||||
test_4;
|
||||
test_5;
|
||||
test_6;
|
||||
test_7;
|
||||
test_8;
|
||||
test_9;
|
||||
test_10;
|
||||
test_11;
|
||||
test_12;
|
||||
test_13;
|
||||
test_14;
|
||||
test_15;
|
||||
test_16;
|
||||
test_reset;
|
||||
test_invalid_start_sequence_1_pulse;
|
||||
test_invalid_start_sequence_2_pulse;
|
||||
test_invalid_start_sequence_3_pulse;
|
||||
test_invalid_start_sequence_4_pulse;
|
||||
test_invalid_start_sequence_code_violation_first_half;
|
||||
test_invalid_start_sequence_code_violation_second_half;
|
||||
test_invalid_sync_bit;
|
||||
test_loss_of_mid_bit_transition_error_data_bit_1;
|
||||
test_loss_of_mid_bit_transition_error_data_bit_5;
|
||||
test_loss_of_mid_bit_transition_error_parity_bit;
|
||||
test_parity_error;
|
||||
test_loss_of_mid_bit_transition_error_sync_end_bit;
|
||||
test_invalid_end_sequence;
|
||||
test_data;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
task test_1;
|
||||
task test_reset;
|
||||
begin
|
||||
$display("START: test_1");
|
||||
$display("START: test_reset");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -68,13 +67,13 @@ module coax_rx_tb;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_1");
|
||||
$display("END: test_reset");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_2;
|
||||
task test_invalid_start_sequence_1_pulse;
|
||||
begin
|
||||
$display("START: test_2");
|
||||
$display("START: test_invalid_start_sequence_1_pulse");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -83,14 +82,15 @@ module coax_rx_tb;
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
`assert_equal(dut.ss_detector.state, dut.ss_detector.STATE_IDLE, "ss_detector.state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_2");
|
||||
$display("END: test_invalid_start_sequence_1_pulse");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_3;
|
||||
task test_invalid_start_sequence_2_pulse;
|
||||
begin
|
||||
$display("START: test_3");
|
||||
$display("START: test_invalid_start_sequence_2_pulse");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -103,14 +103,15 @@ module coax_rx_tb;
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
`assert_equal(dut.ss_detector.state, dut.ss_detector.STATE_IDLE, "ss_detector.state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_3");
|
||||
$display("END: test_invalid_start_sequence_2_pulse");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_4;
|
||||
task test_invalid_start_sequence_3_pulse;
|
||||
begin
|
||||
$display("START: test_4");
|
||||
$display("START: test_invalid_start_sequence_3_pulse");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -124,14 +125,15 @@ module coax_rx_tb;
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
`assert_equal(dut.ss_detector.state, dut.ss_detector.STATE_IDLE, "ss_detector.state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_4");
|
||||
$display("END: test_invalid_start_sequence_3_pulse");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_5;
|
||||
task test_invalid_start_sequence_4_pulse;
|
||||
begin
|
||||
$display("START: test_5");
|
||||
$display("START: test_invalid_start_sequence_4_pulse");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -146,14 +148,15 @@ module coax_rx_tb;
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
`assert_equal(dut.ss_detector.state, dut.ss_detector.STATE_IDLE, "ss_detector.state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_5");
|
||||
$display("END: test_invalid_start_sequence_4_pulse");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_6;
|
||||
task test_invalid_start_sequence_code_violation_first_half;
|
||||
begin
|
||||
$display("START: test_6");
|
||||
$display("START: test_invalid_start_sequence_code_violation_first_half");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -169,38 +172,15 @@ module coax_rx_tb;
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
`assert_equal(dut.ss_detector.state, dut.ss_detector.STATE_IDLE, "ss_detector.state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_6");
|
||||
$display("END: test_invalid_start_sequence_code_violation_first_half");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_7;
|
||||
task test_invalid_start_sequence_code_violation_second_half;
|
||||
begin
|
||||
$display("START: test_7");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
mock_tx.tx_set(1);
|
||||
#16;
|
||||
mock_tx.tx_set(0);
|
||||
|
||||
mock_tx.tx_bit(1);
|
||||
mock_tx.tx_bit(1);
|
||||
mock_tx.tx_bit(1);
|
||||
mock_tx.tx_bit(1);
|
||||
mock_tx.tx_bit(1);
|
||||
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_7");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_8;
|
||||
begin
|
||||
$display("START: test_8");
|
||||
$display("START: test_invalid_start_sequence_code_violation_second_half");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -221,16 +201,17 @@ module coax_rx_tb;
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
`assert_equal(dut.ss_detector.state, dut.ss_detector.STATE_IDLE, "ss_detector.state should be STATE_IDLE");
|
||||
|
||||
mock_tx.tx_set(0);
|
||||
|
||||
$display("END: test_8");
|
||||
$display("END: test_invalid_start_sequence_code_violation_second_half");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_9;
|
||||
task test_invalid_sync_bit;
|
||||
begin
|
||||
$display("START: test_9");
|
||||
$display("START: test_invalid_sync_bit");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -241,14 +222,15 @@ module coax_rx_tb;
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
`assert_equal(dut.ss_detector.state, dut.ss_detector.STATE_IDLE, "ss_detector.state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_9");
|
||||
$display("END: test_invalid_sync_bit");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_10;
|
||||
task test_loss_of_mid_bit_transition_error_data_bit_1;
|
||||
begin
|
||||
$display("START: test_10");
|
||||
$display("START: test_loss_of_mid_bit_transition_error_data_bit_1");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -268,13 +250,13 @@ module coax_rx_tb;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_10");
|
||||
$display("END: test_loss_of_mid_bit_transition_error_data_bit_1");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_11;
|
||||
task test_loss_of_mid_bit_transition_error_data_bit_5;
|
||||
begin
|
||||
$display("START: test_11");
|
||||
$display("START: test_loss_of_mid_bit_transition_error_data_bit_5");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -299,13 +281,13 @@ module coax_rx_tb;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_11");
|
||||
$display("END: test_loss_of_mid_bit_transition_error_data_bit_5");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_12;
|
||||
task test_loss_of_mid_bit_transition_error_parity_bit;
|
||||
begin
|
||||
$display("START: test_12");
|
||||
$display("START: test_loss_of_mid_bit_transition_error_parity_bit");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -335,13 +317,13 @@ module coax_rx_tb;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_12");
|
||||
$display("END: test_loss_of_mid_bit_transition_error_parity_bit");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_13;
|
||||
task test_parity_error;
|
||||
begin
|
||||
$display("START: test_13");
|
||||
$display("START: test_parity_error");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -372,13 +354,13 @@ module coax_rx_tb;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_13");
|
||||
$display("END: test_parity_error");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_14;
|
||||
task test_loss_of_mid_bit_transition_error_sync_end_bit;
|
||||
begin
|
||||
$display("START: test_14");
|
||||
$display("START: test_loss_of_mid_bit_transition_error_sync_end_bit");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -409,13 +391,13 @@ module coax_rx_tb;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_14");
|
||||
$display("END: test_loss_of_mid_bit_transition_error_sync_end_bit");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_15;
|
||||
task test_invalid_end_sequence;
|
||||
begin
|
||||
$display("START: test_15");
|
||||
$display("START: test_invalid_end_sequence");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -447,13 +429,13 @@ module coax_rx_tb;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
$display("END: test_15");
|
||||
$display("END: test_invalid_end_sequence");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_16;
|
||||
task test_data;
|
||||
begin
|
||||
$display("START: test_16");
|
||||
$display("START: test_data");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
@@ -478,7 +460,7 @@ module coax_rx_tb;
|
||||
|
||||
`assert_equal(dut.data, 10'b0110110011, "data not correct")
|
||||
|
||||
$display("END: test_16");
|
||||
$display("END: test_data");
|
||||
end
|
||||
endtask
|
||||
|
||||
|
||||
171
interface2/fpga/tests/regression_memorex_tb.v
Normal file
171
interface2/fpga/tests/regression_memorex_tb.v
Normal file
@@ -0,0 +1,171 @@
|
||||
`default_nettype none
|
||||
|
||||
`include "assert.v"
|
||||
|
||||
module regression_memorex_tb;
|
||||
reg clk = 0;
|
||||
|
||||
initial
|
||||
begin
|
||||
forever
|
||||
begin
|
||||
#1 clk <= ~clk;
|
||||
end
|
||||
end
|
||||
|
||||
reg rx = 0;
|
||||
reg reset = 0;
|
||||
|
||||
coax_rx #(
|
||||
.CLOCKS_PER_BIT(8)
|
||||
) dut (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.rx(rx),
|
||||
.parity(1'b1)
|
||||
);
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("regression_memorex_tb.vcd");
|
||||
$dumpvars(0, regression_memorex_tb);
|
||||
|
||||
test_1;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
task test_1;
|
||||
begin
|
||||
$display("START: test_1");
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
rx = 0;
|
||||
#20;
|
||||
rx = 1;
|
||||
#5;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#5;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#25;
|
||||
rx = 1;
|
||||
#25;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#15;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#5;
|
||||
rx = 0;
|
||||
#10;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#10;
|
||||
rx = 0;
|
||||
#20;
|
||||
rx = 1;
|
||||
#15;
|
||||
rx = 0;
|
||||
#15;
|
||||
rx = 1;
|
||||
#20;
|
||||
rx = 0;
|
||||
#15;
|
||||
rx = 1;
|
||||
#20;
|
||||
rx = 0;
|
||||
#5;
|
||||
rx = 1;
|
||||
#35;
|
||||
rx = 0;
|
||||
|
||||
#64;
|
||||
|
||||
`assert_equal(dut.state, dut.STATE_IDLE, "state should be STATE_IDLE");
|
||||
|
||||
`assert_equal(dut.data, 10'b0000001010, "data not correct")
|
||||
|
||||
$display("END: test_1");
|
||||
end
|
||||
endtask
|
||||
endmodule
|
||||
Reference in New Issue
Block a user