125 lines
2.5 KiB
Coq
125 lines
2.5 KiB
Coq
|
// 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"
|
||
|
|
||
|
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
|
||
|
);
|
||
|
|
||
|
/// Clocks
|
||
|
// Main clock (sys_clock/16)
|
||
|
reg [3:0] clock_counter;
|
||
|
wire clock = clock_counter[3];
|
||
|
// UART clock (toggle every 217 sys_clocks)
|
||
|
reg [7:0] uart_clock_counter;
|
||
|
reg uart_clock;
|
||
|
|
||
|
/// UART
|
||
|
reg uart_latch;
|
||
|
wire uart_transmitted;
|
||
|
uart_controller uart(
|
||
|
.tx_data_in (data),
|
||
|
.tx_data_latch (uart_latch),
|
||
|
.tx_clock (uart_clock),
|
||
|
.reset (reset),
|
||
|
.tx_transmitted (uart_transmitted),
|
||
|
.tx_signal (uart_signal));
|
||
|
|
||
|
|
||
|
/// State machine
|
||
|
reg [2:0] state;
|
||
|
`define ASSERT_ROW 0
|
||
|
`define ROW_LATCH 1
|
||
|
`define ASSERT_COL 2
|
||
|
`define COL_LATCH 3
|
||
|
`define WAITING 4
|
||
|
`define OUTPUT 5
|
||
|
`define OUTPUT_WAIT 6
|
||
|
|
||
|
|
||
|
reg [21:0] read_address;
|
||
|
assign leds = read_address[21:14];
|
||
|
|
||
|
|
||
|
/// 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
|
||
|
state <= `ASSERT_ROW;
|
||
|
read_address <= 0;
|
||
|
rowcol <= 1;
|
||
|
uart_latch <= 0;
|
||
|
end else begin
|
||
|
case (state)
|
||
|
`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;
|
||
|
state <= `ASSERT_ROW;
|
||
|
read_address <= read_address + 1;
|
||
|
end
|
||
|
end
|
||
|
endcase
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
endmodule
|