From 4e43167ee0b9eea65b8e2b32ff7448a0f7f7d81f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Fri, 9 May 2014 13:07:56 +0200 Subject: Adding support for setting bit rate, data- and stop bits. --- src/rtl/uart.v | 119 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 26 deletions(-) diff --git a/src/rtl/uart.v b/src/rtl/uart.v index d5a5a86..40a3f69 100644 --- a/src/rtl/uart.v +++ b/src/rtl/uart.v @@ -18,7 +18,7 @@ // // // Author: Joachim Strombergson -// Copyright (c) 2014 SUNET +// Copyright (c) 2014, SUNET // // Redistribution and use in source and binary forms, with or // without modification, are permitted provided that the following @@ -68,7 +68,7 @@ module uart( // API interface. input wire cs, input wire we, - input wire [3 : 0] address, + input wire [7 : 0] address, input wire [31 : 0] write_data, output wire [31 : 0] read_data, output wire error, @@ -82,34 +82,46 @@ module uart( // Internal constant and parameter definitions. //---------------------------------------------------------------- // API addresses. - parameter ADDR_CORE_NAME0 = 4'h0; - parameter ADDR_CORE_NAME1 = 4'h1; - parameter ADDR_CORE_TYPE = 4'h2; - parameter ADDR_CORE_VERSION = 4'h3; + parameter ADDR_CORE_NAME0 = 8'h00; + parameter ADDR_CORE_NAME1 = 8'h01; + parameter ADDR_CORE_TYPE = 8'h02; + parameter ADDR_CORE_VERSION = 8'h03; + parameter ADDR_BIT_RATE = 8'h10; + parameter ADDR_DATA_BITS = 8'h11; + parameter ADDR_STOP_BITS = 8'h12; + // Core ID constants. parameter CORE_NAME0 = 32'h75617274; // "uart" parameter CORE_NAME1 = 32'h20202020; // " " parameter CORE_TYPE = 32'h20202031; // " 1" parameter CORE_VERSION = 32'h302e3031; // "0.01" - // The default clock rate is based on target clock frequency + // 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: 50 MHz - // Bitrate: 19200 bps + // Clock: 50 MHz, 9600 bps // Divisor = 50*10E6 / 9600 = 5208 - parameter DEFAULT_CLK_RATE = 16'd5208; - parameter DEFAULT_HALF_CLK_RATE = DEFAULT_CLK_RATE / 2; - + parameter DEFAULT_BIT_RATE = 16'd5208; parameter DEFAULT_DATA_BITS = 4'h8; - parameter DEFAULT_STOP_BITS = 2'h2; + parameter DEFAULT_STOP_BITS = 2'h1; //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- + reg [15 : 0] bit_rate_reg; + reg [15 : 0] bit_rate_new; + reg bit_rate_we; + reg [3 : 0] data_bits_reg; + reg [3 : 0] data_bits_new; + reg data_bits_we; + + reg [1 : 0] stop_bits_reg; + reg [1 : 0] stop_bits_new; + reg stop_bits_we; + //---------------------------------------------------------------- // Wires. @@ -117,19 +129,19 @@ module uart( wire [15 : 0] bit_rate; wire [1 : 0] stop_bits; - wire core_rxd; - wire core_txd; + wire core_rxd; + wire core_txd; - wire core_rxd_syn; - wire [7 : 0] core_rxd_data; - wire core_rxd_ack; + wire core_rxd_syn; + wire [7 : 0] core_rxd_data; + wire core_rxd_ack; - wire core_txd_syn; - wire [7 : 0] core_txd_data; - wire core_txd_ack; + wire core_txd_syn; + wire [7 : 0] core_txd_data; + wire core_txd_ack; - reg [31 : 0] tmp_read_data; - reg tmp_error; + reg [31 : 0] tmp_read_data; + reg tmp_error; //---------------------------------------------------------------- @@ -162,8 +174,9 @@ module uart( .reset_n(reset_n), // Configuration parameters - .bit_rate(bit_rate), - .stop_bits(stop_bits), + .bit_rate(bit_rate_reg), + .data_bits(data_bits_reg), + .stop_bits(stop_bits_reg), // External data interface .rxd(core_rxd), @@ -192,10 +205,26 @@ module uart( 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 <= bit_rate_new; + end + + if (data_bits_we) + begin + data_bits_reg <= data_bits_new; + end + + if (stop_bits_we) + begin + stop_bits_reg <= stop_bits_new; + end end end // reg_update @@ -210,6 +239,12 @@ module uart( always @* begin: api // Default assignments. + bit_rate_new = 16'h0000; + bit_rate_we = 0; + data_bits_new = 4'h0; + data_bits_we = 0; + stop_bits_new = 2'b00; + stop_bits_we = 0; tmp_read_data = 32'h00000000; tmp_error = 0; @@ -219,6 +254,23 @@ module uart( begin // Write operations. case (address) + ADDR_BIT_RATE: + begin + bit_rate_new = write_data[15 : 0]; + bit_rate_we = 1; + end + + ADDR_DATA_BITS: + begin + data_bits_new = write_data[3 : 0]; + data_bits_we = 1; + end + + ADDR_STOP_BITS: + begin + stop_bits_new = write_data[1 : 0]; + stop_bits_we = 1; + end default: begin @@ -250,6 +302,21 @@ module uart( tmp_read_data = CORE_VERSION; end + ADDR_BIT_RATE: + begin + tmp_read_data = {16'h0000, bit_rate_reg}; + end + + ADDR_DATA_BITS: + begin + tmp_read_data = {28'h0000000, data_bits_reg}; + end + + ADDR_STOP_BITS: + begin + tmp_read_data = {30'h0000000, stop_bits_reg}; + end + default: begin tmp_error = 1; -- cgit v1.2.3