【双FiFo流水线操作】

这篇文章详细描述了一个硬件设计中的串口输入模块,用于处理86x86数据,通过连续三行对应列的数值相加,并通过串转并模块实现。同时介绍了FIFO的控制逻辑,以及整个系统的时序同步和仿真过程。着重展示了UART通信和数据处理的实现方法。
摘要由CSDN通过智能技术生成

串口输入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 读模式,读出的数据和读使能之间无延迟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值