该模块功能, 接收数据。
module rs232_rx_cnt(
clk,
rst_n,
sel_bps,
uart_rx,
rx_done,
data_recv);
input clk;
input rst_n;
input uart_rx;
input [2:0] sel_bps;
output rx_done;
output [7:0] data_recv;
reg [11:0] cnt1;//第一阶段计数器
reg [12:0] cnt2;
reg [12:0] Time;
always @(*) begin
if (sel_bps == 3'd0)
Time <= 5208; //9600
else if (sel_bps == 3'd1)
Time <= 1302; //38400
else if (sel_bps == 3'd2)
Time <= 434; //115200
else
Time <= 5208;
end
reg rx1,rx2;
always @ (posedge clk or negedge rst_n) begin
if ( rst_n == 1'b0) begin
rx1 <= 1'b0;
rx2 <= 1'b0;
end
else if (sta ==IDLE)
begin
rx1 <= uart_rx;
rx2 <= rx1;
end
else begin
rx1 <= 1'b0;
rx2 <= 1'b0;
end
end
assign start = !rx1 & rx2;
reg [1:0] sta;
parameter IDLE=2'd0;
parameter S1=2'd1;
parameter S2=2'd2;
always @ (posedge clk or negedge rst_n) begin
if (rst_n ==1'b0)
sta <= IDLE;
else
begin
case(sta)
IDLE: begin
if (start==1'b1)
sta <= S1;
else
sta <= IDLE;
end
S1: begin
if (cnt1== Time[11:1])
sta <= S2;
else
sta <= S1;
end
S2: begin
if (rx_done == 1'b1)
sta <= IDLE;
else
sta <= S2;
end
endcase
end
end
always @ (posedge clk or negedge rst_n) begin
if (rst_n ==1'b0)
cnt1 <= 12'd0;
else if (sta==S1)
begin
if (cnt1== Time[11:1])
cnt1 <= 12'd0;
else
cnt1 <= cnt1 + 1'b1;
end
else
begin
cnt1 <= 12'd0;
end
end
//周期性cnt2, 产生采样脉冲
reg pulse_sample ;
always @ (posedge clk or negedge rst_n) begin
if (rst_n ==1'b0)
begin
cnt2 <= 13'd0;
pulse_sample <= 1'b0;
end
else if (sta == S2) begin
if (cnt2 == Time-1)
begin
cnt2 <= 13'd0;
pulse_sample <= 1'b1;
end
else
begin
cnt2 <= cnt2 + 1'd1;
pulse_sample <= 1'b0;
end
end
else
begin
cnt2 <= 13'd0;
pulse_sample <= 1'b0;
end
end
//根据采样脉冲,接收数据
reg [7:0] data_buf;
always @ (posedge clk or negedge rst_n) begin
if (rst_n ==1'b0)
data_buf <= 8'd0;
else
if (sta == S2)
begin
if (pulse_sample == 1'b1)
begin
// data_recv <= {data_recv[6:0], uart_rx};
data_buf <= {uart_rx, data_buf[7:1]};
end
else
data_buf <= data_buf;
end
else
data_buf <= 8'd0;
end
reg [3:0] cnt3;
always @ (posedge clk or negedge rst_n)
if (rst_n ==1'b0)
cnt3 <= 3'd0;
else
begin
if (sta == S2)
begin
if (cnt2 == Time-1)
cnt3 <= cnt3 + 1'b1;
else
cnt3 <= cnt3;
end
else
cnt3 <= 3'd0;
end
//assign rx_done = ((cnt2 == Time-1) && (cnt3 == 3'd8));
assign rx_done = ((cnt2 == Time-1) && (cnt3 == 4'd8));
assign data_recv = rx_done ? data_buf: data_recv;
endmodule
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
这里是发送模块
module rs232_tx_cnt(
Clk,
rst_n,
en_go,
tx_done,
sel_bps,
Data,
uart_tx);
input Clk;
input rst_n;
input en_go;
output tx_done;
input [2:0] sel_bps;
input [7:0] Data;
output reg uart_tx;
reg [20:0] Time;
reg [31:0] counter;
reg [3:0] counter2;
wire bps_Start;
reg en;
always @(*) begin
if (sel_bps == 3'd0)
Time <= 5208; //9600
else if (sel_bps == 3'd1)
Time <= 1302; //38400
else if (sel_bps == 3'd2)
Time <= 434; //115200
else
Time <= 5208;
end
always @(posedge Clk or negedge rst_n) begin
if ( rst_n == 1'b0)
en <= 0;
else if (en_go == 1'b1)
en <= 1;
else if (tx_done == 1'b1)
en <= 0;
else
en <= en;
end
reg [7:0] R_Data;
always @(posedge Clk or negedge rst_n) begin
if ( rst_n == 1'b0)
R_Data <= 0;
else if (en_go == 1'b1)
R_Data <= Data;
else
R_Data <= R_Data;
end
//bps产生
always @(posedge Clk or negedge rst_n) begin
if ( rst_n == 1'b0)
counter <= 0;
else if (en == 1'b1)
begin
if (counter == Time - 1)
counter <= 0;
else
counter <= counter + 1'd1;
end
else
counter <= 0;
end
assign bps_Start = ((counter == 0) && (en==1'b1));
always @(posedge Clk or negedge rst_n) begin
if ( rst_n == 1'b0)
counter2 <= 0;
else if( en == 1'b1)
begin
if (tx_done)
counter2 <=0;
else if (counter == Time - 1)
counter2 <= counter2 + 1'b1;
else
counter2 <= counter2;
end
else
counter2 <= 0;
end
assign tx_done = ((counter2 == 9) && (counter == Time - 1));
always @(posedge Clk or negedge rst_n) begin
if (rst_n == 1'b0)
uart_tx <= 1'b1;
else if ( en ==1'b1) begin
case(counter2 )
0: uart_tx <= 1'b0;
1: uart_tx <= R_Data[0];
2: uart_tx <= R_Data[1];
3: uart_tx <= R_Data[2];
4: uart_tx <= R_Data[3];
5: uart_tx <= R_Data[4];
6: uart_tx <= R_Data[5];
7: uart_tx <= R_Data[6];
8: uart_tx <= R_Data[7];
9: uart_tx <= 1'b1;
default : uart_tx <= 1'b1;
endcase
end
else
uart_tx <= 1'b1;
end
endmodule
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
这里是顶层文件
`timescale 1ns/1ps
module top(clk, Rest_n,uart_tx ) ;
input Rest_n;
input clk;
output uart_tx;
reg [7:0] data;
//wire tx_done;
reg en_go;
reg [20:0] cnt;
rs232_tx_cnt u2(
.Clk(clk),
.rst_n(Rest_n),
.en_go(en_go),
.tx_done(),
.sel_bps(3'd2),//
.Data(data),
.uart_tx(uart_tx)
);
always @(posedge clk or negedge Rest_n) begin
if ( Rest_n == 1'b0) begin
en_go <= 0;
data <= 8'h54;
end
else if( cnt == 1) begin
en_go <= 1'b1;
data <=data+1'd1;
end
else en_go <= 1'b0;
end
always @(posedge clk or negedge Rest_n) begin
if ( Rest_n == 1'b0)
cnt <= 0;
//else if( cnt == 50000000 -1) //
else if( cnt == 50000 -1) //for simualato
cnt <= 0;
else
cnt <= cnt + 1'd1;
end
wire [7:0] data_recv;
rs232_rx_cnt u3(
.clk(clk),
.rst_n(Rest_n),
.sel_bps(3'd2),
.uart_rx(uart_tx),
.rx_done(),
.data_recv(data_recv)
);
endmodule
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
下面是 测试的tb文件
module top_tb();
reg clk;
reg rst_n;
wire uart_tx;
initial clk = 1;
initial begin
rst_n= 0;
#201; rst_n=1;
#10000000;
$stop;
end
top u1(.clk(clk),
.Rest_n(rst_n),
.uart_tx (uart_tx)) ;
always #10 clk = ~clk;//50Mhz 时钟
endmodule
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
运行之后,下面的仿真结果的图:
从图上发现,rx_done完成信号,有一个脉冲之后,data_recv是收到的数据0x55. tb文件里面发送的是顺序数,因此,下一个数据是55,56.。。。。
说明串口的接收模块也能正常的接收数据了。
来源:oschina
链接:https://my.oschina.net/u/4346770/blog/4872163