mirror of
https://github.com/lowobservable/coax.git
synced 2026-02-27 01:19:52 +00:00
New coax_tx_rx_frontend and coax_rx_blanker modules
This commit is contained in:
56
interface2/fpga/rtl/coax_rx_blanker.v
Normal file
56
interface2/fpga/rtl/coax_rx_blanker.v
Normal file
@@ -0,0 +1,56 @@
|
||||
// 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_blanker (
|
||||
input clk,
|
||||
input reset,
|
||||
input enable,
|
||||
|
||||
input rx_input,
|
||||
input tx_active,
|
||||
|
||||
output reg rx_output
|
||||
);
|
||||
parameter DELAY_CLOCKS = 2;
|
||||
|
||||
reg rx_input_d0;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
rx_input_d0 <= rx_input;
|
||||
end
|
||||
|
||||
reg [DELAY_CLOCKS-1:0] blank;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (reset)
|
||||
blank <= { (DELAY_CLOCKS){1'b0} };
|
||||
else if (tx_active)
|
||||
blank <= { (DELAY_CLOCKS){1'b1} };
|
||||
else
|
||||
blank <= { blank[DELAY_CLOCKS-2:0], 1'b0 };
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
// TODO: should enable be delayed 1 clock to match input?
|
||||
if (!enable || !blank[DELAY_CLOCKS-1])
|
||||
rx_output <= rx_input_d0;
|
||||
else
|
||||
rx_output <= 1'b0;
|
||||
end
|
||||
endmodule
|
||||
@@ -8,6 +8,8 @@ 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"
|
||||
add_file -verilog -lib work "coax_rx_blanker.v"
|
||||
add_file -verilog -lib work "coax_tx_rx_frontend.v"
|
||||
add_file -verilog -lib work "control.v"
|
||||
add_file -verilog -lib work "spi_device.v"
|
||||
add_file -verilog -lib work "coax_buffered_tx.v"
|
||||
|
||||
@@ -20,8 +20,8 @@ module coax_tx_distorter (
|
||||
input tx_input,
|
||||
output reg active_output,
|
||||
output reg tx_output,
|
||||
output reg tx_delay,
|
||||
output reg tx_n
|
||||
output reg tx_delay_output,
|
||||
output reg tx_n_output
|
||||
);
|
||||
parameter CLOCKS_PER_BIT = 8;
|
||||
|
||||
@@ -37,8 +37,8 @@ module coax_tx_distorter (
|
||||
|
||||
active_output <= 1;
|
||||
tx_output <= tx_input;
|
||||
tx_delay <= tx_d[DELAY_CLOCKS-1];
|
||||
tx_n <= ~tx_input;
|
||||
tx_delay_output <= tx_d[DELAY_CLOCKS-1];
|
||||
tx_n_output <= ~tx_input;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@@ -46,8 +46,8 @@ module coax_tx_distorter (
|
||||
|
||||
active_output <= 0;
|
||||
tx_output <= 0;
|
||||
tx_delay <= 0;
|
||||
tx_n <= 0;
|
||||
tx_delay_output <= 0;
|
||||
tx_n_output <= 0;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
71
interface2/fpga/rtl/coax_tx_rx_frontend.v
Normal file
71
interface2/fpga/rtl/coax_tx_rx_frontend.v
Normal file
@@ -0,0 +1,71 @@
|
||||
// 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_tx_rx_frontend (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input loopback,
|
||||
input tx_active_input,
|
||||
input tx_input,
|
||||
output rx_output,
|
||||
|
||||
// The outside world...
|
||||
output tx_active_output,
|
||||
output tx_output,
|
||||
output tx_n_output,
|
||||
output tx_delay_output,
|
||||
input rx_input,
|
||||
|
||||
output rx_debug
|
||||
);
|
||||
parameter CLOCKS_PER_BIT = 8;
|
||||
|
||||
coax_tx_distorter #(
|
||||
.CLOCKS_PER_BIT(CLOCKS_PER_BIT)
|
||||
) coax_tx_distorter (
|
||||
.clk(clk),
|
||||
.active_input(!loopback && tx_active_input),
|
||||
.tx_input(tx_input),
|
||||
.active_output(tx_active_output),
|
||||
.tx_output(tx_output),
|
||||
.tx_delay_output(tx_delay_output),
|
||||
.tx_n_output(tx_n_output)
|
||||
);
|
||||
|
||||
reg [1:0] rx_input_d;
|
||||
reg internal_rx;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
rx_input_d <= { rx_input_d[0], rx_input };
|
||||
|
||||
internal_rx <= loopback ? tx_input : rx_input_d[1];
|
||||
end
|
||||
|
||||
coax_rx_blanker #(
|
||||
.DELAY_CLOCKS(2 + 4) // To account for the RX input 2FF synchronizer and more
|
||||
) coax_rx_blanker (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.enable(!loopback),
|
||||
.rx_input(internal_rx),
|
||||
.tx_active(tx_active_output),
|
||||
.rx_output(rx_output)
|
||||
);
|
||||
|
||||
assign rx_debug = internal_rx;
|
||||
endmodule
|
||||
@@ -40,13 +40,13 @@ module top (
|
||||
output gpio2,
|
||||
output gpio3
|
||||
);
|
||||
localparam CLOCKS_PER_BIT = 16;
|
||||
|
||||
reg [1:0] reset_n_d;
|
||||
reg [1:0] rx_d;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
reset_n_d <= { reset_n_d[0], reset_n };
|
||||
rx_d <= { rx_d[0], rx };
|
||||
end
|
||||
|
||||
reg reset;
|
||||
@@ -89,8 +89,6 @@ module top (
|
||||
.tx_strobe(spi_tx_strobe)
|
||||
);
|
||||
|
||||
wire loopback;
|
||||
|
||||
wire tx_reset;
|
||||
wire internal_tx_active;
|
||||
wire internal_tx;
|
||||
@@ -103,7 +101,7 @@ module top (
|
||||
wire tx_parity;
|
||||
|
||||
coax_buffered_tx #(
|
||||
.CLOCKS_PER_BIT(16),
|
||||
.CLOCKS_PER_BIT(CLOCKS_PER_BIT),
|
||||
.DEPTH(2048),
|
||||
.START_DEPTH(1536)
|
||||
) coax_buffered_tx (
|
||||
@@ -120,14 +118,8 @@ module top (
|
||||
.parity(tx_parity)
|
||||
);
|
||||
|
||||
reg internal_rx;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
internal_rx <= loopback ? internal_tx : (!internal_tx_active ? rx_d[1] : 0);
|
||||
end
|
||||
|
||||
wire rx_reset;
|
||||
wire internal_rx;
|
||||
wire rx_active;
|
||||
wire rx_error;
|
||||
wire [9:0] rx_data;
|
||||
@@ -136,7 +128,7 @@ module top (
|
||||
wire rx_parity;
|
||||
|
||||
coax_buffered_rx #(
|
||||
.CLOCKS_PER_BIT(16),
|
||||
.CLOCKS_PER_BIT(CLOCKS_PER_BIT),
|
||||
.DEPTH(2048)
|
||||
) coax_buffered_rx (
|
||||
.clk(clk),
|
||||
@@ -150,6 +142,28 @@ module top (
|
||||
.parity(rx_parity)
|
||||
);
|
||||
|
||||
wire loopback;
|
||||
wire rx_debug;
|
||||
|
||||
coax_tx_rx_frontend #(
|
||||
.CLOCKS_PER_BIT(CLOCKS_PER_BIT)
|
||||
) coax_tx_rx_frontend (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.loopback(loopback),
|
||||
.tx_active_input(internal_tx_active),
|
||||
.tx_input(internal_tx),
|
||||
.rx_output(internal_rx),
|
||||
|
||||
.tx_active_output(tx_active),
|
||||
.tx_n_output(tx_n),
|
||||
.tx_delay_output(tx_delay),
|
||||
.rx_input(rx),
|
||||
|
||||
.rx_debug(rx_debug)
|
||||
);
|
||||
|
||||
control control (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
@@ -181,20 +195,9 @@ module top (
|
||||
.rx_parity(rx_parity)
|
||||
);
|
||||
|
||||
coax_tx_distorter #(
|
||||
.CLOCKS_PER_BIT(16)
|
||||
) coax_tx_distorter (
|
||||
.clk(clk),
|
||||
.active_input(!loopback && internal_tx_active),
|
||||
.tx_input(internal_tx),
|
||||
.active_output(tx_active),
|
||||
.tx_delay(tx_delay),
|
||||
.tx_n(tx_n)
|
||||
);
|
||||
|
||||
assign irq = rx_active || rx_error;
|
||||
|
||||
assign gpio0 = rx_d[1];
|
||||
assign gpio0 = rx_debug;
|
||||
assign gpio1 = tx_active;
|
||||
assign gpio2 = rx_active;
|
||||
assign gpio3 = 0;
|
||||
|
||||
@@ -12,6 +12,8 @@ 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
|
||||
coax_rx_blanker_tb: coax_rx_blanker_tb.v $(RTL)/coax_rx_blanker.v
|
||||
coax_tx_rx_frontend_tb: coax_tx_rx_frontend_tb.v $(RTL)/coax_tx_rx_frontend.v $(RTL)/coax_tx_distorter.v $(RTL)/coax_rx_blanker.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
|
||||
|
||||
|
||||
117
interface2/fpga/tests/coax_rx_blanker_tb.v
Normal file
117
interface2/fpga/tests/coax_rx_blanker_tb.v
Normal file
@@ -0,0 +1,117 @@
|
||||
`default_nettype none
|
||||
|
||||
`include "assert.v"
|
||||
|
||||
module coax_rx_blanker_tb;
|
||||
reg clk = 0;
|
||||
|
||||
initial
|
||||
begin
|
||||
forever
|
||||
begin
|
||||
#1 clk <= ~clk;
|
||||
end
|
||||
end
|
||||
|
||||
reg reset = 0;
|
||||
reg enable = 0;
|
||||
reg rx_input = 0;
|
||||
reg tx_active = 0;
|
||||
|
||||
coax_rx_blanker #(
|
||||
.DELAY_CLOCKS(6)
|
||||
) dut (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.enable(enable),
|
||||
.rx_input(rx_input),
|
||||
.tx_active(tx_active)
|
||||
);
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("coax_rx_blanker_tb.vcd");
|
||||
$dumpvars(0, coax_rx_blanker_tb);
|
||||
|
||||
test_not_enabled;
|
||||
test_enabled_tx_not_active;
|
||||
test_enabled_tx_active;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
task test_not_enabled;
|
||||
begin
|
||||
$display("START: test_not_enabled");
|
||||
|
||||
enable = 0;
|
||||
rx_input = 1;
|
||||
|
||||
#4;
|
||||
|
||||
`assert_high(dut.rx_output, "rx_output should be HIGH");
|
||||
|
||||
rx_input = 0;
|
||||
|
||||
#4;
|
||||
|
||||
`assert_low(dut.rx_output, "rx_output should be LOW");
|
||||
|
||||
#16;
|
||||
|
||||
$display("END: test_not_enabled");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_enabled_tx_not_active;
|
||||
begin
|
||||
$display("START: test_enabled_tx_not_active");
|
||||
|
||||
enable = 1;
|
||||
rx_input = 1;
|
||||
tx_active = 0;
|
||||
|
||||
#4;
|
||||
|
||||
`assert_high(dut.rx_output, "rx_output should be HIGH");
|
||||
|
||||
rx_input = 0;
|
||||
|
||||
#4;
|
||||
|
||||
`assert_low(dut.rx_output, "rx_output should be LOW");
|
||||
|
||||
#16;
|
||||
|
||||
$display("END: test_enabled_tx_not_active");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_enabled_tx_active;
|
||||
begin
|
||||
$display("START: test_enabled_tx_active");
|
||||
|
||||
enable = 1;
|
||||
rx_input = 1;
|
||||
tx_active = 1;
|
||||
|
||||
#4;
|
||||
|
||||
`assert_low(dut.rx_output, "rx_output should be LOW");
|
||||
|
||||
tx_active = 0;
|
||||
|
||||
#4;
|
||||
|
||||
`assert_low(dut.rx_output, "rx_output should be LOW");
|
||||
|
||||
#12;
|
||||
|
||||
`assert_high(dut.rx_output, "rx_output should be HIGH");
|
||||
|
||||
#16;
|
||||
|
||||
$display("END: test_enabled_tx_active");
|
||||
end
|
||||
endtask
|
||||
endmodule
|
||||
88
interface2/fpga/tests/coax_tx_rx_frontend_tb.v
Normal file
88
interface2/fpga/tests/coax_tx_rx_frontend_tb.v
Normal file
@@ -0,0 +1,88 @@
|
||||
`default_nettype none
|
||||
|
||||
`include "assert.v"
|
||||
|
||||
module coax_tx_rx_frontend_tb;
|
||||
reg clk = 0;
|
||||
|
||||
initial
|
||||
begin
|
||||
forever
|
||||
begin
|
||||
#1 clk <= ~clk;
|
||||
end
|
||||
end
|
||||
|
||||
reg reset = 0;
|
||||
reg loopback = 0;
|
||||
reg tx_active_input = 0;
|
||||
reg tx_input = 0;
|
||||
reg rx_input = 0;
|
||||
|
||||
coax_tx_rx_frontend #(
|
||||
.CLOCKS_PER_BIT(8)
|
||||
) dut (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.loopback(loopback),
|
||||
.tx_active_input(tx_active_input),
|
||||
.tx_input(tx_input),
|
||||
.rx_input(rx_input)
|
||||
);
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("coax_tx_rx_frontend_tb.vcd");
|
||||
$dumpvars(0, coax_tx_rx_frontend_tb);
|
||||
|
||||
test_loopback;
|
||||
test_not_loopback;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
task test_loopback;
|
||||
begin
|
||||
$display("START: test_loopback");
|
||||
|
||||
loopback = 1;
|
||||
tx_active_input = 1;
|
||||
tx_input = 1;
|
||||
rx_input = 0;
|
||||
|
||||
#16;
|
||||
|
||||
tx_active_input = 0;
|
||||
tx_input = 0;
|
||||
|
||||
#8;
|
||||
|
||||
loopback = 0;
|
||||
|
||||
#16;
|
||||
|
||||
$display("END: test_loopback");
|
||||
end
|
||||
endtask
|
||||
|
||||
task test_not_loopback;
|
||||
begin
|
||||
$display("START: test_not_loopback");
|
||||
|
||||
loopback = 0;
|
||||
tx_active_input = 1;
|
||||
tx_input = 1;
|
||||
rx_input = 1;
|
||||
|
||||
#16;
|
||||
|
||||
tx_active_input = 0;
|
||||
tx_input = 0;
|
||||
rx_input = 0;
|
||||
|
||||
#16;
|
||||
|
||||
$display("END: test_not_loopback");
|
||||
end
|
||||
endtask
|
||||
endmodule
|
||||
Reference in New Issue
Block a user