Bit timer module

This commit is contained in:
Andrew Kay
2020-02-14 19:59:12 -06:00
parent a95e83bd5e
commit 81c6172e7b
6 changed files with 114 additions and 35 deletions

View File

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

View File

@@ -0,0 +1,33 @@
`default_nettype none
module coax_bit_timer (
input clk,
input reset,
output strobe,
output first_half,
output second_half
);
parameter CLOCKS_PER_BIT = 8;
reg [$clog2(CLOCKS_PER_BIT):0] counter = 0;
always @(posedge clk or posedge reset)
begin
if (reset)
begin
counter <= 0;
end
else
begin
if (counter == CLOCKS_PER_BIT - 1)
counter <= 0;
else
counter <= counter + 1;
end
end
assign strobe = (counter == CLOCKS_PER_BIT - 1);
assign first_half = (counter < CLOCKS_PER_BIT / 2);
assign second_half = ~first_half;
endmodule

View File

@@ -29,21 +29,32 @@ module coax_tx (
localparam END_2 = 14;
localparam END_3 = 15;
reg [$clog2(CLOCKS_PER_BIT):0] bit_counter = 0;
wire bit_strobe;
wire bit_first_half;
reg [4:0] state = IDLE;
reg [4:0] next_state;
reg [4:0] previous_state;
reg [4:0] previous_state = IDLE;
reg previous_load = 0;
reg [1:0] data_valid = 2'b00;
reg [9:0] holding_data;
reg [9:0] output_data;
reg [3:0] output_data_counter;
reg parity_bit;
reg bit_counter_reset = 0;
wire bit_strobe;
wire bit_first_half;
wire bit_second_half;
coax_bit_timer #(
.CLOCKS_PER_BIT(CLOCKS_PER_BIT)
) bit_timer (
.clk(clk),
.reset(bit_counter_reset),
.strobe(bit_strobe),
.first_half(bit_first_half),
.second_half(bit_second_half)
);
localparam TX_DELAY_CLOCKS = CLOCKS_PER_BIT / 4;
reg [TX_DELAY_CLOCKS-1:0] tx_delay_buffer;
@@ -74,21 +85,15 @@ module coax_tx (
end
end
reg previous_load = 0;
always @(posedge clk)
begin
previous_state <= state;
state <= next_state;
if (bit_counter == CLOCKS_PER_BIT - 1)
bit_counter <= 0;
else
bit_counter <= bit_counter + 1;
bit_counter_reset <= 0;
if (load && !previous_load)
begin
if (full)
begin
// TODO: error...
@@ -106,7 +111,7 @@ module coax_tx (
if (state == IDLE)
begin
bit_counter <= 0;
bit_counter_reset <= 1;
// Let's go!
state <= LINE_QUIESCE_1;
@@ -143,19 +148,7 @@ module coax_tx (
assign full = data_valid[1]; // TODO: full should be indicated to give setup time at bit 10
assign bit_strobe = (bit_counter == CLOCKS_PER_BIT - 1);
assign bit_first_half = (bit_counter < CLOCKS_PER_BIT / 2);
always @(posedge clk)
begin
// The delayed output is "stretched" to go high when active.
if (!active)
tx_delay_buffer <= { TX_DELAY_CLOCKS{1'b1} };
else
tx_delay_buffer <= { tx_delay_buffer[TX_DELAY_CLOCKS-2:0], tx };
end
assign active = ((state == LINE_QUIESCE_1 && !bit_first_half) || state > LINE_QUIESCE_1);
assign active = ((state == LINE_QUIESCE_1 && bit_second_half) || state > LINE_QUIESCE_1);
always @(*) // ??? is this best?
begin
@@ -181,6 +174,15 @@ module coax_tx (
tx <= 1;
end
always @(posedge clk)
begin
// The delayed output is "stretched" to go high when active.
if (!active)
tx_delay_buffer <= { TX_DELAY_CLOCKS{1'b1} };
else
tx_delay_buffer <= { tx_delay_buffer[TX_DELAY_CLOCKS-2:0], tx };
end
assign tx_delay = active ? tx_delay_buffer[TX_DELAY_CLOCKS-1] : 0;
assign tx_inverted = active ? ~tx : 0;
endmodule

View File

@@ -3,10 +3,11 @@ VVP ?= vvp
RTL = ../rtl
all: coax_tx_tb.vcd hello_world_tb.vcd
all: coax_bit_timer_tb.vcd coax_tx_tb.vcd hello_world_tb.vcd
coax_tx_tb: coax_tx_tb.v $(RTL)/coax_tx.v
hello_world_tb: hello_world_tb.v $(RTL)/hello_world.v $(RTL)/coax_tx.v
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
clean:
rm -f *_tb *.vcd

View File

@@ -0,0 +1,43 @@
`default_nettype none
module coax_bit_timer_tb();
reg clk = 0;
initial
begin
forever
begin
#1 clk <= ~clk;
end
end
reg reset = 0;
wire strobe;
wire first_half;
wire second_half;
coax_bit_timer #(
.CLOCKS_PER_BIT(8)
) dut (
.clk(clk),
.reset(reset),
.strobe(strobe),
.first_half(first_half),
.second_half(second_half)
);
initial
begin
$dumpfile("coax_bit_timer_tb.vcd");
$dumpvars(0, coax_bit_timer_tb);
repeat(100) @(posedge clk);
reset = 1;
#2 reset = 0;
repeat(100) @(posedge clk);
$finish;
end
endmodule

View File

@@ -31,17 +31,17 @@ module coax_tx_tb();
$dumpfile("coax_tx_tb.vcd");
$dumpvars(0, coax_tx_tb);
repeat(10) @(posedge clk);
#8
data = 10'b0000000101;
load = 1;
#8 load = 0;
#2 load = 0;
#200
#32
data = 10'b1111111111;
load = 1;
# 8 load = 0;
#2 load = 0;
repeat(1000) @(posedge clk);