catalyst-n1 / rtl /uart_rx.v
mrwabbit's picture
Initial upload: Catalyst N1 open source neuromorphic processor RTL
e4cdd5f verified
// ============================================================================
// UART Receiver
// ============================================================================
//
// Copyright 2026 Henry Arthur Shulayev Barnes / Catalyst Neuromorphic Ltd
// Company No. 17054540 — UK Patent Application No. 2602902.6
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================
module uart_rx #(
parameter CLK_FREQ = 100_000_000,
parameter BAUD = 115200
)(
input wire clk,
input wire rst_n,
input wire rx,
output reg [7:0] data,
output reg valid
);
localparam CLKS_PER_BIT = CLK_FREQ / BAUD;
localparam HALF_BIT = CLKS_PER_BIT / 2;
localparam S_IDLE = 2'd0;
localparam S_START = 2'd1;
localparam S_DATA = 2'd2;
localparam S_STOP = 2'd3;
reg [1:0] state;
reg [15:0] clk_cnt;
reg [2:0] bit_idx;
reg [7:0] shift;
reg rx_s1, rx_s2;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rx_s1 <= 1;
rx_s2 <= 1;
end else begin
rx_s1 <= rx;
rx_s2 <= rx_s1;
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= S_IDLE;
valid <= 0;
clk_cnt <= 0;
bit_idx <= 0;
shift <= 0;
data <= 0;
end else begin
valid <= 0;
case (state)
S_IDLE: begin
if (!rx_s2) begin
clk_cnt <= 0;
state <= S_START;
end
end
S_START: begin
if (clk_cnt == HALF_BIT - 1) begin
if (!rx_s2) begin
clk_cnt <= 0;
bit_idx <= 0;
state <= S_DATA;
end else
state <= S_IDLE;
end else
clk_cnt <= clk_cnt + 1;
end
S_DATA: begin
if (clk_cnt == CLKS_PER_BIT - 1) begin
clk_cnt <= 0;
shift <= {rx_s2, shift[7:1]};
if (bit_idx == 7)
state <= S_STOP;
else
bit_idx <= bit_idx + 1;
end else
clk_cnt <= clk_cnt + 1;
end
S_STOP: begin
if (clk_cnt == CLKS_PER_BIT - 1) begin
data <= shift;
valid <= 1;
state <= S_IDLE;
end else
clk_cnt <= clk_cnt + 1;
end
endcase
end
end
endmodule