ソースを参照

cores/misc: Add simple UART TX/RX cores

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Sylvain Munaut 6 年 前
コミット
2ed6b32cf4
4 ファイル変更331 行追加0 行削除
  1. 3 0
      cores/misc/core.mk
  2. 130 0
      cores/misc/rtl/uart_rx.v
  3. 96 0
      cores/misc/rtl/uart_tx.v
  4. 102 0
      cores/misc/sim/uart_tb.v

+ 3 - 0
cores/misc/core.mk

@@ -8,9 +8,12 @@ RTL_SRCS_misc = $(addprefix rtl/, \
 	ram_sdp.v \
 	prims.v \
 	pwm.v \
+	uart_rx.v \
+	uart_tx.v \
 )
 
 TESTBENCHES_misc := \
 	fifo_tb \
+	uart_tb \
 
 include $(ROOT)/build/core-magic.mk

+ 130 - 0
cores/misc/rtl/uart_rx.v

@@ -0,0 +1,130 @@
+/*
+ * uart_rx.v
+ *
+ * vim: ts=4 sw=4
+ *
+ * Copyright (C) 2019  Sylvain Munaut <tnt@246tNt.com>
+ * All rights reserved.
+ *
+ * BSD 3-clause, see LICENSE.bsd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * 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 <COPYRIGHT HOLDER> 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.
+ */
+
+`default_nettype none
+
+module uart_rx #(
+	parameter integer DIV_WIDTH = 8,
+	parameter integer GLITCH_FILTER = 2
+)(
+	input  wire rx,
+	output wire [7:0] data,
+	output reg  stb,
+	input  wire [DIV_WIDTH-1:0] div,	// div - 2
+	input  wire clk,
+	input  wire rst
+);
+	// Signals
+	wire rx_val;
+	wire rx_fall;
+
+	wire go, done, ce;
+	reg  active;
+	reg [DIV_WIDTH:0] div_cnt;
+	reg [4:0] bit_cnt;
+	reg [8:0] shift;
+
+	// Input stage (synchronizer / de-glitch / change detect)
+	generate
+		// Glitch filter
+		if (GLITCH_FILTER > 0)
+			glitch_filter #(
+				.L(GLITCH_FILTER)
+			) gf_I (
+				.pin_iob_reg(rx),
+				.cond(1'b1),
+				.val(rx_val),
+				.rise(),
+				.fall(rx_fall),
+				.clk(clk),
+				.rst(rst)
+			);
+
+		// Or simple synchronizer
+		else begin
+			reg [1:0] rx_sync;
+			reg rx_fd;
+
+			always @(posedge clk)
+			begin
+				rx_sync <= { rx_sync[0], rx };
+				rx_fd   <= rx_sync[1] & ~rx_sync[0];
+			end
+
+			assign rx_fall = rx_fd;
+			assign rx_val  = rx_sync[1];
+		end
+	endgenerate
+
+	// Control
+	assign go = rx_fall & ~active;
+	assign done = ce & bit_cnt[4];
+
+	always @(posedge clk or posedge rst)
+		if (rst)
+			active <= 1'b0;
+		else
+			active <= (active & ~done) | go;
+
+	// Baud rate generator
+	always @(posedge clk)
+		if (~active)
+			div_cnt <= { 2'b00, div[DIV_WIDTH-1:1] } - 1;
+		else if (div_cnt[DIV_WIDTH])
+			div_cnt <= { 1'b0, div };
+		else
+			div_cnt <= div_cnt - 1;
+
+	assign ce = div_cnt[DIV_WIDTH];
+
+	// Bit counter
+	always @(posedge clk)
+		if (~active)
+			bit_cnt <= 5'h08;
+		else if (ce)
+			bit_cnt <= bit_cnt - 1;
+
+	// Signals
+
+	// Shift register
+	always @(posedge clk)
+		if (ce)
+			shift <= { rx_val, shift[8:1] };
+
+	// Outputs
+	assign data = shift[7:0];
+
+	always @(posedge clk)
+		stb <= ce & bit_cnt[4] & rx_val;
+
+endmodule // uart_rx

+ 96 - 0
cores/misc/rtl/uart_tx.v

@@ -0,0 +1,96 @@
+/*
+ * uart_tx.v
+ *
+ * vim: ts=4 sw=4
+ *
+ * Copyright (C) 2019  Sylvain Munaut <tnt@246tNt.com>
+ * All rights reserved.
+ *
+ * BSD 3-clause, see LICENSE.bsd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * 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 <COPYRIGHT HOLDER> 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.
+ */
+
+`default_nettype none
+
+module uart_tx #(
+	parameter integer DIV_WIDTH = 8
+)(
+	output wire tx,
+	input  wire [7:0] data,
+	input  wire valid,
+	output reg  ack,
+	input  wire [DIV_WIDTH-1:0] div,	// div - 2
+	input  wire clk,
+	input  wire rst
+);
+
+	// Signals
+	wire go, done, ce;
+	reg  active;
+	reg [9:0] shift;
+	reg [DIV_WIDTH:0] div_cnt;
+	reg [4:0] bit_cnt;
+
+	// Control
+	assign go = valid & ~active;
+	assign done = ce & bit_cnt[4];
+
+	always @(posedge clk or posedge rst)
+		if (rst)
+			active <= 1'b0;
+		else
+			active <= (active & ~done) | go;
+
+	// Baud rate generator
+	always @(posedge clk)
+		if (~active | div_cnt[DIV_WIDTH])
+			div_cnt <= { 1'b0, div };
+		else
+			div_cnt <= div_cnt - 1;
+
+	assign ce = div_cnt[DIV_WIDTH];
+
+	// Bit counter
+	always @(posedge clk)
+		if (~active)
+			bit_cnt <= 5'h08;
+		else if (ce)
+			bit_cnt <= bit_cnt - 1;
+
+	// Shift register
+	always @(posedge clk or posedge rst)
+		if (rst)
+			shift <= 10'h3ff;
+		else if (go)
+			shift <= { 1'b1, data, 1'b0 };
+		else if (ce)
+			shift <= { 1'b1, shift[9:1] };
+
+	// Outputs
+	always @(posedge clk)
+		ack <= go;
+
+	assign tx = shift[0];
+
+endmodule // uart_tx

+ 102 - 0
cores/misc/sim/uart_tb.v

@@ -0,0 +1,102 @@
+/*
+ * uart_tb.v
+ *
+ * vim: ts=4 sw=4
+ *
+ * Copyright (C) 2019  Sylvain Munaut <tnt@246tNt.com>
+ * All rights reserved.
+ *
+ * BSD 3-clause, see LICENSE.bsd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * 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 <COPYRIGHT HOLDER> 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.
+ */
+
+`default_nettype none
+`timescale 1ns / 100ps
+
+module uart_tb;
+
+	// Signals
+	reg rst = 1'b1;
+	reg clk_rx = 1'b0;
+	reg clk_tx = 1'b0;
+
+	wire serial;
+
+	reg  [7:0] tx_data;
+	wire tx_valid;
+	wire tx_ack;
+
+	wire [7:0] rx_data;
+	wire rx_stb;
+
+	// Setup recording
+	initial begin
+		$dumpfile("uart_tb.vcd");
+		$dumpvars(0,uart_tb);
+	end
+
+	// Reset pulse
+	initial begin
+		# 200 rst = 0;
+		# 1000000 $finish;
+	end
+
+	// Clocks
+	always #10.4 clk_rx = !clk_rx;
+	always #10.0 clk_tx = !clk_tx;
+
+	// DUT
+	uart_tx #(
+		.DIV_WIDTH(4)
+	) dut_tx_I (
+		.tx(serial),
+		.data(tx_data),
+		.valid(tx_valid),
+		.ack(tx_ack),
+		.div(4'h3),
+		.clk(clk_tx),
+		.rst(rst)
+	);
+
+	uart_rx #(
+		.DIV_WIDTH(4),
+		.GLITCH_FILTER(2)
+	) dut_rx_I (
+		.rx(serial),
+		.data(rx_data),
+		.stb(rx_stb),
+		.div(4'h3),
+		.clk(clk_rx),
+		.rst(rst)
+	);
+
+	always @(posedge clk_tx)
+		if (rst)
+			tx_data <= 8'h00;
+		else if (tx_ack)
+			tx_data <= tx_data + 1;
+
+	assign tx_valid = ~rst;
+
+endmodule // uart_tb