blob: f623a60f7abb9b17f4dc1f47faeda874a872878e [file] [log] [blame]
Matt Venn08cd6eb2020-11-16 12:01:14 +01001`default_nettype none
shalanfd13eb52020-08-21 16:48:07 +02002/*
3 * PicoSoC - A simple example SoC using PicoRV32
4 *
5 * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21`timescale 1 ns / 1 ps
22
23/* tbuart --- mimic an external UART display, operating at 9600 baud */
24/* and accepting ASCII characters for display. */
25
26/* To do: Match a known UART 3.3V 16x2 LCD display. However, it */
27/* should be possible on a testing system to interface to the UART */
28/* pins on a Raspberry Pi, also running at 3.3V. */
29
30module tbuart (
31 input ser_rx
32);
33 reg [3:0] recv_state;
34 reg [2:0] recv_divcnt;
35 reg [7:0] recv_pattern;
36 reg [8*50-1:0] recv_buf_data; // 50 characters. Increase as needed for tests.
37
38 reg clk;
39
40 initial begin
41 clk <= 1'b0;
42 recv_state <= 0;
43 recv_divcnt <= 0;
44 recv_pattern <= 0;
45 recv_buf_data <= 0;
46 end
47
48 // NOTE: Running at 3.0us clock period @ 5 clocks per bit = 15.0us per
49 // bit ~= 64 kbaud. Not tuned to any particular UART. Most run at
50 // 9600 baud default and will bounce up to higher baud rates when
51 // passed specific command words.
52
53 always #1500 clk <= (clk === 1'b0);
54
55 always @(posedge clk) begin
56 recv_divcnt <= recv_divcnt + 1;
57 case (recv_state)
58 0: begin
59 if (!ser_rx)
60 recv_state <= 1;
61 recv_divcnt <= 0;
62 end
63 1: begin
64 if (2*recv_divcnt > 3'd3) begin
65 recv_state <= 2;
66 recv_divcnt <= 0;
67 end
68 end
69 10: begin
70 if (recv_divcnt > 3'd3) begin
71 // 0x0a = '\n'
72 if (recv_pattern == 8'h0a) begin
73 $display("output: %s", recv_buf_data);
74 end else begin
75 recv_buf_data <= {recv_buf_data, recv_pattern};
76 end
77 recv_state <= 0;
78 end
79 end
80 default: begin
81 if (recv_divcnt > 3'd3) begin
82 recv_pattern <= {ser_rx, recv_pattern[7:1]};
83 recv_state <= recv_state + 1;
84 recv_divcnt <= 0;
85 end
86 end
87 endcase
88 end
89
90endmodule