148 lines
3.1 KiB
Verilog
148 lines
3.1 KiB
Verilog
// Copyright (c) 2014 Sergiusz 'q3k' BazaĆski <sergiusz@bazanski.pl>
|
|
// Released under the 2-clause BSD license - see the COPYING file
|
|
|
|
`timescale 1ns / 1ps
|
|
|
|
module top(
|
|
// Board-specific signals
|
|
input sys_clk,
|
|
input sys_rst,
|
|
|
|
// To EC
|
|
input [7:0] data,
|
|
output reg [14:0] address,
|
|
output reg oe,
|
|
output reg ce,
|
|
output xout,
|
|
|
|
// UART signals for control
|
|
output uart_signal_tx,
|
|
input uart_signal_rx,
|
|
|
|
// Debug signals
|
|
output led0,
|
|
output debug
|
|
);
|
|
|
|
// FSM states
|
|
`define STATE_IDLE 4'b0000
|
|
`define STATE_ASSERT_ADDRESS 4'b0001
|
|
`define STATE_READ_DATA 4'b0010
|
|
`define STATE_OUTPUT 4'b0011
|
|
`define STATE_OUTPUT_WAIT 4'b0100
|
|
// State of our FSM
|
|
reg [3:0] state;
|
|
assign led0 = state != 0;
|
|
|
|
// Clocks 'n stuff
|
|
// 'Main' clock
|
|
reg [11:0] clock_counter;
|
|
wire clock = clock_counter[11];
|
|
// UART clock
|
|
reg [7:0] uart_clock_counter;
|
|
reg uart_clock;
|
|
assign debug = uart_clock;
|
|
// EC clock
|
|
reg [2:0] ec_clock_counter;
|
|
reg ec_clock;
|
|
assign xout = ec_clock;
|
|
|
|
// UART
|
|
reg uart_latch;
|
|
wire uart_receied;
|
|
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(!sys_rst),
|
|
.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));
|
|
|
|
// Internal reader registers
|
|
reg [14:0] read_address;
|
|
reg [8:0] bytes_left;
|
|
|
|
// Clocks
|
|
always @(posedge sys_clk) begin
|
|
clock_counter <= clock_counter + 1;
|
|
if (uart_clock_counter >= 216) begin
|
|
uart_clock <= !uart_clock;
|
|
uart_clock_counter <= 0;
|
|
end else begin
|
|
uart_clock_counter <= uart_clock_counter + 1;
|
|
end
|
|
if (ec_clock_counter >= 4) begin
|
|
ec_clock <= !ec_clock;
|
|
ec_clock_counter <= 0;
|
|
end else begin
|
|
ec_clock_counter <= ec_clock_counter + 1;
|
|
end
|
|
|
|
//clock_counter <= 0;
|
|
//uart_clock_counter <= 0;
|
|
//uart_clock <= 0;
|
|
//ec_clock_counter <= 0;
|
|
//ec_clock <= 0;
|
|
end
|
|
|
|
// State machine
|
|
always @(posedge clock) begin
|
|
if (!sys_rst) begin
|
|
// reset condition
|
|
state <= `STATE_IDLE;
|
|
uart_received_clear <= 0;
|
|
uart_latch <= 0;
|
|
read_address <= 0;
|
|
oe <= 1;
|
|
ce <= 1;
|
|
end else begin
|
|
case (state)
|
|
`STATE_IDLE: begin
|
|
if (uart_received) begin
|
|
uart_received_clear <= 1;
|
|
read_address <= (uart_rx * 256) & 15'h7FFF;
|
|
state <= `STATE_ASSERT_ADDRESS;
|
|
bytes_left <= 9'h100;
|
|
end
|
|
end
|
|
`STATE_ASSERT_ADDRESS: begin
|
|
oe <= 0;
|
|
ce <= 0;
|
|
address <= read_address;
|
|
state <= `STATE_READ_DATA;
|
|
end
|
|
`STATE_READ_DATA: begin
|
|
state <= `STATE_OUTPUT;
|
|
end
|
|
`STATE_OUTPUT: begin
|
|
if (uart_transmitted) begin
|
|
uart_latch <= 1;
|
|
state <= `STATE_OUTPUT_WAIT;
|
|
end
|
|
end
|
|
`STATE_OUTPUT_WAIT: begin
|
|
if (!uart_transmitted) begin
|
|
bytes_left <= bytes_left - 1;
|
|
read_address <= read_address + 1;
|
|
uart_latch <= 0;
|
|
if (bytes_left - 1 == 0) begin
|
|
uart_received_clear <= 0;
|
|
state <= `STATE_IDLE;
|
|
end else begin
|
|
state <= `STATE_ASSERT_ADDRESS;
|
|
end
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
endmodule
|