Skip to content

Commit 392bc24

Browse files
committed
UartExtreme rewrite and simulation done
1 parent a045839 commit 392bc24

File tree

3 files changed

+143
-15
lines changed

3 files changed

+143
-15
lines changed

UartRxExtreme.v

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
// INFO --------------------------------------------------------------------------------
77
// Extreme minimal UART receiver optimized for 20MHz/115200 data rate
8-
8+
//
9+
// CAUTION:
10+
// optimized for 20MHz/115200
11+
// rx_sample_cntr[7:0] does never stop, but reloads on sequense start condition
12+
// initial rx_sample_cntr[7:0] value has been made 255 instead of 257 to save one precious counter register
13+
// rx_busy and rx_done fall simultaneously 0,5 bit before stop bit time end
914

1015
/* --- INSTANTIATION TEMPLATE BEGIN ---
1116
@@ -28,18 +33,20 @@ input wire clk;
2833
output reg [7:0] rx_data = 0;
2934
reg rx_data_9th_bit = 0; // {rx_data[7:0],rx_data_9th_bit} is actually a shift register
3035

31-
output wire rx_busy;
36+
output reg rx_busy = 0; // sequence control is done by rx_busy and unique high logic state of rx_data_9th_bit register
3237
output wire rx_done;
3338
input wire rxd;
3439

3540

41+
// Falling edge detector
3642
reg rxd_prev = 0;
3743
always @ (posedge clk) begin
3844
rxd_prev <= rxd;
3945
end
4046
wire start_bit_strobe = ~rx_busy && (~rxd & rxd_prev);
4147

4248

49+
// Sample counter
4350
reg [7:0] rx_sample_cntr = 0;
4451
always @ (posedge clk) begin
4552
if (start_bit_strobe) begin
@@ -50,29 +57,27 @@ always @ (posedge clk) begin
5057
end else begin
5158
rx_sample_cntr[7:0] <= rx_sample_cntr[7:0] - 1;
5259
end // rx_sample_cntr
53-
end // ~rx_busy && start_bit_strobe
60+
end // start_bit_strobe
5461
end
5562
wire rx_do_sample = (rx_sample_cntr[7:0] == 0);
5663

57-
64+
// Data shifting
5865
always @ (posedge clk) begin
5966
if (start_bit_strobe) begin
6067
{rx_data[7:0],rx_data_9th_bit} <= 9'b100000000;
68+
rx_busy <= 1;
6169
end // start_bit_strobe
6270

63-
if (rx_do_sample) begin
64-
if (~rx_done) begin
65-
{rx_data[7:0],rx_data_9th_bit} <= {rxd,rx_data[7:0]};
71+
if (rx_busy && rx_do_sample) begin
72+
if (rx_data_9th_bit) begin
73+
rx_busy <= 0;
6674
end else begin
67-
rx_data[7:0] <= 0;
68-
rx_data_9th_bit <= 0;
69-
end // ~rx_done
70-
end // rx_do_sample
75+
{rx_data[7:0],rx_data_9th_bit} <= {rxd,rx_data[7:0]};
76+
end
77+
end // (rx_busy && rx_do_sample)
7178
end
7279

7380
assign
74-
rx_busy = |{rx_data[7:0],rx_data_9th_bit},
75-
rx_done = rx_data_9th_bit && rx_do_sample && rxd;
81+
rx_done = (rx_busy && rx_do_sample && rx_data_9th_bit) && rxd;
7682

77-
7883
endmodule

UartTxExtreme.v

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,25 @@
55

66
// INFO --------------------------------------------------------------------------------
77
// Extreme minimal UART transmitter
8+
//
9+
// CAUTION:
10+
// optimized for 20MHz/115200
11+
// tx_busy has been made asynchronous to tx_do_sample
12+
// tx_start has no internal protection and should be rised only when tx_busy is low
813

914

1015
/* --- INSTANTIATION TEMPLATE BEGIN ---
1116
17+
reg [7:0] tx_sample_cntr = 0;
18+
always @ (posedge clk20) begin
19+
if (tx_sample_cntr[7:0] == 0) begin
20+
tx_sample_cntr[7:0] <= (173-1);
21+
end else begin
22+
tx_sample_cntr[7:0] <= tx_sample_cntr[7:0] - 1;
23+
end
24+
end
25+
wire tx_do_sample = (tx_sample_cntr[7:0] == 0);
26+
1227
UartTxExtreme UT1 (
1328
.clk(),
1429
//.tx_do_sample(),
@@ -34,7 +49,6 @@ output reg txd = 1;
3449

3550

3651
reg [9:0] tx_shifter = 0;
37-
3852
always @ (posedge clk) begin
3953
if (tx_start) begin
4054
tx_shifter[9:0] <= {1'b1,tx_data[7:0],1'b0};

UartTxExtreme_UartRxExtreme_tb.v

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//--------------------------------------------------------------------------------
2+
// SimWrapper.v
3+
// Konstantin Pavlov, pavlovconst@gmail.com
4+
//--------------------------------------------------------------------------------
5+
6+
// INFO --------------------------------------------------------------------------------
7+
//
8+
//
9+
10+
`timescale 1ns / 1ps
11+
12+
module SimWrapper();
13+
14+
reg clk200;
15+
initial begin
16+
#0 clk200 = 1;
17+
forever
18+
#2.5 clk200 = ~clk200;
19+
end
20+
21+
reg rst;
22+
initial begin
23+
#10.2 rst = 1;
24+
#5 rst = 0;
25+
//#10000;
26+
forever begin
27+
#9985 rst = ~rst;
28+
#5 rst = ~rst;
29+
end
30+
end
31+
wire nrst = ~rst;
32+
33+
reg rst_once;
34+
initial begin // initializing non-X data before PLL starts
35+
#10.2 rst_once = 1;
36+
#5 rst_once = 0;
37+
end
38+
initial begin
39+
#510.2 rst_once = 1; // PLL starts at 500ns, clock appears, so doing the reset for modules
40+
#5 rst_once = 0;
41+
end
42+
wire nrst_once = ~rst_once;
43+
44+
wire [31:0] DerivedClocks;
45+
ClkDivider CD1 (
46+
.clk(clk200),
47+
.nrst(nrst_once),
48+
.out(DerivedClocks[31:0]));
49+
defparam CD1.WIDTH = 32;
50+
51+
wire [31:0] E_DerivedClocks;
52+
EdgeDetect ED1 (
53+
.clk(clk200),
54+
.nrst(nrst_once),
55+
.in(DerivedClocks[31:0]),
56+
.rising(E_DerivedClocks[31:0]),
57+
.falling(),
58+
.both()
59+
);
60+
defparam ED1.WIDTH = 32;
61+
62+
wire [15:0] RandomNumber1;
63+
c_rand RNG1 (
64+
.clk(clk200),
65+
.rst(rst_once),
66+
.reseed(1'b0),
67+
.seed_val(DerivedClocks[31:0]),
68+
.out(RandomNumber1[15:0]));
69+
70+
reg start;
71+
initial begin
72+
#100.2 start = 1;
73+
#5 start = 0;
74+
end
75+
76+
77+
78+
reg [7:0] tx_sample_cntr = 0;
79+
80+
always @ (posedge clk200) begin
81+
if (tx_sample_cntr[7:0] == 0) begin
82+
tx_sample_cntr[7:0] <= (173-1);
83+
end else begin
84+
tx_sample_cntr[7:0] <= tx_sample_cntr[7:0] - 1;
85+
end
86+
end
87+
wire tx_do_sample = (tx_sample_cntr[7:0] == 0);
88+
89+
wire txd_pin;
90+
wire txbusy_pin;
91+
92+
UartTxExtreme UT1 (
93+
.clk(clk200),
94+
.tx_do_sample(tx_do_sample),
95+
.tx_data(RandomNumber1[7:0]),
96+
.tx_start(start),
97+
.tx_busy(txbusy_pin),
98+
.txd(txd_pin)
99+
);
100+
101+
UartRxExtreme UR1 (
102+
.clk(clk200),
103+
.rx_data(),
104+
.rx_busy(),
105+
.rx_done(),
106+
.rxd(txd_pin)
107+
);
108+
109+
endmodule

0 commit comments

Comments
 (0)