fpga项目:uart_rx_fifo - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

设计和验证框图

image

uart_rx_wrapper.v (uart_rx+fifo)

`timescale 1ns / 1ps

module uart_rx_wrapper(
    input clk,
    input rst_n,
    
    output [7:0] dout,
    input rd_en,
    
    output full,
    output almost_full,
    output empty,
    output almost_empty,
    input rx
    );
    
    wire [8 : 0] data_count; 
    wire [7:0] din;      
    
    uart_rx uart_rx_inst
    (
        .sys_clk(clk),
        .sys_rst_n(rst_n),
        .po_data(din),
        .po_flag(xfer_vld),
        .rx(rx)
    );    
    
    assign wr_en=xfer_vld && (~full);  
    
    fifo_generator_0 your_instance_name (
      .clk(clk),                    // input wire clk
      .din(din),                    // input wire [7 : 0] din
      .wr_en(wr_en),                // input wire wr_en
      .rd_en(rd_en),                // input wire rd_en
      .dout(dout),                  // output wire [7 : 0] dout
      .full(full),                  // output wire full
      .almost_full(almost_full),    // output wire almost_full
      .empty(empty),                // output wire empty
      .almost_empty(almost_empty),  // output wire almost_empty
      .data_count(data_count)      // output wire [8 : 0] data_count
    ); 
endmodule

syn_uart_rx_fifo_wrapper2.v

`timescale 1ns / 1ps

module syn_uart_rx_fifo_wrapper2(
    input clk,
    input rst_n,
    
    input  sw,
    output empty,
    output full,
    
    input rx,
    output tx
    );
    
    /*********************************************************************************/ 
    parameter CNT_MAX=50_000_000/100;
    parameter LSM_MAX=512;
    bit [31:0] div_cnt;
    bit [5:0] lsm_cnt;
    bit cnt_valid;
    
    always @(posedge clk or negedge rst_n)
    if(rst_n==0)
        div_cnt<=0;
    else if(add_div_cnt) begin
        if(end_div_cnt)
            div_cnt<=0;
        else
            div_cnt<=div_cnt+1; 
    end 
    
    assign add_div_cnt=cnt_valid;
    assign end_div_cnt=add_div_cnt && (div_cnt==CNT_MAX-1);    
        
    always @(posedge clk or negedge rst_n)
    if(rst_n==0)
        lsm_cnt<=0;
    else if(add_lsm_cnt) begin
        if(end_lsm_cnt)
            lsm_cnt<=0; 
        else
            lsm_cnt<=lsm_cnt+1;    
    end
    
    assign add_lsm_cnt=end_div_cnt && cnt_valid;
    assign end_lsm_cnt=add_lsm_cnt && (lsm_cnt==LSM_MAX-1); 

    assign cnt_valid=sw && (~empty);  
    
    /*********************************************************************************/ 
    
    bit [7:0] dout;
    bit [7:0] xfer_dout;
    bit xfer_start;
    bit rd_en;
    
    always @(posedge clk or negedge rst_n)
    if(rst_n==0) begin
        rd_en<=0;
    end
    else if(add_lsm_cnt) begin
        rd_en<=1;
    end
    else
        rd_en<=0;  
        
    always @(posedge clk or negedge rst_n)
    if(rst_n==0)
        xfer_start<=0;
    else
        xfer_start<=rd_en; 
    
    assign xfer_dout=dout;         
    
    uart_rx_wrapper uart_rx_wrapper_inst
(   
    .clk(clk),
    .rst_n(rst_n),
    
    .dout(dout),
    .rd_en(rd_en),
    
    .full(full),
    .almost_full(almost_full),
    .empty(empty),
    .almost_empty(almost_empty),
    .rx(rx)
); 

    uart_tx uart_tx_inst
    (
        .sys_clk(clk),
        .sys_rst_n(rst_n),
        .pi_data(xfer_dout),
        .pi_flag(xfer_start),
        .po_ack(xfer_end),
        .tx(tx)
    );   

endmodule

tb_syn_uart_rx_fifo_wrapper.v

module tb_syn_uart_rx_fifo_wrapper;
    reg clk, rst_n;
    initial clk=0;
    always #10 clk=~clk;
    
    initial begin
        rst_n=0;
        #1000;
        rst_n=1;
    end 

    reg [7:0] xfer_dout;
    reg xfer_start;
    initial begin
    xfer_dout=8'h00;
    xfer_start=0;
    
    wait(rst_n==1);
    #1000;
    
    @(posedge clk) begin
        #1 xfer_start=1;
        xfer_dout=8'h12;
    end

    @(posedge clk) begin
        #1 xfer_start=0;
    end 
    
    #2000;
     @(posedge clk) begin
        #1 xfer_start=1;
        xfer_dout=8'h34;
    end

    @(posedge clk) begin
        #1 xfer_start=0;
    end      
    
    
    
    end
    
    syn_uart_rx_fifo_wrapper2 syn_uart_rx_fifo_wrapper2_inst(
        .clk(clk),
        .rst_n(rst_n),
        .sw(1),
        .rx(rx)
    );
    defparam syn_uart_rx_fifo_wrapper2_inst.uart_rx_wrapper_inst.uart_rx_inst.UART_BPS= 'd9600;
    defparam syn_uart_rx_fifo_wrapper2_inst.uart_rx_wrapper_inst.uart_rx_inst.CLK_FREQ= 'd50_000;
    defparam syn_uart_rx_fifo_wrapper2_inst.CNT_MAX='d50_00;
    
    uart_tx uart_tx_inst
    (
        .sys_clk(clk),
        .sys_rst_n(rst_n),
        .pi_data(xfer_dout),
        .pi_flag(xfer_start),
        .po_ack(xfer_end),
        .tx(rx)
    );
    defparam uart_tx_inst.UART_BPS= 'd9600;
    defparam uart_tx_inst.CLK_FREQ= 'd50_000;          
    
endmodule

仿真波形

顶层tb uart_tx_master的行为

底层uart_rx+fifo写的行为

中层uart_tx+fifo的行为

z7nano+eda_v3引脚约束

create_clock -period 20.000 -name clk [get_ports clk]
set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports clk]
set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports rst_n]

set_property -dict {PACKAGE_PIN G15 IOSTANDARD LVCMOS33} [get_ports sw]
set_property -dict {PACKAGE_PIN A20 IOSTANDARD LVCMOS33} [get_ports full]
set_property -dict {PACKAGE_PIN C20 IOSTANDARD LVCMOS33} [get_ports empty]
set_property -dict {PACKAGE_PIN K16 IOSTANDARD LVCMOS33} [get_ports tx]
set_property -dict {PACKAGE_PIN J16 IOSTANDARD LVCMOS33} [get_ports rx]

上板运行结果