mirror of https://github.com/YosysHQ/yosys.git
155 lines
3.7 KiB
Verilog
155 lines
3.7 KiB
Verilog
//-----------------------------------------------------
|
|
// Design Name : uart
|
|
// File Name : uart.v
|
|
// Function : Simple UART
|
|
// Coder : Deepak Kumar Tala
|
|
//-----------------------------------------------------
|
|
module uart (
|
|
reset ,
|
|
txclk ,
|
|
ld_tx_data ,
|
|
tx_data ,
|
|
tx_enable ,
|
|
tx_out ,
|
|
tx_empty ,
|
|
rxclk ,
|
|
uld_rx_data ,
|
|
rx_data ,
|
|
rx_enable ,
|
|
rx_in ,
|
|
rx_empty
|
|
);
|
|
// Port declarations
|
|
input reset ;
|
|
input txclk ;
|
|
input ld_tx_data ;
|
|
input [7:0] tx_data ;
|
|
input tx_enable ;
|
|
output tx_out ;
|
|
output tx_empty ;
|
|
input rxclk ;
|
|
input uld_rx_data ;
|
|
output [7:0] rx_data ;
|
|
input rx_enable ;
|
|
input rx_in ;
|
|
output rx_empty ;
|
|
|
|
// Internal Variables
|
|
reg [7:0] tx_reg ;
|
|
reg tx_empty ;
|
|
reg tx_over_run ;
|
|
reg [3:0] tx_cnt ;
|
|
reg tx_out ;
|
|
reg [7:0] rx_reg ;
|
|
reg [7:0] rx_data ;
|
|
reg [3:0] rx_sample_cnt ;
|
|
reg [3:0] rx_cnt ;
|
|
reg rx_frame_err ;
|
|
reg rx_over_run ;
|
|
reg rx_empty ;
|
|
reg rx_d1 ;
|
|
reg rx_d2 ;
|
|
reg rx_busy ;
|
|
|
|
// UART RX Logic
|
|
always @ (posedge rxclk or posedge reset)
|
|
if (reset) begin
|
|
rx_reg <= 0;
|
|
rx_data <= 0;
|
|
rx_sample_cnt <= 0;
|
|
rx_cnt <= 0;
|
|
rx_frame_err <= 0;
|
|
rx_over_run <= 0;
|
|
rx_empty <= 1;
|
|
rx_d1 <= 1;
|
|
rx_d2 <= 1;
|
|
rx_busy <= 0;
|
|
end else begin
|
|
// Synchronize the asynch signal
|
|
rx_d1 <= rx_in;
|
|
rx_d2 <= rx_d1;
|
|
// Uload the rx data
|
|
if (uld_rx_data) begin
|
|
rx_data <= rx_reg;
|
|
rx_empty <= 1;
|
|
end
|
|
// Receive data only when rx is enabled
|
|
if (rx_enable) begin
|
|
// Check if just received start of frame
|
|
if (!rx_busy && !rx_d2) begin
|
|
rx_busy <= 1;
|
|
rx_sample_cnt <= 1;
|
|
rx_cnt <= 0;
|
|
end
|
|
// Start of frame detected, Proceed with rest of data
|
|
if (rx_busy) begin
|
|
rx_sample_cnt <= rx_sample_cnt + 1;
|
|
// Logic to sample at middle of data
|
|
if (rx_sample_cnt == 7) begin
|
|
if ((rx_d2 == 1) && (rx_cnt == 0)) begin
|
|
rx_busy <= 0;
|
|
end else begin
|
|
rx_cnt <= rx_cnt + 1;
|
|
// Start storing the rx data
|
|
if (rx_cnt > 0 && rx_cnt < 9) begin
|
|
rx_reg[rx_cnt - 1] <= rx_d2;
|
|
end
|
|
if (rx_cnt == 9) begin
|
|
rx_busy <= 0;
|
|
// Check if End of frame received correctly
|
|
if (rx_d2 == 0) begin
|
|
rx_frame_err <= 1;
|
|
end else begin
|
|
rx_empty <= 0;
|
|
rx_frame_err <= 0;
|
|
// Check if last rx data was not unloaded,
|
|
rx_over_run <= (rx_empty) ? 0 : 1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if (!rx_enable) begin
|
|
rx_busy <= 0;
|
|
end
|
|
end
|
|
|
|
// UART TX Logic
|
|
always @ (posedge txclk or posedge reset)
|
|
if (reset) begin
|
|
tx_reg <= 0;
|
|
tx_empty <= 1;
|
|
tx_over_run <= 0;
|
|
tx_out <= 1;
|
|
tx_cnt <= 0;
|
|
end else begin
|
|
if (ld_tx_data) begin
|
|
if (!tx_empty) begin
|
|
tx_over_run <= 0;
|
|
end else begin
|
|
tx_reg <= tx_data;
|
|
tx_empty <= 0;
|
|
end
|
|
end
|
|
if (tx_enable && !tx_empty) begin
|
|
tx_cnt <= tx_cnt + 1;
|
|
if (tx_cnt == 0) begin
|
|
tx_out <= 0;
|
|
end
|
|
if (tx_cnt > 0 && tx_cnt < 9) begin
|
|
tx_out <= tx_reg[tx_cnt -1];
|
|
end
|
|
if (tx_cnt == 9) begin
|
|
tx_out <= 1;
|
|
tx_cnt <= 0;
|
|
tx_empty <= 1;
|
|
end
|
|
end
|
|
if (!tx_enable) begin
|
|
tx_cnt <= 0;
|
|
end
|
|
end
|
|
|
|
endmodule
|