1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
// Copyright (c) 2014 Sergiusz 'q3k' BazaĆski <sergiusz@baznaski.pl>
// Released under the 2-clause BSD license - see the COPYING file
`timescale 1ns / 1ps
`include "uart.v"
`include "sevenseg.v"
module aamux_controller(
// To the BIOS chip
input [7:0] data,
output reg [10:0] address,
output reg rowcol,
input busy,
// Debug LEDs
output [7:0] leds,
// Main system clock (50MHz)
input sys_clock,
// Reset button
input reset,
// UART TX&RX
output uart_signal_tx,
input uart_signal_rx,
// Seven-segment display
output [6:0] segments,
output [3:0] segments_anodes
);
/// Clocks
// Main clock (sys_clock/32)
reg [4:0] clock_counter;
wire clock = clock_counter[4];
// UART clock (toggle every 217 sys_clocks)
reg [7:0] uart_clock_counter;
reg uart_clock;
/// UART
reg uart_latch;
wire uart_received;
reg uart_received_clear;
wire [7:0] uart_rx;
wire uart_transmitted;
uart_controller uart(
.tx_data_in (data),
.tx_data_latch (uart_latch),
.clock (uart_clock),
.reset (reset),
.tx_transmitted (uart_transmitted),
.tx_signal (uart_signal_tx),
.rx_present (uart_received),
.rx_present_clear (uart_received_clear),
.rx_data (uart_rx),
.rx_signal (uart_signal_rx));
/// Seven-segment display
reg [15:0] to_display;
sevenseg display (
.value (to_display),
.segments (segments),
.anodes (segments_anodes),
.sys_clock (sys_clock),
.reset (reset));
/// State machine
reg [2:0] state;
`define WAIT_CMD 0
`define ASSERT_ROW 1
`define ROW_LATCH 2
`define ASSERT_COL 3
`define COL_LATCH 4
`define WAITING 5
`define OUTPUT 6
`define OUTPUT_WAIT 7
//assign leds = (1 << state);
assign leds = uart_received;
/// Address from which we will be reading, and
// how many bytes are left
reg [21:0] read_address;
reg [16:0] bytes_left;
/// sys_clock division into clock and uart_clock
always @(posedge sys_clock) begin
clock_counter <= clock_counter + 1;
if (uart_clock_counter >= 217) begin
uart_clock_counter <= 0;
uart_clock <= !uart_clock;
end else begin
uart_clock_counter <= uart_clock_counter + 1;
end
end
/// Main state machine code
always @(posedge clock) begin
if (reset) begin
// Reset state
state <= `WAIT_CMD;
read_address <= 0;
bytes_left <= 0;
rowcol <= 1;
uart_latch <= 0;
to_display <= 16'hDEAD;
uart_received_clear <= 0;
end else begin
case (state)
`WAIT_CMD: begin
if (uart_received) begin
state <= `ASSERT_ROW;
read_address <= uart_rx * 65536;
bytes_left <= 'h10000;
uart_received_clear <= 1;
end else
to_display <= 16'hDEAD;
end
`ASSERT_ROW: begin
address <= read_address[10:0];
state <= `ROW_LATCH;
rowcol <= 1;
end
`ROW_LATCH: begin
rowcol <= 0;
state <= `ASSERT_COL;
end
`ASSERT_COL: begin
address <= read_address[21:11];
state <= `COL_LATCH;
end
`COL_LATCH: begin
rowcol <= 1;
state <= `WAITING;
end
`WAITING: begin
if (busy)
state <= `OUTPUT;
end
// Wait for UART to be ready to latch data
`OUTPUT: begin
if (uart_transmitted) begin
uart_latch <= 1;
state <= `OUTPUT_WAIT;
end
end
// Wait for UART to latch our data and begin sending out
`OUTPUT_WAIT: begin
if (!uart_transmitted) begin
uart_latch <= 0;
to_display <= bytes_left;
read_address <= read_address + 1;
bytes_left <= bytes_left - 1;
if (bytes_left - 1 == 0) begin
uart_received_clear <= 0;
state <= `WAIT_CMD;
end else
state <= `ASSERT_ROW;
end
end
endcase
end
end
endmodule
|