`timescale 1ns / 1ps
//
// Engineer: ian
//
// Create Date: 2019/11/30 14:51:50
// Design Name: uart
// Module Name: uart_tx
// Project Name:
// Target Devices: zynq 7020
// Tool Versions: vivado 2018.3
// Description: This this a uart transmit module
//
// Dependencies:
//
// Revision: v1.0
//
//**********************************************************************************
//input port: sys_clk //system clock
// sys_rst_n //syssystem reset, 0 is valid
// tx_start //start transmit singal, 1 is valid
// data //transmit data
//output port: tx //transmit port
// tx_done //finish transmit signal, 1 is valid
//**********************************************************************************
module uart_tx(
//input port define
input sys_clk, //system clock
input sys_rst_n, //system reset, 0 is valid
input tx_start, //start transmit signal
input [7:0] data, //data
//output port defien
output reg tx, //tx port
output reg tx_done //finish transmit signal
);
reg [3:0] state;
reg transmiting;
reg tx_clk_en;
wire tx_clk;
//*********************************************
//-----generate baudrate-----
//*********************************************
baudrate_gen baudrate_gen_1(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.tx_clk_en(tx_clk_en),
.rx_clk_en(),
.tx_clk(tx_clk),
.rx_clk()
);
//*********************************************
//-----generate transmiting symbol signal-----
//*********************************************
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
transmiting <= 1'b0;
else if (tx_done)
transmiting <= 1'b0;
else if (tx_start)
transmiting <= 1'b1;
end
//*********************************************
//-----send data-----
//*********************************************
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
state <= 1'b0;
tx <= 1'b1;
tx_done <= 1'b0;
tx_clk_en <= 1'b0;
end
else if (transmiting) begin
tx_clk_en <= 1'b1;
if (tx_clk)begin
case (state)
4'd0: begin
tx <= 1'b0;
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd1: begin
tx <= data[0];
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd2: begin
tx <= data[1];
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd3: begin
tx <= data[2];
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd4: begin
tx <= data[3];
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd5: begin
tx <= data[4];
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd6: begin
tx <= data[5];
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd7: begin
tx <= data[6];
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd8: begin
tx <= data[7];
tx_done <= 1'b0;
state <= state + 1'b1;
end
4'd9: begin
tx <= 1'b1;
tx_done <= 1'b0;
state <= 4'd10;
end
4'd10:begin
tx <= 1'b1;
tx_done <= 1'b1;
state <= 4'd10;
end
default:
state <= 4'd0;
endcase
end
end
else begin
tx_clk_en <= 1'b0;
state <= 1'b0;
tx_done <= 1'b0;
tx <= 1'b1;
end
end
endmodule
`timescale 1ns / 1ps
//
// Engineer: ian
//
// Create Date: 2019/11/29 22:08:48
// Design Name: bandrate generate
// Module Name: baudrate_gen
// Project Name: uart
// Target Devices: zynq7020
// Tool Versions: vivado 2018.3
// Description: This module is generate the baudrate clock of transmit and receive
//
// Revision: v1.0
// Revision 0.01 - File Created
//
//
//**********************************************************************************
//input port: sys_clk, //system clock
// sys_rst_n, //system reset, 0 is valid
// tx_clk_en, //tx module baudrate clock generate enable, 1 is valid
// rx_clk_en, //rx module baudrate clock generate enable, 1 is valid
//output port: tx_clk, //tx module baudrate clock
// rx_clk //rx module baudrate clock
//**********************************************************************************
module baudrate_gen(
//input port define
input sys_clk, //system clock
input sys_rst_n, //system reset, 0 is valid
input tx_clk_en, //tx module baudrate clock generate enable, 1 is valid
input rx_clk_en, //rx module baudrate clock generate enable, 1 is valid
//output port define
output tx_clk, //tx module baudrate clock
output rx_clk //rx module baudrate clock
);
//parameter define
parameter baud9600 = 5207, //baudrate -> 9600
baud115200 = 433; //baudrate -> 115200
parameter baud = baud115200; //baudrate select
//reg define
reg [12:0] cnt_rx; //rx module baudrate clock counter
reg [12:0] cnt_tx; //tx module baudrate clock counter
//****************************************
//-----rx module baudrate generate-----
//****************************************
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
cnt_rx <= 13'b0;
end
else if (rx_clk_en) begin
if (cnt_rx == baud) begin
cnt_rx <= 13'b0;
end
else begin
cnt_rx <= cnt_rx + 1'b1;
end
end
else
cnt_rx <= 13'b0;
end
assign rx_clk = (cnt_rx == 13'd1) ? 1'b1 : 1'b0;
//****************************************
//-----tx module baudrate generate-----
//****************************************
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
cnt_tx <= 13'b0;
end
else if (tx_clk_en) begin
if (cnt_tx == baud) begin
cnt_tx <= 13'b0;
end
else begin
cnt_tx <= cnt_tx + 1'b1;
end
end
else
cnt_tx <= 13'b0;
end
assign tx_clk = (cnt_tx == 13'd1) ? 1'b1 : 1'b0;
endmodule