FPGA实验之串口接收
串口数据的接收采样在每个数据位的中间,这样能够采集到比较准确的数据。
(1) 建立工程
(2) 编写程序
module UART_receive(input CLK,RST,RXD,
output Receive_done,Odd_data,
output [7:0]Receive_data);
//parameter BPS9600=13'd5208; //每位数据传输时间为t=1/9600 s,周期T=1/50000000,计数值为t/T=5208
parameter BPS115200=9'd434;//每位数据传输时间为t=1/115200 s,周期T=1/50000000,计数值为t/T=434
reg [31:0]C1;
reg [7:0]ii;
reg H2L1,H2L2;
reg receive_done,odd_data;
reg [7:0]receive_data;
always @(posedge CLK or negedge RST)
if(!RST)
begin C1<=32'd0;ii<=0; receive_done<=0; receive_data<=8'b0; odd_data<=1'b0;end
else
case(ii)
0: if(!RXD) beginii<=ii+1;end
1: if(C1==BPS115200)begin C1<=32'd0; ii<=ii+1; end //起始位,,没做处理,直接忽略
elseC1<=C1+1;
2,3,4,5,6,7,8,9:begin
if(C1==BPS115200-1)begin C1<=32'd0; ii<=ii+1; end //接收数据位
elseC1<=C1+1;
if(C1==BPS115200>>1)begin receive_data[ii-2]<=RXD; end
end
10:beginif(C1==BPS115200-1) begin C1<=32'd0; ii<=ii+1; end //接收校验位
elseC1<=C1+1;
if(C1==BPS115200>>1)begin odd_data<=RXD;end
end
11:if(C1==BPS115200-1) begin C1<=32'd0; ii<=ii+1; end //接收停止位,依然没做处理
elseC1<=C1+1;
12:beginreceive_done<=1;ii<=ii+1;end //产生接收完成信号
13:beginreceive_done<=0;ii<=0;end //产生接收完成信号
endcase
assign Receive_data=receive_data;
assign Receive_done=receive_done;
assign Odd_data=odd_data;
endmodule
以下为激励信号:
`timescale 1 ps/ 1 ps
module UART_receive_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg CLK;
reg RST;
wire RXD;
reg TXD;
reg [7:0] i;
reg odd_data;
reg [31:0]C1;
reg [7:0] data;
parameter BPS115200=9'd434;//每位数据传输时间为t=1/115200 s,周期T=1/50000000,计数值为t/T=434
// wires
wire Odd_data;
wire [7:0] Receive_data;
wire Receive_done;
// assign statements (if any)
UART_receive i1 (
// port map - connection between master ports andsignals/registers
.CLK(CLK),
.Odd_data(Odd_data),
.RST(RST),
.RXD(RXD),
.Receive_data(Receive_data),
.Receive_done(Receive_done)
);
initial
begin
RST = 0; #10; RST = 1;
CLK = 0; forever #10 CLK =~CLK;
end
always @(posedge CLK or negedgeRST)
if(!RST)
beginTXD<=1; i<=0; C1<=32'd0;data<=8'b11111111;end
else
case(i)
0:if(C1==BPS115200) begin C1<=32'd0; i<=i+1; end //起始位
elsebegin C1<=C1+1'd1; TXD<=1'b0; odd_data<=^~data; end //按位同或求奇校验,,,如果按位异或(even_data<=^data;)求偶校验
1,2,3,4,5,6,7,8:
if(C1==BPS115200)begin C1<=32'd0; i<=i+1; end //数据位
elsebegin C1<=C1+1'd1; TXD<=data[i-1]; end
9:if(C1==BPS115200) begin C1<=32'd0; i<=i+1; end //校验位
elsebegin C1<=C1+1'd1; TXD<=odd_data; end
10:if(C1==BPS115200)begin C1<=32'd0; i<=i+1; end // 停止位
elsebegin C1<=C1+1'd1; TXD<=1'b1; end
11:if(Receive_done)begin i<=i+1;end
elsei<=i;
12:i<=i;
endcase
assign RXD = TXD ;
endmodule
(3)ModelSim仿真