Implement read

This commit is contained in:
Andrew Kay
2020-07-05 18:38:59 -05:00
parent d8464625e7
commit e2974b2365
4 changed files with 108 additions and 16 deletions

View File

@@ -6,13 +6,16 @@ module coax_rx (
input reset,
output active,
output error,
output reg [9:0] data
output reg [9:0] data,
output reg data_available = 0,
input read
);
parameter CLOCKS_PER_BIT = 8;
localparam LOSS_OF_MID_BIT_TRANSITION_ERROR = 10'b0000000001;
localparam PARITY_ERROR = 10'b0000000010;
localparam INVALID_END_SEQUENCE_ERROR = 10'b0000000100;
localparam OVERFLOW_ERROR = 10'b0000001000;
localparam IDLE = 0;
localparam START_SEQUENCE_1 = 1;
@@ -42,12 +45,15 @@ module coax_rx (
reg next_bit_timer_reset;
reg [9:0] next_data;
reg next_data_available;
reg [9:0] internal_data;
reg [9:0] next_internal_data;
reg [3:0] bit_counter = 0;
reg [3:0] next_bit_counter;
reg previous_read;
wire sample;
wire synchronized;
@@ -68,9 +74,10 @@ module coax_rx (
next_bit_timer_reset = 0;
next_data = data;
next_data_available = data_available;
next_bit_counter = bit_counter;
next_internal_data = internal_data;
next_bit_counter = bit_counter;
case (state)
IDLE:
@@ -254,7 +261,17 @@ module coax_rx (
// Even parity includes the sync bit.
if (rx == ^{ 1'b1, internal_data })
begin
next_state = SYNC_BIT;
if (!data_available)
begin
next_data_available = 1;
next_data = internal_data;
next_state = SYNC_BIT;
end
else
begin
next_data = OVERFLOW_ERROR;
next_state = ERROR;
end
end
else
begin
@@ -294,31 +311,37 @@ module coax_rx (
always @(posedge clk)
begin
state <= next_state;
state_counter <= (state == next_state) ? state_counter + 1 : 0;
bit_timer_reset <= next_bit_timer_reset;
data <= next_data;
data_available <= next_data_available;
bit_counter <= next_bit_counter;
internal_data <= next_internal_data;
bit_counter <= next_bit_counter;
if (reset)
begin
bit_timer_reset <= 1;
state_counter <= 0;
state <= IDLE;
state_counter <= 0;
data <= 10'b0000000000;
data_available <= 0;
bit_counter <= 0;
internal_data <= 10'b0000000000;
bit_counter <= 0;
end
else if (data_available && !read && previous_read)
begin
data_available <= 0;
end
previous_rx <= rx;
previous_state <= state;
previous_read <= read;
end
assign active = (state >= SYNC_BIT && state <= PARITY_BIT);

View File

@@ -17,8 +17,8 @@ set_io --warn-no-port reset E1 # 9
#set_io --warn-no-port rx_enable E1 # 9
set_io --warn-no-port rx_active G2 # 10
set_io --warn-no-port rx_error H1 # 11
#set_io --warn-no-port rx_data_available xx # xx
#set_io --warn-no-port rx_data_read J1 # 12
set_io --warn-no-port rx_data_available J1 # 12
set_io --warn-no-port rx_read H2 # 13
# Shared data bus
set_io --warn-no-port data[9] B6 # 23
@@ -32,6 +32,6 @@ set_io --warn-no-port data[2] D8
set_io --warn-no-port data[1] D9
set_io --warn-no-port data[0] H9 # 14
set_io --warn-no-port debug H2 # 13
set_io --warn-no-port debug A6 # 24
set_io --warn-no-port usb_pu A3

View File

@@ -7,6 +7,8 @@ module top (
input rx,
output rx_active,
output rx_error,
output rx_data_available,
input rx_read,
// Shared data bus
inout [9:0] data,
@@ -35,12 +37,18 @@ module top (
);
reg rx_0 = 0;
reg rx_1 = 1;
reg rx_1 = 0;
reg rx_read_0 = 0;
reg rx_read_1 = 0;
always @(posedge clk_38mhz)
begin
rx_0 <= rx;
rx_1 <= rx_0;
rx_read_0 <= rx_read;
rx_read_1 <= rx_read_0;
end
wire [9:0] rx_data;
@@ -53,7 +61,9 @@ module top (
.reset(reset),
.active(rx_active),
.error(rx_error),
.data(rx_data)
.data(rx_data),
.data_available(rx_data_available),
.read(rx_read_1)
);
assign data = rx_data;

View File

@@ -13,20 +13,21 @@ module coax_rx_tb;
reg rx = 0;
reg reset = 0;
reg read = 0;
coax_rx #(
.CLOCKS_PER_BIT(8)
) dut (
.clk(clk),
.rx(rx),
.reset(reset)
.reset(reset),
.read(read)
);
initial begin
$dumpfile("coax_rx_tb.vcd");
$dumpvars(0, coax_rx_tb);
/*
test_1;
test_2;
test_3;
@@ -42,8 +43,8 @@ module coax_rx_tb;
test_13;
test_14;
test_15;
*/
test_16;
test_17;
$finish;
end
@@ -437,7 +438,7 @@ module coax_rx_tb;
rx_bit(1); // LSB DATA_BIT
rx_bit(1); // PARITY_BIT
rx_bit(0);
rx = 1;
#16;
rx = 0;
@@ -446,10 +447,68 @@ module coax_rx_tb;
`assert_equal(dut.state, dut.IDLE, "state should be IDLE");
`assert_high(dut.data_available, "data_available should be HIGH");
`assert_equal(dut.data, 10'b0110110011, "data not correct")
read = 1;
#2;
read = 0;
#2;
`assert_low(dut.data_available, "data_available should be LOW");
$display("END: test_16");
end
endtask
task test_17;
begin
$display("START: test_17");
`assert_equal(dut.state, dut.IDLE, "state should be IDLE");
rx_start_sequence;
rx_bit(1); // SYNC_BIT
rx_bit(0); // MSB DATA_BIT
rx_bit(1);
rx_bit(1);
rx_bit(0);
rx_bit(1);
rx_bit(1);
rx_bit(0);
rx_bit(0);
rx_bit(1);
rx_bit(1); // LSB DATA_BIT
rx_bit(1); // PARITY_BIT
rx_bit(1); // SYNC_BIT
rx_bit(1); // MSB DATA_BIT
rx_bit(0);
rx_bit(1);
rx_bit(1);
rx_bit(0);
rx_bit(1);
rx_bit(1);
rx_bit(0);
rx_bit(1);
rx_bit(1); // LSB DATA_BIT
rx_bit(0); // PARITY_BIT
`assert_equal(dut.state, dut.ERROR, "State should be ERROR");
`assert_high(dut.error, "error should be HIGH");
`assert_equal(dut.data, dut.OVERFLOW_ERROR, "data should be OVERFLOW_ERROR");
dut_reset;
#16;
`assert_equal(dut.state, dut.IDLE, "state should be IDLE");
$display("END: test_17");
end
endtask
task dut_reset;
begin
reset = 1;