计算机组成原理实验报告2

1. 实验内容

  • 学习UART解析模块代码逻辑
  • 根据实验手册中提供的波形图,自行完成回环功能,并使用串口调试助手完成回环功能的测试

2. 实验要求

  • 给出完整的回环程序代码
  • 验收串口调试助手的回环显示
  • 提交完整的实验报告

3. 实验过程

1. 添加样例代码

2. 添加 IP 核


3. 开始编写代码

根据UART的逻辑,编写了以下回环代码:

module uart_top#(
    parameter                          baudrate = 115200
)(
    input  wire                        CLK,
    input  wire                        RSTN,

    input  wire                        rx_i,     // Receiver input
    output wire                        tx_o      // Transmitter output

);

    localparam  baud_div = 434 ;

    // receive buffer register, read only
   (*mark_debug="true"*)wire [7:0]  rx_data;
    (*mark_debug="true"*)wire [7:0]  tx_data;
    // parity error
    wire        parity_error;
    wire [3:0]  IIR_o;
    reg  [3:0]  clr_int;
    // tx flow control
    (*mark_debug="true"*)wire        tx_ready;
    // rx flow control

    (*mark_debug="true"*)wire        rx_valid;

    reg         fifo_tx_valid;
   (*mark_debug="true"*)reg         tx_valid;
    wire        fifo_rx_valid;
    reg         fifo_rx_ready;
   (*mark_debug="true"*) wire        rx_ready;

   (*mark_debug="true"*) wire        fifo_wren;
  (*mark_debug="true"*) wire        fifo_rden;
    (*mark_debug="true"*)wire        fifo_full;
    (*mark_debug="true"*)wire        fifo_empty;

    uart_rx u_uart_rx(
        .clk_i            ( CLK                                                      ),
        .rstn_i           ( RSTN                                                     ),
        .rx_i             ( rx_i                                                     ),
        .cfg_en_i         ( 1'b1 ),     // 涓插彛妯″潡浣胯兘
        .cfg_div_i        ( 16'd0431 ), // 姣忎竴浣嶆暟鎹帴鏀堕渶瑕佺殑鍛ㄦ湡鏁?
        .cfg_parity_en_i  ( 1'b0 ),     // 濂囧伓鏍¢獙浣胯兘
        .cfg_parity_sel_i ( 2'b00 ),    // 濂囧伓鏍¢獙绫诲瀷浣胯兘
        .cfg_bits_i       ( 2'b11 ),    // 鏁版嵁浣嶉?夋嫨锛?2'b00 -> 5bit, 2'b01 -> 6bit, 2'b10 -> 7bit, 2'b11 -> 8bit
        // .cfg_stop_bits_i    ( regs_q[(LCR * 8) + 2]                               ),
        .busy_o           (                                                          ),
        .err_o            ( parity_error                                             ),
        .err_clr_i        ( 1'b0                                                     ),
        .rx_data_o        ( rx_data                                                  ),
        .rx_valid_o       ( rx_valid                                                 ),
        .rx_ready_i       ( rx_ready                                                 )
    );

    uart_tx u_uart_tx(
        .clk_i            ( CLK                                                      ),
        .rstn_i           ( RSTN                                                     ),
        .tx_o             ( tx_o                                                     ),
        .busy_o           (                                                          ),
        .cfg_en_i         ( 1'b1 ),     // 涓插彛妯″潡浣胯兘
        .cfg_div_i        ( 16'd0431 ), // 姣忎竴浣嶆暟鎹帴鏀堕渶瑕佺殑鍛ㄦ湡鏁?
        .cfg_parity_en_i  ( 1'b0 ),     // 濂囧伓鏍¢獙浣胯兘
        .cfg_parity_sel_i ( 2'b00 ),    // 濂囧伓鏍¢獙绫诲瀷浣胯兘
        .cfg_bits_i       ( 2'b11 ),    // 鏁版嵁浣嶉?夋嫨锛?2'b00 -> 5bit, 2'b01 -> 6bit, 2'b10 -> 7bit, 2'b11 -> 8bit
        .cfg_stop_bits_i  ( 1'b1 ),     // 鏄惁鏈夊仠姝綅
        .tx_data_i        ( tx_data                                                  ),
        .tx_valid_i       ( tx_valid                                                 ),
        .tx_ready_o       ( tx_ready                                                 )
    );

    // loop

    fifo_8b u_fifo_8b (
        .clk(CLK),      // input wire clk
        .srst(~RSTN),    // input wire srst
        .din(rx_data),      // input wire [7 : 0] din
        .wr_en(fifo_wren),  // input wire wr_en
        .rd_en(fifo_rden),  // input wire rd_en
        .dout(tx_data),    // output wire [7 : 0] dout
        .full(fifo_full),    // output wire full
        .empty(fifo_empty)  // output wire empty
    );
    // your code here
      assign fifo_wren = (rx_valid &&!fifo_full); 
    assign fifo_rden = (!fifo_empty && tx_ready); 
   assign rx_ready=(!fifo_full);
 always @(posedge CLK or negedge RSTN) begin
    if (!RSTN) begin
        tx_valid <= 1'b0;  // 在复位时应清零 tx_valid
    end else begin
        if (!fifo_empty && fifo_rden) begin
            tx_valid <= 1'b1;
        end else begin
            tx_valid <= 1'b0;
        end
    end
end
    // your code end

endmodule

为了验证UART回环功能的实现,编写了测试模块 uart_loop_tb。该模块用于生成时钟信号,初始化UART模块,并模拟数据传输过程。

module uart_loop_tb;

    // Internal signals
    parameter clk_freq = 10;

    reg             clk;
    reg             rst_n;

    reg             tx_release;

    reg     [7:0]   rx_data;
    reg             rx_valid;
    wire            rx_ready;
    wire    [7:0]   tx_data;
    reg             tx_valid;
    reg             tx_ready;

    wire            fifo_wren;
    wire            fifo_rden;
    wire            fifo_full;
    wire            fifo_empty;

    // Clock process to generate clock signals
    always begin
        # (clk_freq / 2) clk = ~clk;
    end

    // Reset signals
    initial begin
        clk = 1'b1;
        rst_n = 1'b0;
        #50 rst_n = 1'b1;
    end

    // DUT instantiation
    fifo_8b u_fifo_8b (
        .clk(clk),      // input wire clk
        .srst(~rst_n),    // input wire srst
        .din(rx_data),      // input wire [7 : 0] din
        .wr_en(fifo_wren),  // input wire wr_en
        .rd_en(fifo_rden),  // input wire rd_en
        .dout(tx_data),    // output wire [7 : 0] dout
        .full(fifo_full),    // output wire full
        .empty(fifo_empty)  // output wire empty
    );

    // simulation code
    initial begin
        rx_data = 8'h25;
        rx_valid = 1'b0;
        tx_ready = 1'b1;
        tx_release = 1'b0;
        // oper after rst release
        #80 tx_release = 1'b0;
        // your code here
         rx_valid=1'b1;
        #10;
         rx_valid=1'b0;

        // your code end

        // this signal used for release tx_ready
        #80 tx_release = 1'b1;
        #10 tx_release = 1'b0;
    end 

    always @(posedge clk) begin
        if(tx_valid)
            tx_ready <= 1'b0;
        else if (tx_release)
            tx_ready <= 1'b1;
    end

    // loop code here
      assign fifo_wren = (rx_valid &&!fifo_full); 
    assign fifo_rden = (!fifo_empty && tx_ready); 
   assign rx_ready=(!fifo_full);
 always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        tx_valid <= 1'b0;  // 在复位时应清零 tx_valid
    end else begin
        if (!fifo_empty && fifo_rden) begin
            tx_valid <= 1'b1;
        end else begin
            tx_valid <= 1'b0;
        end
    end
end
    // loop code end

endmodule

4. 结果分析

利用Vivado得到仿真波形如图:

通过使用串口调试助手进行测试,验证了UART回环功能。测试时输入的每个字节都能够通过UART正确回传,显示在调试助手的接收窗口中,验证了代码逻辑的正确性,结果如图:

5. 总结

本次实验通过学习和实现UART的回环功能,加深了对串口通信的理解。通过实验,我们掌握了如何使用FIFO缓冲区处理接收到的数据以及如何通过UART模块进行数据的发送和接收。同时,测试结果表明我们实现的回环功能符合预期,为今后更复杂的串口通信打下了基础。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇