Skip to content

Commit 6f4420d

Browse files
committedAug 15, 2017
Added UART test
1 parent b5d38c9 commit 6f4420d

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed
 

Diff for: ‎tests/greenpak4/slg46620v/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ add_greenpak4_bitstream(Loop SLG46620V)
1414
add_greenpak4_bitstream(POR SLG46620V)
1515
add_greenpak4_bitstream(SPIToDCMP SLG46620V)
1616
add_greenpak4_bitstream(Tristate SLG46620V)
17+
add_greenpak4_bitstream(UART SLG46620V)
1718
add_greenpak4_bitstream(Vector SLG46620V)
1819
add_greenpak4_bitstream(VrefEXT SLG46620V)
1920
add_greenpak4_bitstream(VrefVDD SLG46620V)

Diff for: ‎tests/greenpak4/slg46620v/UART.v

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/***********************************************************************************************************************
2+
* Copyright (C) 2017 Andrew Zonenberg and contributors *
3+
* *
4+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General *
5+
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) *
6+
* any later version. *
7+
* *
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for *
10+
* more details. *
11+
* *
12+
* You should have received a copy of the GNU Lesser General Public License along with this program; if not, you may *
13+
* find one here: *
14+
* https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt *
15+
* or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
17+
**********************************************************************************************************************/
18+
19+
`default_nettype none
20+
21+
/**
22+
TODO
23+
*/
24+
module UART(txd, rxd);
25+
26+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27+
// I/O declarations
28+
29+
(* LOC = "P9" *) //not yet used
30+
input wire rxd;
31+
32+
(* LOC = "P7" *)
33+
output reg txd = 0;
34+
35+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36+
// Clocking
37+
38+
//The 2 MHz RC oscillator
39+
wire clk_250khz_cnt; //dedicated output to hard IP only
40+
wire clk_250khz; //general fabric output
41+
GP_RCOSC #(
42+
.PWRDN_EN(0),
43+
.AUTO_PWRDN(0),
44+
.OSC_FREQ("2M"),
45+
.HARDIP_DIV(8),
46+
.FABRIC_DIV(1)
47+
) rcosc (
48+
.PWRDN(1'b0),
49+
.CLKOUT_HARDIP(clk_250khz_cnt),
50+
.CLKOUT_FABRIC(clk_250khz)
51+
);
52+
53+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54+
// Baud rate generator
55+
56+
localparam UART_BAUD = 9600;
57+
localparam CLOCK_FREQ = 250000;
58+
localparam UART_BDIV = CLOCK_FREQ / UART_BAUD;
59+
localparam UART_BMAX = UART_BDIV - 1;
60+
61+
reg[7:0] baud_count = UART_BMAX;
62+
wire baud_edge = (baud_count == 0);
63+
64+
reg sending = 0;
65+
66+
always @(posedge clk_250khz_cnt) begin
67+
68+
baud_count <= baud_count - 1'h1;
69+
if(baud_edge)
70+
baud_count <= UART_BMAX;
71+
72+
end
73+
74+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
75+
// Transmit counter
76+
77+
localparam MESSAGE_MAX = 14'h3fff;
78+
79+
reg[13:0] message_count = MESSAGE_MAX;
80+
wire message_edge = (message_count == 0);
81+
82+
always @(posedge clk_250khz_cnt) begin
83+
message_count <= message_count - 1'h1;
84+
85+
if(message_edge)
86+
message_count <= MESSAGE_MAX;
87+
end
88+
89+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
90+
// Pattern generator for the actual message we're sending
91+
92+
//Start bit is in LSB since that's what we output during reset.
93+
//High 7 bits of PGEN ignored, then bit-reversed payload
94+
wire txd_raw;
95+
GP_PGEN #(
96+
.PATTERN_LEN(5'd10),
97+
.PATTERN_DATA({7'h0, 8'h82, 1'h1})
98+
) tx_pgen (
99+
.nRST(!message_edge),
100+
.CLK(baud_edge),
101+
.OUT(txd_raw)
102+
);
103+
104+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
105+
// Timer so we know how long the actual message lasts
106+
107+
localparam BYTE_MAX = 8'd10;
108+
109+
//Can't infer GP_COUNTx_ADV yet, so instantiate
110+
wire byte_done;
111+
GP_COUNT8_ADV #(
112+
.CLKIN_DIVIDE(1),
113+
.COUNT_TO(BYTE_MAX),
114+
.RESET_MODE("LEVEL"),
115+
.RESET_VALUE("COUNT_TO")
116+
) byte_count (
117+
.CLK(clk_250khz_cnt),
118+
.RST(!sending),
119+
.UP(1'b0),
120+
.KEEP(!baud_edge),
121+
.OUT(byte_done),
122+
.POUT()
123+
);
124+
125+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
126+
// Send logic
127+
128+
reg send_pending = 0;
129+
always @(posedge clk_250khz) begin
130+
131+
if(message_edge) begin
132+
send_pending <= 1;
133+
end
134+
135+
if(send_pending && baud_edge) begin
136+
send_pending <= 0;
137+
sending <= 1;
138+
end
139+
140+
if(byte_done) begin
141+
sending <= 0;
142+
end
143+
144+
if(sending)
145+
txd <= txd_raw;
146+
else
147+
txd <= 1;
148+
149+
end
150+
151+
endmodule

0 commit comments

Comments
 (0)
Please sign in to comment.