Skip to content

Commit 4a25276

Browse files
committed
Update README.md and add tests/README.md
1 parent a805332 commit 4a25276

27 files changed

+149114
-11
lines changed

README.md

+86-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,94 @@
1+
<img src="images/uart01_chip.svg" title="UART01-V Chip in Verilog" align="right" width="6.3%">
2+
<br />
3+
<br />
4+
15
# uart-verilog
26

3-
8 bit UART includes tests, documentation, timing diagrams
7+
8 bit UART with tests, documentation, timing diagrams
8+
9+
&ensp;&ensp;For simulation and Electronic Design Automation
10+
11+
#### Parameters
412

5-
The baud rate is parametrized; e.g.:
13+
Selected rates, e.g.:
14+
```
15+
CLOCK_RATE = 12000000
16+
```
617
```
718
BAUD_RATE = 115200
819
```
20+
Mode 8-N-1 or 8-N-2 (8 bits data, no parity, 1 or 2 stop bits). The default 2 stop bits:
21+
```
22+
TURBO_FRAMES = 0
23+
```
24+
&ensp;&ensp;trades off maximum bandwidth against more reliable communication
25+
26+
![Multiple module design of the UART](images/Uart3ChipScreenShot.png "Hierarchy of the design showing the Verilog modules: Transmitter, Receiver, Baud clock generator")
27+
28+
#### Test benches
29+
30+
Functional.
31+
32+
&ensp;&ensp;Direct to [the tests](tests/)
33+
34+
Some text.
35+
36+
#### Running the tests on your machine
37+
38+
The test benches can be run using the open source simulator Icarus Verilog: [Installation][link-iverilogi], [Getting Started][link-iverilogs].
39+
40+
With it installed, you can run a command like the following that specifies the required input files and one output file (.vvp):
41+
42+
> iverilog -g2012 -I.. -osimout.vvp -D"DUMP_FILE_NAME=\"1.vcd\"" 1.v
43+
44+
&ensp;&ensp;(This is run in the "tests" directory, and ".." thus references the device .v files or .vh files at root level.)
45+
46+
It then requires a second step: Run the Icarus Verilog simulator/runtime to store all signal and timing data to a .vcd file (viewable signal trace):
47+
48+
> vvp simout.vvp
49+
50+
I combine these:
51+
52+
> iverilog -g2012 -I.. -osimout.vvp -D"DUMP_FILE_NAME=\"1.vcd\"" 1.v && timeout 1 >NUL && vvp simout.vvp
53+
54+
GTKWave viewer is used to view the trace (waveforms): [Installation][link-gtkwavei], [Getting Started][link-gtkwaves].
55+
56+
With GTKWave installed, just click on the .vcd file. However, to persist the view (the duration window, amount of zoom and the particular signals) that you want to see for that test bench, save it as a .gtkw file. The .gtkw file persists and is a consistent view, whereas .vcd, the data, can be regenerated at will. Thus runs can be compared. (If you haven't changed the HDL code, the runs will come out identical.)
57+
58+
<img src="tests/images/13.png" title="Simulation waveform" width="50%">
59+
60+
#### Topics: Device and circuit simulation
61+
62+
#### Related open source technology for device and circuit simulation:
63+
64+
- [HDLs][link-web-hdls] · Hardware Description Languages
65+
- [EDA][link-web-eda] · Electronic Design Automation
66+
- [FPGAs][link-web-fpgas] · Field-Programmable Gate Arrays
67+
68+
#### Related open source technology
69+
70+
[IceChips][link-icechips] devices from 7400 TTL family
71+
72+
[Icestudio][link-icestudio] and Apio built on top of IceStorm, Yosys, nextpnr
73+
74+
[Yosys][link-yosys] synthesis by Claire Wolf
75+
76+
[Icarus Verilog][link-iverilog] simulator by Stephen Williams
77+
78+
[GTKWave][link-gtkwavei] for viewing waveforms
79+
80+
## <!-- -->
981

10-
Mode 8-N-1 or 8-N-2 is parametrized. The designations mean: 8 bits data, no parity, 1 stop bit or 2 stop bits.
82+
© 2022-2023 Tim Rudy
1183

12-
© 2022 Tim Rudy
84+
[link-icechips]: https://github.com/TimRudy/ice-chips-verilog
85+
[link-icestudio]: https://icestudio.io
86+
[link-web-hdls]: https://www.google.com/search?q=Hardware+Description+Languages
87+
[link-web-eda]: https://www.google.com/search?q=Electronic+Design+Automation
88+
[link-web-fpgas]: https://www.google.com/search?q=Field-Programmable+Gate+Arrays
89+
[link-yosys]: https://github.com/YosysHQ/yosys
90+
[link-iverilog]: http://iverilog.icarus.com
91+
[link-iverilogi]: https://steveicarus.github.io/iverilog/usage/installation.html
92+
[link-iverilogs]: https://steveicarus.github.io/iverilog/usage/getting_started.html
93+
[link-gtkwavei]: http://gtkwave.sourceforge.net
94+
[link-gtkwaves]: https://gtkwave.sourceforge.net/gtkwave.pdf

Uart8Receiver.v

+3-3
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ always @(posedge clk) begin
260260
sample_count <= sample_count + 4'b1;
261261
if (!err && !in_sample || &sample_count) begin
262262
// check if this is the change to a start signal -
263-
// in_sample has met the min high hold time
264-
// any time it drops to low in this state
263+
// note that in this state, in_sample has met the min high
264+
// hold time any time it drops to low
265265
// (also in these cases, namely !{err} or tick 15 special case,
266266
// signaling of {done} is in progress)
267267
if (&sample_count) begin // reached 15, last tick, and no error
@@ -288,7 +288,7 @@ always @(posedge clk) begin
288288
state <= `IDLE;
289289
end
290290
end else if (&sample_count[3:1]) begin // reached 14 -
291-
// additional tick 15 comes from transitting the READY state
291+
// additional tick 15 comes from transiting the READY state
292292
// to get to the RESET state
293293
if (err || !in_sample) begin
294294
state <= `RESET;

ice/UART-RX.ice

+1-1
Large diffs are not rendered by default.

ice/UART.ice

+1-1
Large diffs are not rendered by default.

images/ReceiverScreenShot.png

159 KB
Loading

images/Uart3ChipScreenShot.png

92.3 KB
Loading

tests/12.v

+5-2
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,12 @@ initial begin
134134
for (t = 0; t < ENABLED_BAUD_CLOCK_STEPS; t++) begin
135135
#1000
136136
case (t)
137+
4: begin
138+
$display("%7.2fms | tx start: %d", $realtime/10000, txStart_1);
139+
$display("%7.2fms | rx done: %d", $realtime/10000, rxDone_2);
140+
$display("%7.2fms | rx data: %8b", $realtime/10000, rxByte_2);
141+
end
137142
5: begin
138-
txStart_1 = 1'b0;
139-
140143
$display("%7.2fms | tx start: %d", $realtime/10000, txStart_1);
141144
$display("%7.2fms | rx done: %d", $realtime/10000, rxDone_2);
142145
$display("%7.2fms | rx data: %8b", $realtime/10000, rxByte_2);

tests/1a.gtkw

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[*]
2+
[*] GTKWave Analyzer v3.3.81 (w)1999-2017 BSI
3+
[*] Thu Feb 09 02:05:26 2023
4+
[*]
5+
[dumpfile] "1a.vcd"
6+
[dumpfile_mtime] "Thu Feb 09 02:04:09 2023"
7+
[dumpfile_size] 1227861
8+
[savefile] "1a.gtkw"
9+
[timestart] 0
10+
[size] 1536 937
11+
[pos] -9 -9
12+
*-18.545267 1555000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
13+
[treeopen] test.
14+
[treeopen] test.uart1.
15+
[sst_width] 197
16+
[signals_width] 210
17+
[sst_expanded] 1
18+
[sst_vpaned_height] 482
19+
@22
20+
test.uart1.txInst.in_data[7:0]
21+
@28
22+
test.uart1.txClk
23+
test.uart1.txEn
24+
test.uart1.txStart
25+
test.uart1.txBusy
26+
test.uart1.txDone
27+
test.uart1.txInst.bit_index[2:0]
28+
test.uart1.txInst.state[2:0]
29+
test.uart1.txInst.out
30+
test.uart1.rxClk
31+
test.uart1.rxEn
32+
test.uart1.rxBusy
33+
test.uart1.rxDone
34+
test.uart1.rxErr
35+
test.uart1.rxInst.in
36+
test.uart1.rxInst.in_sample
37+
test.uart1.rxInst.state[2:0]
38+
test.uart1.rxInst.bit_index[2:0]
39+
@22
40+
test.uart1.rxInst.received_data[7:0]
41+
test.uart1.rxInst.out[7:0]
42+
[pattern_trace] 1
43+
[pattern_trace] 0

tests/1a.v

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
`timescale 100ns/1ns
2+
`default_nettype none
3+
4+
`include "Uart8.v"
5+
6+
module test;
7+
8+
localparam CLOCK_FREQ = 12000000; // Alhambra board
9+
localparam SIM_STEP_FREQ = 1 / 0.0000001 / 2; // this sim timescale 100ns
10+
11+
// for the simulation timeline:
12+
// ratio SIM_STEP_FREQ MHz / CLOCK_FREQ MHz gives the output waveform in proper time
13+
// (*but note all clocks and the timeline are approximate due to rounding)
14+
localparam SIM_TIMESTEP_FACTOR = SIM_STEP_FREQ / CLOCK_FREQ;
15+
16+
localparam ENABLED_BAUD_CLOCK_STEPS = 17;
17+
18+
reg clk;
19+
reg en_1;
20+
reg txStart_1;
21+
wire txBusy_1;
22+
wire rxBusy_1;
23+
wire txDone_1;
24+
wire rxDone_1;
25+
wire rxErr_1;
26+
reg [7:0] txByte_1;
27+
wire [7:0] rxByte_1;
28+
wire bus_wire;
29+
30+
Uart8 #(.CLOCK_RATE(CLOCK_FREQ)) uart1(
31+
.clk(clk),
32+
33+
// rx interface
34+
.rxEn(en_1),
35+
.rx(bus_wire),
36+
.rxBusy(rxBusy_1),
37+
.rxDone(rxDone_1),
38+
.rxErr(rxErr_1),
39+
.out(rxByte_1),
40+
41+
// tx interface
42+
.txEn(en_1),
43+
.txStart(txStart_1),
44+
.in(txByte_1),
45+
.txBusy(txBusy_1),
46+
.txDone(txDone_1),
47+
.tx(bus_wire)
48+
);
49+
50+
initial clk = 1'b0;
51+
52+
always #SIM_TIMESTEP_FACTOR clk = ~clk;
53+
54+
initial begin
55+
integer t;
56+
57+
$dumpfile(`DUMP_FILE_NAME);
58+
$dumpvars(0, test);
59+
60+
#600
61+
en_1 = 1'b0;
62+
txStart_1 = 1'b0;
63+
#600
64+
en_1 = 1'b1;
65+
66+
txByte_1 = 8'b01000101;
67+
68+
$display(" tx data: %8b", txByte_1);
69+
70+
for (t = 0; t < ENABLED_BAUD_CLOCK_STEPS; t++) begin
71+
// #1000 x 100ns == 0.1ms == 1 tx clock period (approximately) at 9600 baud
72+
#1000
73+
case (t)
74+
1: begin
75+
txStart_1 = 1'b1;
76+
77+
$display("%7.2fms | tx start: %d", $realtime/10000, txStart_1);
78+
$display("%7.2fms | tx busy: %d, tx done: %d", $realtime/10000, txBusy_1, txDone_1);
79+
$display("%7.2fms | rx data: %8b", $realtime/10000, rxByte_1);
80+
end
81+
4: begin
82+
txStart_1 = 1'b0;
83+
84+
$display("%7.2fms | tx start: %d", $realtime/10000, txStart_1);
85+
end
86+
13: begin
87+
// output is ready
88+
89+
$display("%7.2fms | tx busy: %d, tx done: %d", $realtime/10000, txBusy_1, txDone_1);
90+
$display("%7.2fms | rx data: %8b", $realtime/10000, rxByte_1);
91+
end
92+
endcase
93+
end
94+
95+
en_1 = 1'b0;
96+
#2400
97+
98+
$finish();
99+
end
100+
101+
endmodule

0 commit comments

Comments
 (0)