串口接收端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} */
仿真结果:
注意:
分析寄存器的更新一定要结合时钟沿,然后寄存器在时钟沿前后的变化状态。