FPGA UART仿真

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-21 17:19   32   0

摘自威三学员尤凯元

tb文件

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2019 All rights reserved
// -----------------------------------------------------------------------------
// Author : Youkaiyuan  v3eduyky@126.com
// wechat : 15921999232
// File   : tb_top_uart.v
// Create : 2019-03-28 12:01:49
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
`timescale 1ns / 1ps
module tb_top_uart;

 // Inputs
 reg sclk;
 reg rst_n;
 reg rx;

 reg [7:0] mem[15:0];

 // Outputs
 wire tx;

 // Instantiate the Unit Under Test (UUT)
 top_uart uut (
  .sclk(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

 initial begin
  $readmemh("./data.txt",mem);
 end

 always #10 sclk = ~sclk;

 initial begin
  #200;
  rx_byte();
 end

 task rx_byte();
  integer i;
  begin
   for (i=0;i<16;i=i+1)begin
    rx_bit(mem[i]);
   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;
      end
     end
    endtask  
endmodule

data.txt

0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f

top_uart.v

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2019 All rights reserved
// -----------------------------------------------------------------------------
// Author : Youkaiyuan  v3eduyky@126.com
// wechat : 15921999232
// File   : top_uart.v
// Create : 2019-03-28 11:53:38
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
module top_uart(
 input wire    sclk,
 input wire    rst_n,
 input wire    rx,
 output wire    tx
 );
wire   flag;
wire [7:0] data;

 uart_rx  inst_uart_rx (
   .sclk    (sclk),
   .rst_n   (rst_n),
   .rx      (rx),
   .po_data (data),
   .po_flag (flag)
  );
 uart_tx inst_uart_tx (
   .sclk    (sclk),
   .rst_n   (rst_n),
   .pi_flag (flag),
   .pi_data (data),
   .tx      (tx)
  );

endmodule 

uart_rx.v

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2019 All rights reserved
// -----------------------------------------------------------------------------
// Author : Youkaiyuan  v3eduyky@126.com
// wechat : 15921999232
// File   : uart_rx.v
// Create : 2019-03-28 10:32:23
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
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;
parameter CNT_HALF_BAUD_MAX = 2603;
reg    rx1,rx2,rx2_reg;
reg    rx_flag;
reg  [12:0] cnt_baud;
reg    bit_flag;
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 

uart_tx.v

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2019 All rights reserved
// -----------------------------------------------------------------------------
// Author : Youkaiyuan  v3eduyky@126.com
// wechat : 15921999232
// File   : uart_tx.v
// Create : 2019-03-28 11:34:39
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
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;
reg  [7:0] data_reg;
reg    tx_flag;
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
  data_reg <='d0;
 end
 else if (pi_flag == 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 

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP