Initial attempt at receiver

This commit is contained in:
Andrew Kay
2020-02-15 17:08:55 -06:00
parent 2b81a4a961
commit 811a048685
10 changed files with 247 additions and 16 deletions

View File

@@ -5,7 +5,7 @@ TINYPROG ?= tinyprog
all: top.bin
top.json: top.v hello_world.v coax_bit_timer.v coax_tx.v
top.json: top.v hello_world.v coax_tx_bit_timer.v coax_tx.v coax_rx_bit_timer.v coax_rx.v
prog: top.bin
$(TINYPROG) -p top.bin

128
interface2/rtl/coax_rx.v Normal file
View File

@@ -0,0 +1,128 @@
`default_nettype none
module coax_rx (
input clk,
input rx,
output active
);
parameter CLOCKS_PER_BIT = 8;
reg rx_0 = 0;
reg rx_1 = 0;
localparam IDLE = 0;
localparam LINE_QUIESCE_1 = 1;
localparam LINE_QUIESCE_2 = 2;
localparam LINE_QUIESCE_3 = 3;
localparam LINE_QUIESCE_4 = 4;
localparam LINE_QUIESCE_5 = 5;
localparam LINE_QUIESCE_6 = 6;
localparam CODE_VIOLATION_1A = 7;
localparam CODE_VIOLATION_1B = 8;
localparam CODE_VIOLATION_2 = 9;
localparam CODE_VIOLATION_3A = 10;
localparam CODE_VIOLATION_3B = 11;
localparam SYNC_BIT = 12;
localparam DATA = 13;
localparam PARITY_BIT = 14;
localparam END_1 = 15;
reg [4:0] state = IDLE;
reg [4:0] next_state;
reg [4:0] previous_state = IDLE;
wire bit_timer_enable;
wire bit_timer_sample;
assign bit_timer_enable = (state != CODE_VIOLATION_1A && state != CODE_VIOLATION_3B);
coax_rx_bit_timer #(
.CLOCKS_PER_BIT(CLOCKS_PER_BIT)
) bit_timer (
.clk(clk),
.rx(rx_1),
.enable(bit_timer_enable),
.sample(bit_timer_sample)
);
reg [9:0] input_data = 10'b0;
reg [4:0] input_data_counter;
reg parity_bit;
always @(*)
begin
next_state <= state;
if (state == IDLE)
begin
if (rx_1)
next_state <= LINE_QUIESCE_1;
end
else if (state == CODE_VIOLATION_1A)
begin
if (~rx_1)
next_state <= CODE_VIOLATION_1B;
end
else if (state == CODE_VIOLATION_1B)
begin
if (~rx_1)
next_state <= CODE_VIOLATION_2;
end
else if (state == CODE_VIOLATION_3A)
begin
if (rx_1)
next_state <= CODE_VIOLATION_3B;
end
else if (state == CODE_VIOLATION_3B)
begin
if (~rx_1)
next_state <= SYNC_BIT;
end
else if (bit_timer_sample)
begin
case (state)
LINE_QUIESCE_1: next_state <= rx_1 ? LINE_QUIESCE_2 : IDLE;
LINE_QUIESCE_2: next_state <= rx_1 ? LINE_QUIESCE_3 : IDLE;
LINE_QUIESCE_3: next_state <= rx_1 ? LINE_QUIESCE_4 : IDLE;
LINE_QUIESCE_4: next_state <= rx_1 ? LINE_QUIESCE_5 : IDLE;
LINE_QUIESCE_5: next_state <= rx_1 ? LINE_QUIESCE_6 : IDLE;
LINE_QUIESCE_6: next_state <= rx_1 ? CODE_VIOLATION_1A : IDLE;
CODE_VIOLATION_2: next_state <= rx_1 ? CODE_VIOLATION_3A: IDLE;
SYNC_BIT: next_state <= rx_1 ? DATA : /* TODO: ERROR */ IDLE;
DATA: next_state <= input_data_counter == 9 ? PARITY_BIT : DATA;
PARITY_BIT: next_state <= rx_1 == parity_bit ? END_1 : /* TODO: ERROR */ IDLE;
END_1: next_state <= rx_1 ? DATA : IDLE; // TODO: END_2
endcase
end
end
always @(posedge clk)
begin
rx_0 <= rx;
rx_1 <= rx_0;
if (state == DATA)
begin
if (state != previous_state)
begin
input_data <= 10'b0;
input_data_counter <= 0;
parity_bit <= 1; // Even parity includes sync bit
end
else if (bit_timer_sample)
begin
input_data <= { input_data[8:0], rx_1 };
input_data_counter <= input_data_counter + 1;
if (rx_1)
parity_bit <= ~parity_bit;
end
end
state <= next_state;
previous_state <= state;
end
assign active = (state >= SYNC_BIT && state <= END_1);
endmodule

View File

@@ -0,0 +1,38 @@
`default_nettype none
module coax_rx_bit_timer (
input clk,
input rx,
input enable,
output sample
);
parameter CLOCKS_PER_BIT = 8;
reg previous_rx;
reg [$clog2(CLOCKS_PER_BIT/2):0] counter = 0;
always @(posedge clk)
begin
if (enable)
begin
if (counter == 0)
begin
if (rx != previous_rx)
counter <= 1;
end
else
begin
counter <= counter + 1;
end
end
else
begin
counter <= 0;
end
previous_rx <= rx;
end
assign sample = (enable && counter == CLOCKS_PER_BIT / 4);
endmodule

View File

@@ -45,7 +45,7 @@ module coax_tx (
wire bit_second_half;
wire bit_end_strobe;
coax_bit_timer #(
coax_tx_bit_timer #(
.CLOCKS_PER_BIT(CLOCKS_PER_BIT)
) bit_timer (
.clk(clk),

View File

@@ -1,6 +1,6 @@
`default_nettype none
module coax_bit_timer (
module coax_tx_bit_timer (
input clk,
input reset,
output first_half,

View File

@@ -3,6 +3,13 @@ set_io --warn-no-port tx C2
set_io --warn-no-port tx_delay C1
set_io --warn-no-port tx_inverted D2
set_io --warn-no-port rx D1
set_io --warn-no-port rx_active E2
set_io --warn-no-port rx_data_available E1
set_io --warn-no-port xxx_debug_1 G2
set_io --warn-no-port xxx_debug_2 H1
# 16MHz clock
set_io --warn-no-port clk_16mhz B2

View File

@@ -6,6 +6,10 @@ module top (
output tx,
output tx_delay,
output tx_inverted,
input rx,
output rx_active,
output xxx_debug_1,
output xxx_debug_2,
output usb_pu
);
// 19 MHz
@@ -26,12 +30,10 @@ module top (
.PLLOUTCORE(clk_19mhz)
);
hello_world hello_world (
coax_rx coax_rx (
.clk(clk_19mhz),
.tx_active(tx_active),
.tx(tx),
.tx_delay(tx_delay),
.tx_inverted(tx_inverted)
.rx(rx),
.active(rx_active)
);
assign usb_pu = 0;

View File

@@ -3,11 +3,12 @@ VVP ?= vvp
RTL = ../rtl
all: coax_bit_timer_tb.vcd coax_tx_tb.vcd hello_world_tb.vcd
all: coax_tx_bit_timer_tb.vcd coax_tx_tb.vcd coax_rx_tb.vcd hello_world_tb.vcd
coax_bit_timer_tb: coax_bit_timer_tb.v $(RTL)/coax_bit_timer.v
coax_tx_tb: coax_tx_tb.v $(RTL)/coax_bit_timer.v $(RTL)/coax_tx.v
hello_world_tb: hello_world_tb.v $(RTL)/hello_world.v $(RTL)/coax_bit_timer.v $(RTL)/coax_tx.v
coax_tx_bit_timer_tb: coax_tx_bit_timer_tb.v $(RTL)/coax_tx_bit_timer.v
coax_tx_tb: coax_tx_tb.v $(RTL)/coax_tx_bit_timer.v $(RTL)/coax_tx.v
coax_rx_tb: coax_rx_tb.v $(RTL)/coax_tx_bit_timer.v $(RTL)/coax_tx.v $(RTL)/coax_rx_bit_timer.v $(RTL)/coax_rx.v
hello_world_tb: hello_world_tb.v $(RTL)/hello_world.v $(RTL)/coax_tx_bit_timer.v $(RTL)/coax_tx.v
clean:
rm -f *_tb *.vcd

View File

@@ -0,0 +1,55 @@
`default_nettype none
module coax_rx_tb();
reg clk = 0;
initial
begin
forever
begin
#1 clk <= ~clk;
end
end
reg tx_load = 0;
reg [9:0] tx_data;
wire tx_tx;
coax_tx #(
.CLOCKS_PER_BIT(8)
) tx (
.clk(clk),
.load(tx_load),
.data(tx_data),
.tx(tx_tx)
);
coax_rx #(
.CLOCKS_PER_BIT(8)
) dut (
.clk(clk),
.rx(tx_tx)
);
initial
begin
$dumpfile("coax_rx_tb.vcd");
$dumpvars(0, coax_rx_tb);
#8
tx_data = 10'b0000000101;
tx_load = 1;
#2 tx_load = 0;
#32
tx_data = 10'b1111111111;
tx_load = 1;
#2 tx_load = 0;
repeat(1000) @(posedge clk);
$finish;
end
endmodule

View File

@@ -1,6 +1,6 @@
`default_nettype none
module coax_bit_timer_tb();
module coax_tx_bit_timer_tb();
reg clk = 0;
initial
@@ -16,7 +16,7 @@ module coax_bit_timer_tb();
wire second_half;
wire end_strobe;
coax_bit_timer #(
coax_tx_bit_timer #(
.CLOCKS_PER_BIT(8)
) dut (
.clk(clk),
@@ -28,8 +28,8 @@ module coax_bit_timer_tb();
initial
begin
$dumpfile("coax_bit_timer_tb.vcd");
$dumpvars(0, coax_bit_timer_tb);
$dumpfile("coax_tx_bit_timer_tb.vcd");
$dumpvars(0, coax_tx_bit_timer_tb);
repeat(100) @(posedge clk);