Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `timescale 1ns / 1ps
- module uart(
- input rst,
- input clk,
- input rx,
- output tx,
- input r_clk,
- input r_enable,
- output [63:0] r_out,
- output empty,
- output full,
- output [63:0] buff
- );
- localparam FREQ = 100*1000*1000;
- localparam BAUD = 9600;
- localparam CYCLE = FREQ/BAUD; // 10416, 5208
- reg w_enable;
- reg [63:0] buffer;
- assign buff = buffer;
- wire [8:0] RDCOUNT, WRCOUNT;
- wire RDERR, WRERR, ALMOSTEMPTY, ALMOSTFULL;
- FIFO_DUALCLOCK_MACRO #(
- .ALMOST_EMPTY_OFFSET(13'h0080), // Sets the almost empty threshold
- .ALMOST_FULL_OFFSET(13'h0080), // Sets almost full threshold
- .DATA_WIDTH(64), // Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb")
- .DEVICE("7SERIES"), // Target device: "VIRTEX5", "VIRTEX6", "7SERIES"
- .FIFO_SIZE ("36Kb"), // Target BRAM: "18Kb" or "36Kb"
- .FIRST_WORD_FALL_THROUGH ("FALSE") // Sets the FIfor FWFT to "TRUE" or "FALSE"
- ) FIFO_DUALCLOCK_MACRO_inst (
- .ALMOSTEMPTY(ALMOSTEMPTY), // 1-bit output almost empty
- .ALMOSTFULL(ALMOSTFULL), // 1-bit output almost full
- .EMPTY(empty), // 1-bit output empty
- .FULL(full), // 1-bit output full
- .RDCOUNT(RDCOUNT), // Output read count, width determined by FIfor depth
- .RDERR(RDERR), // 1-bit output read error
- .WRCOUNT(WRCOUNT), // Output write count, width determined by FIfor depth
- .WRERR(WRERR), // 1-bit output write error
- .DO(r_out), // Output data, width defined by DATA_WIDTH parameter
- .RDCLK(r_clk), // 1-bit input read clock
- .RDEN(r_enable), // 1-bit input read enable
- .RST(rst), // 1-bit input reset
- .DI(buffer), // Input data, width defined by DATA_WIDTH parameter
- .WRCLK(clk), // 1-bit input write clock
- .WREN(w_enable) // 1-bit input write enable
- );
- localparam UNDEF = 16'bxxxxxxxxxxxxxxxx;
- localparam READY = 16'b1 << 0;
- localparam READING = 16'b1 << 1;
- reg [15:0] state = READY;
- reg [31:0] nomsg_cnt;
- reg [15:0] delay;
- reg [7:0] bits_to_read, bits_read;
- always @(posedge clk) begin
- w_enable <= 0;
- nomsg_cnt <= nomsg_cnt + 1;
- if (rx == 0)
- nomsg_cnt <= 0;
- if (nomsg_cnt == 1000*1000) begin // 1/100s, reset the automaton
- bits_read <= 0;
- nomsg_cnt <= 0;
- end
- if (delay)
- delay <= delay - 1;
- else case(state)
- READY: begin
- if (rx == 0) begin
- state <= READING;
- bits_to_read <= 7;
- delay <= (CYCLE * 3) / 2;
- end else
- state <= READY;
- end
- READING: begin
- buffer <= {rx, buffer[63:1]};
- delay <= CYCLE;
- bits_read <= bits_read + 1;
- if (bits_read == 63)
- w_enable <= 1;
- if (bits_to_read == 0) begin
- state <= READY;
- end else begin
- bits_to_read <= bits_to_read - 1;
- state <= READING;
- end
- end
- default: state <= UNDEF;
- endcase
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement