串口输入86×86的数据,让连续三行对应列的三个数相加,结果串口输出
rx模块,串转并
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; 下板子用这个,波特率为9600
parameter CNT_BAUD_MaAX =9; //设置为9,方便仿真
//parameter CNT_HALF_BAUD_MAX =2603; 下板子用这个,波特率为9600
parameter CNT_HALF_BAUD_MAX =4; //设置为4,方便仿真
reg rx1,rx2,rx2_reg;
reg rx_flag;
reg [12:0] cnt_baud;
reg bit_flag;
reg [2:0] num;
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
ctrl_fifo模块
module crtl_fifo(
input wire pi_flag,
input wire [7:0]pi_data,
input wire clk,
input wire rst_n,
output reg [7:0] po,
output reg po_flag
);
reg [6:0]cnt_lie,cnt_row;
reg wr_en0,rd_en;
wire full0,empty0;
reg [7:0]wr_data0;
wire [7:0] dout0;
reg wr_en1;
wire full1,empty1;
reg [7:0]wr_data1;
wire [7:0] dout1;
fifo_generator_0 inst_fifo
(
.clk(clk),
.din( wr_data0 ),
. wr_en (wr_en0),
. rd_en (rd_en),
.dout(dout0),
.full(full0),
.empty(empty0)
);
fifo_generator_1 inst_fifo1
(
.clk(clk),
.din( wr_data1 ),
. wr_en (wr_en1),
. rd_en (rd_en),
.dout(dout1),
.full(full1),
.empty(empty1)
);
//cnt_lie,列的个数
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
cnt_lie <= 1'b0;
end
else if (cnt_lie == 'd85&&pi_flag== 'd1) begin
cnt_lie <= 1'b0;
end
else if (pi_flag== 'd1) begin
cnt_lie <= cnt_lie+1'b1;
end
end
//cnt_row,行的个数
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
cnt_row <= 1'b0;
end
else if (cnt_row == 'd85&&pi_flag== 'd1&&cnt_lie == 'd85) begin
cnt_row <= 1'b0;
end
else if (pi_flag== 'd1&&cnt_lie == 'd85) begin
cnt_row <=cnt_row+1'b1;
end
end
//wr_en0,fifo0写使能,当行数为0或2-84时fifo0写使能有效
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
wr_en0 <= 1'b0;
end
else if ((cnt_row== 'd0&&pi_flag==1)||(cnt_row>=2&&cnt_row<=84&&pi_flag==1)) begin
wr_en0 <= 1'b1;
end
else wr_en0 <= 1'b0;
end
//wr_data0,fifo0写数据,第0行时写入rx_data,2-84写入fif01中读出的数据
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
wr_data0 <= 1'b0;
end
else if (pi_flag==1&&cnt_row== 'd0) begin
wr_data0 <= pi_data;
end
else if(cnt_row>=2&&cnt_row<=84&&pi_flag==1)
wr_data0 <= dout1;
end
//wr_en1,fifo1写使能,当行数1-84时fifo1写使能有效
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
wr_en1 <= 1'b0;
end
else if (cnt_row>=1&&cnt_row<=84&&pi_flag==1) begin
wr_en1 <= 1'b1;
end
else wr_en1 <= 1'b0;
end
//wr_data1,fifo1写数据,写入rx_data
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
wr_data1 <= 1'b0;
end
else if (pi_flag==1&&cnt_row>=1&&cnt_row<=84) begin
wr_data1 <= pi_data;
end
end
//rd_en,读使能,第2-85行
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
rd_en <= 1'b0;
end
else if (cnt_row>=2&&pi_flag==1) begin
rd_en <= 1'b1;
end
else rd_en <= 1'b0;
end
//fifo0,fifo1与pi_flag求和
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
po <= 1'b0;
po_flag<='b0;
end
else if (rd_en=='d1) begin
po <= pi_data+dout1+dout0;
po_flag<='d1;
end
else po_flag<='b0;
end
endmodule
top模块
module top(
input wire clk,
input wire rst_n,
input wire rx,
output wire tx
);
wire [7:0]data;
wire flag;
wire flag_sumover;
wire [7:0]sum;
uart_rx inst_rx(
.sclk(clk),
.rst_n(rst_n),
.rx(rx),
.po_data(data),
.po_flag(flag)
);
uart_tx inst_tx(
.sclk(clk),
.rst_n(rst_n),
.pi_flag(flag_sumover),
.pi_data(sum),
.tx(tx)
);
crtl_fifo int_ctrl(
.pi_flag(flag),
.pi_data(data),
.clk(clk),
.rst_n(rst_n),
.po(sum),
.po_flag(flag_sumover)
);
endmodule
tx模块
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; 下板子用这个,波特率9600
parameter CNT_BAUD_MAX =9; //为了仿真方便,设置为9
reg [7:0] data_reg;
reg tx_flag,pi_flag2;
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
pi_flag2 <='d0;
end
else if (pi_flag == 1'b1) begin
pi_flag2 <=1;
end
else pi_flag2 <='d0;
end
always @(posedge sclk or negedge rst_n) begin
if (rst_n == 1'b0) begin
data_reg <='d0;
end
else if (pi_flag2 == 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
仿真模块
`timescale 1ns / 1ps
module tb_top_uart;
// Inputs
reg sclk;
reg rst_n;
reg rx;
reg [7:0]mem[85:0];
// Outputs
wire tx;
// Instantiate the Unit Under Test (UUT)
top uut (
.clk(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
always #10 sclk = ~sclk;
initial begin
$readmemb("C:/zynq/fifo-add/fifo-add.srcs/sim_1/new/data.txt",mem);
end
initial begin
#200;
rx_byte();
end
task rx_byte();
integer i;
integer j;
begin
for(j=0;j<86;j=j+1)begin
for (i=0;i<86;i=i+1)begin
rx_bit(mem[i]);
end
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;
#200;
end
end
endtask
endmodule
仿真效果
注:FIFO采用的是First-Word Fall-Through 读模式,读出的数据和读使能之间无延迟。