顶层代码:
module uart_rx_top(Clk,Rst_n,Rs232_Rx);
input Clk;
input Rst_n;
input Rs232_Rx;
reg [7:0]data_rx_r;
wire [7:0]data_rx;
wire Rx_Done;
uart_byte_rx uart_byte_rx(
.Clk(Clk),
.Rst_n(Rst_n),
.baud_set(3'd0),
.Rs232_Rx(Rs232_Rx),
.data_byte(data_rx),
.Rx_Done(Rx_Done)
);
issp issp(
.probe(data_rx_r),
.source()
);
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
data_rx_r <= 8'd0;
else if(Rx_Done)
data_rx_r <= data_rx;
else
data_rx_r <= data_rx_r;
endmodule
工程模块代码:
输入 Clk(时钟),Rst_n(复位),baud_set(波特率设置),Rs232_Rx(输入数据)
输出 data_byte(接收的数据),Rx_Done
module uart_byte_rx(
Clk,
Rst_n,
baud_set,
Rs232_Rx,
data_byte,
Rx_Done
);
input Clk;
input Rst_n;
input [2:0]baud_set;
input Rs232_Rx;
output reg [7:0]data_byte;
output reg Rx_Done;
reg s0_Rs232_Rx,s1_Rs232_Rx;//同步寄存器
reg tmp0_Rs232_Rx,tmp1_Rs232_Rx;//数据寄存器
reg [15:0]bps_DR;//分频计数器计数最大值
reg [15:0]div_cnt;//分频计数器
reg bps_clk;//
reg [7:0]bps_cnt;
reg uart_state;
reg [2:0] r_data_byte [7:0];
reg [7:0] tmp_data_byte;
reg [2:0] START_BIT,STOP_BIT;
wire nedege;
//同步寄存器,消除亚稳态
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
s0_Rs232_Rx <= 1'b0;
s1_Rs232_Rx <= 1'b0;
end
else begin
s0_Rs232_Rx <= Rs232_Rx;
s1_Rs232_Rx <= s0_Rs232_Rx;
end
//数据寄存器
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
tmp0_Rs232_Rx <= 1'b0;
tmp1_Rs232_Rx <= 1'b0;
end
else begin
tmp0_Rs232_Rx <= s1_Rs232_Rx;
tmp1_Rs232_Rx <= tmp0_Rs232_Rx;
end
assign nedege = !tmp0_Rs232_Rx & tmp1_Rs232_Rx;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
bps_DR <= 16'd324;
else begin
case(baud_set)
0:bps_DR <= 16'd324;
1:bps_DR <= 16'd162;
2:bps_DR <= 16'd80;
3:bps_DR <= 16'd53;
4:bps_DR <= 16'd26;
default:bps_DR <= 16'd324;
endcase
end
//counter
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
div_cnt <= 16'd0;
else if(uart_state)begin
if(div_cnt == bps_DR)
div_cnt <= 16'd0;
else
div_cnt <= div_cnt + 1'b1;
end
else
div_cnt <= 16'd0;
// bps_clk gen
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
bps_clk <= 1'b0;
else if(div_cnt == 16'd1)
bps_clk <= 1'b1;
else
bps_clk <= 1'b0;
//bps counter
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
bps_cnt <= 8'd0;
else if(bps_cnt == 8'd159 | (bps_cnt == 8'd12 && (START_BIT > 2)))
bps_cnt <= 8'd0;
else if(bps_clk)
bps_cnt <= bps_cnt + 1'b1;
else
bps_cnt <= bps_cnt;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
Rx_Done <= 1'b0;
else if(bps_cnt == 8'd159)
Rx_Done <= 1'b1;
else
Rx_Done <= 1'b0;
// always@(posedge Clk or negedge Rst_n)
// if(!Rst_n)
// data_byte <= 8'd0;
// else if(bps_cnt == 8'd159)
// data_byte <= tmp_data_byte;
// else
// data_byte <= data_byte;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
data_byte <= 8'd0;
else if(bps_cnt == 8'd159)begin
data_byte[0] <= r_data_byte[0][2];
data_byte[1] <= r_data_byte[1][2];
data_byte[2] <= r_data_byte[2][2];
data_byte[3] <= r_data_byte[3][2];
data_byte[4] <= r_data_byte[4][2];
data_byte[5] <= r_data_byte[5][2];
data_byte[6] <= r_data_byte[6][2];
data_byte[7] <= r_data_byte[7][2];
end
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
START_BIT = 3'd0;
r_data_byte[0] <= 3'd0;
r_data_byte[1] <= 3'd0;
r_data_byte[2] <= 3'd0;
r_data_byte[3] <= 3'd0;
r_data_byte[4] <= 3'd0;
r_data_byte[5] <= 3'd0;
r_data_byte[6] <= 3'd0;
r_data_byte[7] <= 3'd0;
STOP_BIT = 3'd0;
end
else if(bps_clk)begin
case(bps_cnt)
0:begin
START_BIT = 3'd0;
r_data_byte[0] <= 3'd0;
r_data_byte[1] <= 3'd0;
r_data_byte[2] <= 3'd0;
r_data_byte[3] <= 3'd0;
r_data_byte[4] <= 3'd0;
r_data_byte[5] <= 3'd0;
r_data_byte[6] <= 3'd0;
r_data_byte[7] <= 3'd0;
STOP_BIT = 3'd0;
end
6,7,8,9,10,11:START_BIT <= START_BIT + s1_Rs232_Rx; //每位数据取16次,认为1-5和12-16不稳定,取6-11,看其中1/0数谁多,取该数据为谁
22,23,24,25,26,27:r_data_byte[0] <= r_data_byte[0] + s1_Rs232_Rx;
38,39,40,41,42,43:r_data_byte[1] <= r_data_byte[1] + s1_Rs232_Rx;
54,55,56,57,58,59:r_data_byte[2] <= r_data_byte[2] + s1_Rs232_Rx;
70,71,72,73,74,75:r_data_byte[3] <= r_data_byte[3] + s1_Rs232_Rx;
86,87,88,89,90,91:r_data_byte[4] <= r_data_byte[4] + s1_Rs232_Rx;
102,103,104,105,106,107:r_data_byte[5] <= r_data_byte[5] + s1_Rs232_Rx;
118,119,120,121,122,123:r_data_byte[6] <= r_data_byte[6] + s1_Rs232_Rx;
134,135,136,137,138,139:r_data_byte[7] <= r_data_byte[7] + s1_Rs232_Rx;
150,151,152,153,154,155:STOP_BIT <= STOP_BIT + s1_Rs232_Rx;
default:
begin
START_BIT = START_BIT;
r_data_byte[0] <= r_data_byte[0];
r_data_byte[1] <= r_data_byte[1];
r_data_byte[2] <= r_data_byte[2];
r_data_byte[3] <= r_data_byte[3];
r_data_byte[4] <= r_data_byte[4];
r_data_byte[5] <= r_data_byte[5];
r_data_byte[6] <= r_data_byte[6];
r_data_byte[7] <= r_data_byte[7];
STOP_BIT = STOP_BIT;
end
endcase
end
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
uart_state <= 1'b0;
else if(nedege)
uart_state <= 1'b1;
else if(Rx_Done || (bps_cnt == 8'd12 && (START_BIT > 2)))
uart_state <= 1'b0;
else
uart_state <= uart_state;
endmodule
测试代码:
`timescale 1ns/1ns
`define clk_period 20
module uart_byte_rx_tb;
reg Clk;
reg Rst_n;
reg Rs232_Rx;
wire [7:0]data_byte_r;
wire Rx_Done;
reg [7:0]data_byte_t;
reg send_en;
reg [2:0]baud_set;
wire Rs232_Tx;
wire Tx_Done;
wire uart_state;
uart_byte_rx uart_byte_rx(
.Clk(Clk),
.Rst_n(Rst_n),
.baud_set(baud_set),
.Rs232_Rx(Rs232_Tx),
.data_byte(data_byte_r),
.Rx_Done(Rx_Done)
);
uart_byte_tx uart_byte_tx(
.Clk(Clk),
.Rst_n(Rst_n),
.data_byte(data_byte_t),
.send_en(send_en),
.baud_set(baud_set),
.Rs232_Tx(Rs232_Tx),
.Tx_Done(Tx_Done),
.uart_state(uart_state)
);
initial Clk = 1;
always#(`clk_period/2)Clk = ~Clk;
initial begin
Rst_n = 1'b0;
data_byte_t = 8'd0;
send_en = 1'd0;
baud_set = 3'd4;
#(`clk_period*20 + 1 );
Rst_n = 1'b1;
#(`clk_period*50);
data_byte_t = 8'haa;
send_en = 1'd1;
#`clk_period;
send_en = 1'd0;
@(posedge Tx_Done)
#(`clk_period*5000);
data_byte_t = 8'h55;
send_en = 1'd1;
#`clk_period;
send_en = 1'd0;
@(posedge Tx_Done)
#(`clk_period*5000);
$stop;
end
endmodule