Created
November 11, 2023 21:34
-
-
Save rndtrash/cf4e7393774a92be95da5b001daa1ca7 to your computer and use it in GitHub Desktop.
Revisions
-
rndtrash created this gist
Nov 11, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,125 @@ // TODO: this module occasionally reads garbage `define BAUD_RATE 9_600 `define CLOCK 27_000_000 module uart_rx #(TICKS_PER_BIT=2_812) (clk, reset, re, rx, data, received, busy, valid); input clk; input reset; input re; input rx; output reg [7:0] data = 8'h00; output reg received = 0; output reg busy = 0; output reg valid = 0; localparam STATE_INITIAL = 3'd0; localparam STATE_START_BIT = 3'd1; localparam STATE_DATA_BITS = 3'd2; localparam STATE_STOP_BIT = 3'd3; localparam STATE_PADDING = 3'd4; localparam BIT_COUNTER_INITIAL = 3'd0; reg [2:0] state = STATE_INITIAL; // [0; 8) reg [18:0] counter = 0; // [0; 524 288) reg [2:0] bit_counter = BIT_COUNTER_INITIAL; // [0; 8) wire rx_neg_edge; negedge_detector ned(.clk(clk), .rst(reset), .a(rx), .detected(rx_neg_edge)); always @(posedge clk) if (reset) begin state <= STATE_INITIAL; busy <= 0; received <= 0; valid <= 0; end else case (state) STATE_INITIAL: begin if (re && rx_neg_edge) begin state <= STATE_START_BIT; busy <= 1; received <= 0; counter <= 0; end end STATE_START_BIT: begin // a half of the bit interval to read from the middle if (counter == TICKS_PER_BIT / 2) if (~ rx) begin state <= STATE_DATA_BITS; valid <= 0; counter <= 0; bit_counter <= BIT_COUNTER_INITIAL; end else begin state <= STATE_INITIAL; busy <= 0; end else counter <= counter + 19'd1; end STATE_DATA_BITS: begin if (counter == TICKS_PER_BIT) begin data[bit_counter] <= rx; counter <= 0; if (bit_counter == 7) state <= STATE_STOP_BIT; else begin bit_counter <= bit_counter + 3'd1; end end else counter <= counter + 19'd1; end STATE_STOP_BIT: begin if (counter == TICKS_PER_BIT) begin busy <= 0; if (rx) begin state <= STATE_PADDING; received <= 1; valid <= 1; counter <= 0; end else state <= STATE_INITIAL; end else counter <= counter + 19'd1; end STATE_PADDING: begin received <= 0; if (counter == TICKS_PER_BIT / 2) state <= STATE_INITIAL; else counter <= counter + 19'd1; end endcase endmodule