top
module top_uart
(
// clk and rst_n
input wire sys_clk ,
input wire sys_rst_n ,
// start send flag
input wire flag_send ,
// input data
input wire [7:0] in_data ,
// output data
output wire [7:0] rx_data ,
output wire flag_rx ,
// output tx
output wire tx_line ,
// input rx
input wire rx_line
);
tx tx_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.flag_send (flag_send),
.in_data (in_data),
.tx_line (tx_line)
);
rx rx_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.rx_line (rx_line),
.rx_data (rx_data),
.flag_rx (flag_rx)
);
endmodule
rx
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/05/23 17:29:35
// Design Name:
// Module Name: rx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module rx
(
// clk and rst_n
input wire sys_clk ,
input wire sys_rst_n ,
// input rx_line
input wire rx_line ,
// output rx_data and flag
output wire [7:0] rx_data ,
output wire flag_rx
);
localparam IDLE = 4'b0000 ;
localparam RECIVER = 4'b0001 ;
reg [3:0] current_state ;
reg [3:0] next_state ;
wire flag_tx ;
reg end_reciver ;
reg [7:0] out_rx_data ;
reg out_flag_rx ;
reg [7:0] cnt_receiver ;
assign debug_cnt_receiver = cnt_receiver ;
assign rx_data = out_rx_data ;
assign flag_rx = out_flag_rx ;
assign flag_tx = ( rx_line == 1'b0 )?1'b1:1'b0 ;
//one
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
current_state <= IDLE ;
end
else
begin
current_state <= next_state ;
end
end
//two
always@( * )
begin
case( current_state )
IDLE :
begin
if( flag_tx == 1'b1 )
begin
next_state = RECIVER ;
end
else
begin
next_state = IDLE ;
end
end
RECIVER :
begin
if( end_reciver == 1'b1 )
begin
next_state = IDLE ;
end
else
begin
next_state = RECIVER ;
end
end
default :
begin
next_state = IDLE ;
end
endcase
end
//three
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
out_rx_data <= 8'b00000000 ;
out_flag_rx <= 1'b0 ;
cnt_receiver <= 8'd0 ;
end
else
begin
case( current_state )
IDLE :
begin
out_rx_data <= 8'b00000000 ;
out_flag_rx <= 1'b0 ;
cnt_receiver <= 8'd0 ;
//rx_data[0] <= rx_line ;
out_rx_data[0] <= rx_line ;
end
RECIVER :
begin
if( cnt_receiver == 8'd0 )
begin
//rx_data[1] <= rx_line ;
out_rx_data[1] <= rx_line ;
cnt_receiver <= cnt_receiver + 1'b1 ;
end_reciver <= 1'b0 ;
end
else if( cnt_receiver == 8'd1 )
begin
//rx_data[2] <= rx_line ;
out_rx_data[2] <= rx_line ;
cnt_receiver <= cnt_receiver + 1'b1 ;
end_reciver <= 1'b0 ;
end
else if( cnt_receiver == 8'd2 )
begin
//rx_data[3] <= rx_line ;
out_rx_data[3] <= rx_line ;
cnt_receiver <= cnt_receiver + 1'b1 ;
end_reciver <= 1'b0 ;
end
else if( cnt_receiver == 8'd3 )
begin
//rx_data[4] <= rx_line ;
out_rx_data[4] <= rx_line ;
cnt_receiver <= cnt_receiver + 1'b1 ;
end_reciver <= 1'b0 ;
end
else if( cnt_receiver == 8'd4 )
begin
//rx_data[5] <= rx_line ;
out_rx_data[5] <= rx_line ;
cnt_receiver <= cnt_receiver + 1'b1 ;
end_reciver <= 1'b0 ;
end
else if( cnt_receiver == 8'd5 )
begin
//rx_data[6] <= rx_line ;
out_rx_data[6] <= rx_line ;
cnt_receiver <= cnt_receiver + 1'b1 ;
end_reciver <= 1'b0 ;
end
else if( cnt_receiver == 8'd6 )
begin
//rx_data[7] <= rx_line ;
out_rx_data[7] <= rx_line ;
cnt_receiver <= cnt_receiver + 1'b1 ;
end_reciver <= 1'b0 ;
end
else
begin
end_reciver <= 1'b1 ;
out_flag_rx <= 1'b1 ;
end
end
default :
begin
out_rx_data <= 8'b00000000 ;
out_flag_rx <= 1'b0 ;
cnt_receiver <= 8'd0 ;
end
endcase
end
end
endmodule
tx
module tx
(
// clk and rst_n
input wire sys_clk ,
input wire sys_rst_n ,
// start send flag
input wire flag_send ,
// input data
input wire [7:0] in_data ,
// output tx
output wire tx_line
);
localparam IDLE = 4'b0000 ;
localparam SEND = 4'b0001 ;
reg [3:0] current_state ;
reg [3:0] next_state ;
wire [7:0] len_word ;
reg [7:0] send_count ;
reg tx ;
assign tx_line = tx ;
// one
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
current_state <= IDLE ;
end
else
begin
current_state <= next_state ;
end
end
//two
always@( * )
begin
case( current_state )
IDLE :
begin
if( flag_send == 1'b1 )
begin
next_state = SEND ;
end
else
begin
next_state = IDLE ;
end
end
SEND :
begin
if( send_count == 8'd10 )
begin
next_state = IDLE ;
end
else
begin
next_state = SEND ;
end
end
default:
begin
next_state = IDLE ;
end
endcase
end
//three
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
tx <= 1'b1 ;
end
else
begin
case( current_state )
IDLE :
begin
tx <= 1'b1 ;
send_count <= 8'd0 ;
end
SEND :
begin
if( send_count == 8'd0 )
begin
tx <= 1'b0 ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd1 )
begin
tx <= in_data[0] ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd2 )
begin
tx <= in_data[1] ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd3 )
begin
tx <= in_data[2] ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd4 )
begin
tx <= in_data[3] ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd5 )
begin
tx <= in_data[4] ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd6 )
begin
tx <= in_data[5] ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd7 )
begin
tx <= in_data[6] ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd8 )
begin
tx <= in_data[7] ;
send_count <= send_count + 1'b1 ;
end
else if( send_count == 8'd9 )
begin
tx <= 1'b1 ;
send_count <= send_count + 1'b1 ;
end
else
begin
tx <= 1'b1 ;
send_count <= 8'd10 ;
end
end
default :
begin
tx <= 1'b1 ;
send_count <= 8'd10 ;
end
endcase
end
end
endmodule
tb code
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/05/24 11:28:47
// Design Name:
// Module Name: tb_rx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tb_rx
(
);
// clk and rst_n
reg sys_clk ;
reg sys_rst_n ;
// input rx_line
reg rx_line ;
// output rx_data and flag
wire [7:0] rx_data ;
wire flag_rx ;
wire [7:0] tb_data ;
assign tb_data = 8'b01100011 ;
initial
begin
sys_clk = 1'b0 ;
sys_rst_n = 1'b0 ;
#45 ;
sys_rst_n = 1'b1 ;
rx_line = 1'b0 ;
#10 ;
rx_line = tb_data[0] ;
#10 ;
rx_line = tb_data[1] ;
#10 ;
rx_line = tb_data[2] ;
#10 ;
rx_line = tb_data[3] ;
#10 ;
rx_line = tb_data[4] ;
#10 ;
rx_line = tb_data[5] ;
#10 ;
rx_line = tb_data[6] ;
#10 ;
rx_line = tb_data[7] ;
#10 ;
rx_line = 1'b1 ;
#10
#50;
$stop;
end
always #5
begin
sys_clk = ~sys_clk ;
end
rx rx_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.rx_line (rx_line),
.rx_data (rx_data),
.flag_rx (flag_rx)
);
endmodule
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/04/30 15:30:03
// Design Name:
// Module Name: tb_tx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tb_tx();
// clk and rst_n
reg sys_clk ;
reg sys_rst_n ;
// start send flag
reg flag_send ;
// input data
reg [7:0] in_data ;
// output tx
wire tx_line ;
initial
begin
sys_rst_n = 1'b0 ;
sys_clk = 1'b0 ;
flag_send = 1'b0 ;
#50 ;
in_data = 8'b01010011 ;
sys_rst_n = 1'b1 ;
flag_send = 1'b1 ;
#10 ;
flag_send = 1'b0 ;
#100 ;
$stop ;
end
always #10
begin
sys_clk = ~sys_clk ;
end
tx tx_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.flag_send (flag_send),
.in_data (in_data),
.tx_line (tx_line)
);
endmodule
tb结果
rx

tx
