commit ec6c4a0f90d9eb10b6c036b27245a05ae1d38ee6 Author: Sergiusz 'q3k' Bazański Date: Sun Jan 5 19:28:23 2014 +0100 First commit, basic dumper diff --git a/aamux_controller.ucf b/aamux_controller.ucf new file mode 100644 index 0000000..67c1583 --- /dev/null +++ b/aamux_controller.ucf @@ -0,0 +1,36 @@ + +# PlanAhead Generated physical constraints + +NET "address[10]" LOC = D5; +NET "address[9]" LOC = D6; +NET "address[8]" LOC = E7; +NET "address[7]" LOC = D7; +NET "address[6]" LOC = D8; +NET "address[5]" LOC = D10; +NET "address[4]" LOC = B4; +NET "address[3]" LOC = B5; +NET "address[2]" LOC = B6; +NET "address[1]" LOC = A7; +NET "address[0]" LOC = A8; +NET "data[7]" LOC = C5; +NET "data[6]" LOC = C6; +NET "data[5]" LOC = C7; +NET "data[4]" LOC = C8; +NET "data[3]" LOC = C9; +NET "data[2]" LOC = A3; +NET "data[1]" LOC = A4; +NET "data[0]" LOC = A5; +NET "busy" LOC = B7; +NET "rowcol" LOC = B8; +NET "sys_clock" LOC = T9; +NET "leds[0]" LOC = K12; +NET "leds[1]" LOC = P14; +NET "leds[2]" LOC = L12; +NET "leds[3]" LOC = N14; +NET "leds[4]" LOC = P13; +NET "leds[5]" LOC = N12; +NET "leds[6]" LOC = P12; +NET "leds[7]" LOC = P11; +NET "reset" LOC = L14; +NET "uart_signal_tx" LOC = B14; +NET "uart_signal_rx" LOC = A13; \ No newline at end of file diff --git a/aamux_controller.v b/aamux_controller.v new file mode 100644 index 0000000..1e06a09 --- /dev/null +++ b/aamux_controller.v @@ -0,0 +1,124 @@ +// Copyright (c) 2014 Sergiusz 'q3k' Bazański +// 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 diff --git a/uart.v b/uart.v new file mode 100644 index 0000000..4e7432a --- /dev/null +++ b/uart.v @@ -0,0 +1,104 @@ +// Copyright (c) 2014 Sergiusz 'q3k' Bazański +// Released under the 2-clause BSD license - see the COPYING file + +`timescale 1ns / 1ps + +/// This is not the prettiest UART you've seen... + +module uart_controller( + // Data input + input [7:0] tx_data_in, + // Data input latch + input tx_data_latch, + + // baud rate clock + input tx_clock, + + // reset line + input reset, + + // goes 1 when the UART finished transmitting + output reg tx_transmitted, + // the actual UART transmitter output + output reg tx_signal + ); + + // Internal TX data (latched from tx_data_in) + reg [7:0] tx_data; + + reg [3:0] state; + `define IDLE 0 + `define START 1 + `define BIT0 2 + `define BIT1 3 + `define BIT2 4 + `define BIT3 5 + `define BIT4 6 + `define BIT5 7 + `define BIT6 8 + `define BIT7 9 + `define STOP 10 + + always @(posedge tx_clock) + begin + if (reset) begin + state <= `IDLE; + tx_signal <= 1; + tx_data <= 0; + tx_transmitted <= 1; + end else begin + case (state) + `IDLE: begin + if (tx_data_latch) + begin + tx_data <= tx_data_in; + state <= `START; + tx_transmitted <= 0; + end + end + `START: begin + tx_signal <= 0; + state <= `BIT0; + end + `BIT0: begin + tx_signal <= tx_data[0]; + state <= `BIT1; + end + `BIT1: begin + tx_signal <= tx_data[1]; + state <= `BIT2; + end + `BIT2: begin + tx_signal <= tx_data[2]; + state <= `BIT3; + end + `BIT3: begin + tx_signal <= tx_data[3]; + state <= `BIT4; + end + `BIT4: begin + tx_signal <= tx_data[4]; + state <= `BIT5; + end + `BIT5: begin + tx_signal <= tx_data[5]; + state <= `BIT6; + end + `BIT6: begin + tx_signal <= tx_data[6]; + state <= `BIT7; + end + `BIT7: begin + tx_signal <= tx_data[7]; + state <= `STOP; + end + `STOP: begin + tx_signal <= 1; + state <= `IDLE; + tx_transmitted <= 1; + end + endcase + end + end + +endmodule