// Copyright (c) 2014 Sergiusz 'q3k' BazaƄski // 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