-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuart_rx.v
More file actions
102 lines (83 loc) · 3.77 KB
/
Copy pathuart_rx.v
File metadata and controls
102 lines (83 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Author: Jatin Ramchandani
`timescale 1ns / 1ps
// You MUST NOT change the module name or the ports declarations
module uart_rx(
input clk,
input rst_n,
input uart_rx_i,
output reg rec_full_byte, // A full byte has been received
output reg [7:0] text_msg_chara
);
// These declarations are provided as hints for a possible implementation.
// You are free to modify, add, or remove them as long as the module's
// external behavior is correct
reg [3:0] bit_counter; // 10 bits for transferring a whole byte
reg [13:0] baud_time_counter; // counts clock ticks to measure the duration of one bit period
reg en_baud_counter; // enables counting when a UART frame is being received
// ----------- Insert your codes below --------------//
reg [7:0] text_byte;
// Timing: 100 MHz clock, 9600 baud
localparam integer CLKS_PER_BIT = 10417;
localparam integer MID_BIT = CLKS_PER_BIT/2;
// The following always block was refined with assistance of LLMs
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
bit_counter <= 4'd0;
baud_time_counter <= 14'd0;
en_baud_counter <= 1'b0;
text_byte <= 8'd0;
text_msg_chara <= 8'd0;
rec_full_byte <= 1'b0;
end else begin
rec_full_byte <= 1'b0; // default
// --------- Idle / Start detect (level-based) --
if (!en_baud_counter) begin
baud_time_counter <= 14'd0;
bit_counter <= 4'd0;
// Start a frame as soon as we see the low on Rx_i
if (uart_rx_i == 1'b0) begin
en_baud_counter <= 1'b1;
end
end else begin
// ---------------- Bit timing ----------------
if (baud_time_counter == CLKS_PER_BIT-1) begin
baud_time_counter <= 14'd0;
if (bit_counter == 4'd9) begin
// End of stop bit
en_baud_counter <= 1'b0;
bit_counter <= 4'd0;
rec_full_byte <= 1'b1; // one-cycle pulse
end else begin
bit_counter <= bit_counter + 4'd1;
end
end else begin
baud_time_counter <= baud_time_counter + 14'd1;
end
// ------------ Sampling ----------------
// The following function block was created with assistance of LLMs
if (baud_time_counter == MID_BIT) begin
case (bit_counter)
4'd0: begin
// Re-check start bit for false-start
if (uart_rx_i == 1'b1) begin
// Noise/glitch: abort
en_baud_counter <= 1'b0;
baud_time_counter <= 14'd0;
bit_counter <= 4'd0;
end
end
4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8: begin
// LSB first
text_byte[bit_counter-1] <= uart_rx_i;
end
4'd9: begin
// Mid stop-bit: publish so it's stable before the pulse
text_msg_chara <= text_byte;
end
default: ;
endcase
end
end
end
end
endmodule