mirror of
https://github.com/lowobservable/coax.git
synced 2026-02-27 01:19:52 +00:00
Initial coax_rx_bit_timer
This commit is contained in:
97
interface2/rtl/coax_rx_bit_timer.v
Normal file
97
interface2/rtl/coax_rx_bit_timer.v
Normal file
@@ -0,0 +1,97 @@
|
||||
`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 * 1.25)
|
||||
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 * 0.75)
|
||||
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 * 0.75)
|
||||
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
|
||||
@@ -3,7 +3,9 @@ VVP ?= vvp
|
||||
|
||||
RTL = ../rtl
|
||||
|
||||
all:
|
||||
all: coax_rx_bit_timer_tb.vcd
|
||||
|
||||
coax_rx_bit_timer_tb: coax_rx_bit_timer_tb.v $(RTL)/coax_rx_bit_timer.v
|
||||
|
||||
clean:
|
||||
rm -f *_tb *.vcd
|
||||
@@ -12,6 +14,6 @@ clean:
|
||||
$(IVERILOG) -o $@ $^
|
||||
|
||||
%_tb.vcd: %_tb
|
||||
$(VVP) -N $< -lxt2
|
||||
$(VVP) -N $<
|
||||
|
||||
.PHONY: all, clean
|
||||
|
||||
85
interface2/tests/coax_rx_bit_timer_tb.v
Normal file
85
interface2/tests/coax_rx_bit_timer_tb.v
Normal file
@@ -0,0 +1,85 @@
|
||||
`default_nettype none
|
||||
|
||||
module coax_rx_bit_timer_tb();
|
||||
reg clk = 0;
|
||||
|
||||
initial begin
|
||||
forever begin
|
||||
#1 clk <= ~clk;
|
||||
end
|
||||
end
|
||||
|
||||
reg rx = 0;
|
||||
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
|
||||
rx_bit(1);
|
||||
rx_bit(0);
|
||||
rx_bit(1);
|
||||
|
||||
// Delayed
|
||||
rx_bit_custom(0, 9, 8);
|
||||
|
||||
// Shortened
|
||||
rx_bit_custom(0, 6, 7);
|
||||
|
||||
// Stuck
|
||||
rx_bit_custom(1, 24, 8);
|
||||
|
||||
// Reset
|
||||
reset = 1;
|
||||
#2;
|
||||
reset = 0;
|
||||
|
||||
rx_bit(1);
|
||||
|
||||
#32;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
task rx_bit (
|
||||
input bit
|
||||
);
|
||||
begin
|
||||
rx = !bit;
|
||||
#8;
|
||||
rx = bit;
|
||||
#8;
|
||||
rx = 0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task rx_bit_custom (
|
||||
input bit,
|
||||
input [15:0] first_half_duration,
|
||||
input [15:0] second_half_duration
|
||||
);
|
||||
begin
|
||||
rx = !bit;
|
||||
#first_half_duration;
|
||||
rx = bit;
|
||||
#second_half_duration;
|
||||
rx = 0;
|
||||
end
|
||||
endtask
|
||||
endmodule
|
||||
Reference in New Issue
Block a user