mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2024-09-09 03:02:42 +00:00
c35e7680ea
Silence lint on intentional combinatinal loops Use better instance names, and a single lint pragma for all macros Remove unused pointer update signals Silence lint on wires where not all bits are used Change fw_app_mode to be an input port to allow access control Remove redundant, unused wire mem_busy Add lint pragma to ignore debug register only enabled by a define Remove clk and reset_n ports from the ROM Adding note and lint pragma for rom address width Fix incorrect register widths in uart_core Assign all 16 bits in LUT config Silence lint warnings on macro instances Correct bit extraction for core addresses to be eight bits wide Correct the bit width of cdi_mem_we wire Add specific output file for logging lint issues Correct bit width of tmp_ready to match one bit ready port
309 lines
9.0 KiB
Verilog
309 lines
9.0 KiB
Verilog
//======================================================================
|
|
//
|
|
// uart.v
|
|
// ------
|
|
// Top level wrapper for the uart core.
|
|
//
|
|
// A simple universal asynchronous receiver/transmitter (UART)
|
|
// interface. The interface contains 16 byte wide transmit and
|
|
// receivea buffers and can handle start and stop bits. But in
|
|
// general is rather simple. The primary purpose is as host
|
|
// interface for the coretest design. The core also has a
|
|
// loopback mode to allow testing of a serial link.
|
|
//
|
|
// Note that the UART has a separate API interface to allow
|
|
// a control core to change settings such as speed. But the core
|
|
// has default values to allow it to start operating directly
|
|
// after reset. No config should be needed.
|
|
//
|
|
//
|
|
// Author: Joachim Strombergson
|
|
// Copyright (c) 2014, Secworks Sweden AB
|
|
// SPDX-License-Identifier: BSD-2-Clause
|
|
//
|
|
// Redistribution and use in source and binary forms, with or
|
|
// without modification, are permitted provided that the following
|
|
// conditions are met:
|
|
//
|
|
// 1. Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in
|
|
// the documentation and/or other materials provided with the
|
|
// distribution.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
//======================================================================
|
|
|
|
module uart(
|
|
input wire clk,
|
|
input wire reset_n,
|
|
|
|
input wire rxd,
|
|
output wire txd,
|
|
|
|
input wire cs,
|
|
input wire we,
|
|
input wire [7 : 0] address,
|
|
/* verilator lint_off UNUSED */
|
|
input wire [31 : 0] write_data,
|
|
/* verilator lint_on UNUSED */
|
|
output wire [31 : 0] read_data,
|
|
output wire ready
|
|
);
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
// Internal constant and parameter definitions.
|
|
//----------------------------------------------------------------
|
|
localparam ADDR_CORE_NAME0 = 8'h00;
|
|
localparam ADDR_CORE_NAME1 = 8'h01;
|
|
localparam ADDR_CORE_VERSION = 8'h02;
|
|
|
|
localparam ADDR_BIT_RATE = 8'h10;
|
|
localparam ADDR_DATA_BITS = 8'h11;
|
|
localparam ADDR_STOP_BITS = 8'h12;
|
|
|
|
localparam ADDR_RX_STATUS = 8'h20;
|
|
localparam ADDR_RX_DATA = 8'h21;
|
|
|
|
localparam ADDR_TX_STATUS = 8'h40;
|
|
localparam ADDR_TX_DATA = 8'h41;
|
|
|
|
|
|
localparam CORE_NAME0 = 32'h75617274; // "uart"
|
|
localparam CORE_NAME1 = 32'h20202020; // " "
|
|
localparam CORE_VERSION = 32'h00000004;
|
|
|
|
|
|
// The default bit rate is based on target clock frequency
|
|
// divided by the bit rate times in order to hit the
|
|
// center of the bits. I.e.
|
|
// Clock: 18 MHz, 38400 bps
|
|
// Divisor = 18*10E6 / 38400 = 468.75 ~ 469
|
|
localparam DEFAULT_BIT_RATE = 16'd469;
|
|
localparam DEFAULT_DATA_BITS = 4'h8;
|
|
localparam DEFAULT_STOP_BITS = 2'h1;
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
// Registers including update variables and write enable.
|
|
//----------------------------------------------------------------
|
|
reg [15 : 0] bit_rate_reg;
|
|
reg bit_rate_we;
|
|
|
|
reg [3 : 0] data_bits_reg;
|
|
reg data_bits_we;
|
|
|
|
reg [1 : 0] stop_bits_reg;
|
|
reg stop_bits_we;
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
// Wires.
|
|
//----------------------------------------------------------------
|
|
wire core_rxd_syn;
|
|
wire [7 : 0] core_rxd_data;
|
|
wire core_rxd_ack;
|
|
|
|
reg core_txd_syn;
|
|
reg [7 : 0] core_txd_data;
|
|
wire core_txd_ready;
|
|
|
|
wire fifo_out_syn;
|
|
wire [7 : 0] fifo_out_data;
|
|
reg fifo_out_ack;
|
|
|
|
reg [31 : 0] tmp_read_data;
|
|
reg tmp_ready;
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
// Concurrent connectivity for ports etc.
|
|
//----------------------------------------------------------------
|
|
assign read_data = tmp_read_data;
|
|
assign ready = tmp_ready;
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
// Module instantiations.
|
|
//----------------------------------------------------------------
|
|
uart_core core(
|
|
.clk(clk),
|
|
.reset_n(reset_n),
|
|
|
|
// Configuration parameters
|
|
.bit_rate(bit_rate_reg),
|
|
.data_bits(data_bits_reg),
|
|
.stop_bits(stop_bits_reg),
|
|
|
|
// External data interface
|
|
.rxd(rxd),
|
|
.txd(txd),
|
|
|
|
// Internal receive interface.
|
|
.rxd_syn(core_rxd_syn),
|
|
.rxd_data(core_rxd_data),
|
|
.rxd_ack(core_rxd_ack),
|
|
|
|
// Internal transmit interface.
|
|
.txd_syn(core_txd_syn),
|
|
.txd_data(core_txd_data),
|
|
.txd_ready(core_txd_ready)
|
|
);
|
|
|
|
|
|
uart_fifo fifo(
|
|
.clk(clk),
|
|
.reset_n(reset_n),
|
|
|
|
.in_syn(core_rxd_syn),
|
|
.in_data(core_rxd_data),
|
|
.in_ack(core_rxd_ack),
|
|
|
|
.out_syn(fifo_out_syn),
|
|
.out_data(fifo_out_data),
|
|
.out_ack(fifo_out_ack)
|
|
);
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
// reg_update
|
|
//
|
|
// Update functionality for all registers in the core.
|
|
// All registers are positive edge triggered with synchronous
|
|
// active low reset.
|
|
//----------------------------------------------------------------
|
|
always @ (posedge clk)
|
|
begin: reg_update
|
|
if (!reset_n) begin
|
|
bit_rate_reg <= DEFAULT_BIT_RATE;
|
|
data_bits_reg <= DEFAULT_DATA_BITS;
|
|
stop_bits_reg <= DEFAULT_STOP_BITS;
|
|
end
|
|
else begin
|
|
if (bit_rate_we) begin
|
|
bit_rate_reg <= write_data[15 : 0];
|
|
end
|
|
|
|
if (data_bits_we) begin
|
|
data_bits_reg <= write_data[3 : 0];
|
|
end
|
|
|
|
if (stop_bits_we) begin
|
|
stop_bits_reg <= write_data[1 : 0];
|
|
end
|
|
end
|
|
end // reg_update
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
// api
|
|
//
|
|
// The core API that allows an internal host to control the
|
|
// core functionality.
|
|
//----------------------------------------------------------------
|
|
always @*
|
|
begin: api
|
|
// Default assignments.
|
|
bit_rate_we = 1'h0;
|
|
data_bits_we = 1'h0;
|
|
stop_bits_we = 1'h0;
|
|
core_txd_syn = 1'h0;
|
|
fifo_out_ack = 1'h0;
|
|
tmp_read_data = 32'h0;
|
|
tmp_ready = 1'h0;
|
|
|
|
core_txd_data = write_data[7 : 0];
|
|
|
|
if (cs) begin
|
|
tmp_ready = 1'h1;
|
|
|
|
if (we) begin
|
|
case (address)
|
|
ADDR_BIT_RATE: begin
|
|
bit_rate_we = 1;
|
|
end
|
|
|
|
ADDR_DATA_BITS: begin
|
|
data_bits_we = 1;
|
|
end
|
|
|
|
ADDR_STOP_BITS: begin
|
|
stop_bits_we = 1;
|
|
end
|
|
|
|
ADDR_TX_DATA: begin
|
|
core_txd_syn = 1'h1;
|
|
end
|
|
|
|
default: begin
|
|
end
|
|
endcase // case (address)
|
|
end
|
|
|
|
else begin
|
|
case (address)
|
|
ADDR_CORE_NAME0: begin
|
|
tmp_read_data = CORE_NAME0;
|
|
end
|
|
|
|
ADDR_CORE_NAME1: begin
|
|
tmp_read_data = CORE_NAME1;
|
|
end
|
|
|
|
ADDR_CORE_VERSION: begin
|
|
tmp_read_data = CORE_VERSION;
|
|
end
|
|
|
|
ADDR_BIT_RATE: begin
|
|
tmp_read_data = {16'h0, bit_rate_reg};
|
|
end
|
|
|
|
ADDR_DATA_BITS: begin
|
|
tmp_read_data = {28'h0, data_bits_reg};
|
|
end
|
|
|
|
ADDR_STOP_BITS: begin
|
|
tmp_read_data = {30'h0, stop_bits_reg};
|
|
end
|
|
|
|
ADDR_RX_STATUS: begin
|
|
tmp_read_data = {31'h0, fifo_out_syn};
|
|
end
|
|
|
|
ADDR_RX_DATA: begin
|
|
fifo_out_ack = 1'h1;
|
|
tmp_read_data = {24'h0, fifo_out_data};
|
|
end
|
|
|
|
ADDR_TX_STATUS: begin
|
|
tmp_read_data = {31'h0, core_txd_ready};
|
|
end
|
|
|
|
default: begin
|
|
end
|
|
endcase // case (address)
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule // uart
|
|
|
|
//======================================================================
|
|
// EOF uart.v
|
|
//======================================================================
|