串口接收端verilog代碼分析
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: chensimin // // Create Date: 2018/05/23 16:14:30 // Design Name: // Module Name: uart_rx // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module uart_rx( input wire clk, input wire rxd, output reg [7:0]data_i, output wire receive_ack ); reg [7:0] data_i = 0; localparam IDLE = 0, RECEIVE = 1, RECEIVE_END = 2; reg [3:0]cur_st = 0; reg [3:0]nxt_st = 0; always @(posedge clk) begin cur_st <= nxt_st; end always @(*) begin nxt_st = cur_st; case(cur_st) IDLE: begin if(!rxd) //當從接收端口上進來的數據開始為0時,即啟動接收 nxt_st = RECEIVE; end RECEIVE: begin if(count == 7) nxt_st = RECEIVE_END; end RECEIVE_END: begin nxt_st = IDLE; end default: begin nxt_st = IDLE; end endcase end reg [4:0]count = 0; always @(posedge clk) begin if(cur_st == RECEIVE) count <= count + 1; else if(cur_st == IDLE || cur_st == RECEIVE_END) count <= 0; end //當前狀態為接收狀態時,rxd 信號線上的數據存儲在data_i的最高位 //同時data_i 的數據總體右移一位 always @(posedge clk) begin if(cur_st == RECEIVE) begin data_i[6:0] <= data_i[7:1]; data_i[7] <= rxd; // rxd 傳過來什么數據, data_i上立馬顯示什么數據,因為是從端口采集到的數據 end end assign receive_ack = (cur_st == RECEIVE_END) ? 1: 0; endmodule /* add_force {/uart_rx/clk} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps add_force {/uart_rx/rxd} -radix hex {1 0ns} {0 300ns} {1 400ns} {0 500ns} {1 600ns} {0 700ns} {1 800ns} {0 900ns} {1 1000ns} */
仿真結果:
注意:
分析寄存器的更新一定要結合時鍾沿,然后寄存器在時鍾沿前后的變化狀態。