vivado uartlite+block_ram实现串口向上位机发送数据,并保存在simple dual port block_ram里
1首先选择uartlite ip,然后选择bloc_ram IP,配置uartlite波特率为128000,block_ram 配置见下图。
port option选择根据自己需要改变。
其他默认,OK。
之后编写两个模块,uart控制模块和block_ram控制模块。
uart控制模块
`timescale 1ns / 1ps
module uart_rx(clk,rst,rx_data,arready,araddr,arvalid,rdata,rvalid ,rready,en1);
input clk;
input rst;
input arready;
input [31:0] rdata;
input rvalid;
output reg rready;
output reg [7:0] rx_data;
output reg [3:0] araddr;
output reg arvalid;
output reg en1;
reg [10:0] state_c;
reg [10:0] state_n;
reg [1:0]cnt;
parameter s0 = 16'b0000_0000_0000_0001;
parameter s1 = 16'b0000_0000_0000_0010;
parameter t1 = 16'b0000_0000_0000_0100;
parameter s2 = 16'b0000_0000_0000_1000;
parameter s3 = 16'b0000_0000_0001_0000;
parameter s4 = 16'b0000_0000_0010_0000;
parameter s5 = 16'b0000_0000_0100_0000;
parameter t5 = 16'b0000_0000_1000_0000;
parameter s6 = 16'b0000_0001_0000_0000;
parameter s7 = 16'b0000_0010_0000_0000;
parameter t7 = 16'b0000_0100_0000_0000;
always @ (posedge clk) begin
if(!rst) begin
state_c<=s0;
end
else begin
state_c<=state_n;
end
end
always @ (*) begin
case(state_c)
s0 : state_n=s4;
s4 : state_n=s5;
s5 : if(arready) begin
state_n=t5;
end
else begin
state_n=s5;
end
t5 : if(rvalid==1&&rdata[0]==1) begin
state_n=s6;
end
else if(rvalid==1&&rdata[0]==0) begin
state_n<=s0;
end
s6 : state_n=s7;
s7 : if(arready) begin
state_n=t7;
end
else begin
state_n=s7;
end
t7 : if(rvalid==1) begin
state_n=s0;
end
else begin
state_n=t7;
end
default : state_n=s0;
endcase
end
always @ (posedge clk or negedge rst) begin
if(!rst) begin
araddr<=4'h8;
arvalid<=0;
rready<=0;
cnt <= 0;
rx_data<=8'd0;
en1 <= 1'b0;
end
else
case(state_c)
s0 : begin
rx_data <= rx_data;
en1 <= 1'b0;
end
s4 : begin
araddr<=4'h8;
arvalid<=1;
rready<=1;
en1 <= 1'b0;
end
s5 : begin
rready<=1;
if(arready) begin
araddr<=4'h0;
arvalid<=0;
en1 <= 1'b0;
end
else begin
araddr<=4'h8;
arvalid<=1;
en1 <= 1'b0;
end
end
t5 : begin
if(rvalid) begin
rready<=0;
en1 <= 1'b0;
end
else begin
rready<=1;
en1 <= 1'b0;
end
end
s6 : begin
araddr<=4'h0;
arvalid<=1;
rready<=1;
en1 <= 1'b0;
end
s7 : begin
rready<=1;
if(arready) begin
araddr<=4'h0;
arvalid<=0;
en1 <= 1'b0;
end
else begin
araddr<=4'h0;
arvalid<=1;
en1 <= 1'b0;
end
end
t7 : begin
if(rvalid) begin
rready<=0;
rx_data<=rdata[7:0];
en1 <= 1'b1;
end
else begin
rready<=1;
rx_data <= rx_data;
en1 <= 1'b0;
end
end
default : begin
araddr<=4'h8;
arvalid<=0;
rready<=0;
rx_data<= 0;
en1 <= 0;
end
endcase
end
endmodule
block_men控制模块
`timescale 1ns / 1ps
module en_generate(clk,en1,addr,wr_en,wr_done);
input clk;
input en1;
output reg [9:0] addr;
output reg wr_en;
output reg wr_done;
initial begin
wr_en <= 0;
addr <= 10'd0;
wr_done<= 1'b0;
end
always@(posedge clk) begin
if(en1 )begin
if(addr<=10'd783)begin
addr <= addr+1'b1;
wr_en <= 1'b1;
end
else begin
addr <= addr;
wr_en <= 1'b0;
end
end
else begin
addr <= addr;
wr_en <= 1'b0;
end
end
always@(posedge clk) begin
if(addr>=10'd783)begin
wr_done=1'b1;
end end
endmodule
在两个控制模块编写完成之后,上位机已经可以通过串口发送数据到FPGA中并存入block_ram中了,为了测试数据是否存入block_ram 中,再给一个读block_ram 模块,将数据读出我是存入784个数据,可自行选择。
module im(clk,wr_done,addr1,);
input clk;
input wr_done;
output reg [9:0] addr1;
always@(posedge clk) begin
if(addr1<10'd784&&wr_done) begin
addr1<=addr1+1'b1;
end
end
endmodule
再将几个代码块生成 add module to block design
最后几个模块连线,生成如下所示电路图
综合 布局布线之后,下板子测试,上位机打开串口,配置。
下板测试结果如下:
项目地址:
为了实现连续发送数据,使用基于MFC串口工具实现多个数据连续发送 可以参考博客
https://blog.csdn.net/hawords/article/details/111053878