摘自威三学员尤凯元
tb文件
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2019 All rights reserved
// -----------------------------------------------------------------------------
// Author : Youkaiyuan v3eduyky@126.com
// wechat : 15921999232
// File : tb_top_uart.v
// Create : 2019-03-28 12:01:49
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
`timescale 1ns / 1ps
module tb_top_uart;
// Inputs
reg sclk;
reg rst_n;
reg rx;
reg [7:0] mem[15:0];
// Outputs
wire tx;
// Instantiate the Unit Under Test (UUT)
top_uart uut (
.sclk(sclk),
.rst_n(rst_n),
.rx(rx),
.tx(tx)
);
initial begin
// Initialize Inputs
sclk = 0;
rst_n = 0;
rx = 1;
// Wait 100 ns for global reset to finish
#100;
rst_n =1;
// Add stimulus here
end
initial begin
$readmemh("./data.txt",mem);
end
always #10 sclk = ~sclk;
initial begin
#200;
rx_byte();
end
task rx_byte();
integer i;
begin
for (i=0;i<16;i=i+1)begin
rx_bit(mem[i]);
end
end
endtask
task rx_bit(input [7:0] data);
integer i;
begin
for(i=0;i<10;i=i+1) begin
case (i)
0:rx =0;
1:rx =data[i-1];
2:rx =data[i-1];
3:rx =data[i-1];
4:rx =data[i-1];
5:rx =data[i-1];
6:rx =data[i-1];
7:rx =data[i-1];
8:rx =data[i-1];
9:rx =1;
endcase
#104160;
end
end
endtask
endmodule
data.txt
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
top_uart.v
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2019 All rights reserved
// -----------------------------------------------------------------------------
// Author : Youkaiyuan v3eduyky@126.com
// wechat : 15921999232
// File : top_uart.v
// Create : 2019-03-28 11:53:38
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
module top_uart(
input wire sclk,
input wire rst_n,
input wire rx,
output wire tx
);
wire flag;
wire [7:0] data;
uart_rx inst_uart_rx (
.sclk (sclk),
.rst_n (rst_n),
.rx (rx),
.po_data (data),
.po_flag (flag)
);
uart_tx inst_uart_tx (
.sclk (sclk),
.rst_n (rst_n),
.pi_flag (flag),
.pi_data (data),
.tx (tx)
);
endmodule
uart_rx.v
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2019 All rights reserved
// -----------------------------------------------------------------------------
// Author : Youkaiyuan v3eduyky@126.com
// wechat : 15921999232
// File : uart_rx.v
// Create : 2019-03-28 10:32:23
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
module uart_rx(
input wire sclk,
input wire rst_n,
input wire rx,
output reg [7:0] po_data,
output reg po_flag
);
parameter CNT_BAUD_MAX = 5207;
parameter CNT_HALF_BAUD_MAX = 2603;
reg rx1,rx2,rx2_reg;
reg rx_flag;
reg [12:0] cnt_baud;
reg bit_flag;
reg [3:0] bit_cnt;
always @(posedge sclk) begin
{rx2_reg,rx2,rx1}<={rx2,rx1,rx};
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
rx_flag <= 1'b0;
end
else if (bit_cnt == 4'd8 && bit_flag == 1'b1) begin
rx_flag <= 1'b0;
end
else if (rx2_reg == 1'b1 && rx2 == 1'b0) begin
rx_flag <= 1'b1;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
cnt_baud <= 'd0;
end
else if (rx_flag == 1'b0) begin
cnt_baud <= 'd0;
end
else if (rx_flag == 1'b1 && cnt_baud == CNT_BAUD_MAX) begin
cnt_baud <= 'd0;
end
else if (rx_flag == 1'b1) begin
cnt_baud <= cnt_baud + 1'b1;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
bit_flag <= 1'b0;
end
else if (rx_flag == 1'b1 && cnt_baud == CNT_HALF_BAUD_MAX) begin
bit_flag <= 1'b1;
end
else begin
bit_flag <= 1'b0;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
bit_cnt <= 'd0;
end
else if (bit_flag == 1'b1 && bit_cnt == 'd8) begin
bit_cnt <= 'd0;
end
else if (bit_flag == 1'b1) begin
bit_cnt <= bit_cnt + 1'b1;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
po_data <='d0;
end
else if (bit_cnt >= 4'd1 && bit_flag == 1'b1) begin
po_data <= {rx2_reg,po_data[7:1]};
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
po_flag <= 1'b0;
end
else if (bit_cnt == 4'd8 && bit_flag == 1'b1) begin
po_flag <= 1'b1;
end
else begin
po_flag <= 1'b0;
end
end
endmodule
uart_tx.v
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2019 All rights reserved
// -----------------------------------------------------------------------------
// Author : Youkaiyuan v3eduyky@126.com
// wechat : 15921999232
// File : uart_tx.v
// Create : 2019-03-28 11:34:39
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
module uart_tx(
input wire sclk,
input wire rst_n,
input wire pi_flag,
input wire [7:0] pi_data,
output reg tx
);
parameter CNT_BAUD_MAX = 5207;
reg [7:0] data_reg;
reg tx_flag;
reg [12:0] cnt_baud;
reg bit_flag;
reg [3:0] bit_cnt;
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
data_reg <='d0;
end
else if (pi_flag == 1'b1) begin
data_reg <= pi_data;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
tx_flag <= 1'b0;
end
else if(bit_flag == 1'b1 && bit_cnt == 4'd8) begin
tx_flag <= 1'b0;
end
else if (pi_flag == 1'b1) begin
tx_flag <= 1'b1;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
cnt_baud <= 'd0;
end
else if(tx_flag == 1'b0)begin
cnt_baud <='d0;
end
else if (tx_flag == 1'b1 && cnt_baud == CNT_BAUD_MAX) begin
cnt_baud <= 'd0;
end
else if (tx_flag == 1'b1) begin
cnt_baud <= cnt_baud + 1'b1;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
bit_flag <= 1'b0;
end
else if (cnt_baud == CNT_BAUD_MAX -1 && tx_flag == 1'b1) begin
bit_flag <= 1'b1;
end
else begin
bit_flag <= 1'b0;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
bit_cnt <= 'd0;
end
else if(bit_flag == 1'b1 && bit_cnt == 4'd8) begin
bit_cnt <= 'd0;
end
else if (bit_flag == 1'b1) begin
bit_cnt <= bit_cnt + 1'b1;
end
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
tx <= 1'b1;
end
else if (pi_flag == 1'b1) begin
tx <= 1'b0;
end
else if (bit_cnt<=7 && bit_flag == 1'b1) begin
tx <= data_reg[bit_cnt];
end
else if (bit_flag == 1'b1 && bit_cnt == 4'd8) begin
tx <= 1'b1;
end
end
endmodule