【Verilog】串行接收器设计(Serial Receiver),HDLbits题目

这是博主在刷HDLbits卡住很久的一道题,在这里记录下来,自己总结下思路,同时也希望能给大家提供参考。

一、设计要求

在许多串行通信协议中,每个数据字节都与一个起始位和一个停止位一起发送,以帮助接收器从位流中划定字节。一种常见的方案是使用 1 个起始位 (0)、8 个数据位和 1 个停止位 (1)。当没有传输任何内容(空闲)时,该线路也处于逻辑 1。
要求: 设计一个有限状态机,当给定比特流时,它将识别何时正确接收到字节。它需要识别起始位,等待所有 8 个数据位,然后验证停止位是否正确。如果停止位未按预期出现,则 FSM 必须等到找到停止位后再尝试接收下一个字节。

我们要实现的时序图如下。

在这里插入图片描述

二、思路分析

这道题是用状态机来实现,所以重要的是如何设计状态的状态和状态的转换。这里,博主并没有使用题目中时序图给的状态。经过对题目的分析:

  • 传输不出错的时候:也就是起始位为0,结束位为1。这个时候传输结束了有两种状态,连续传输和暂停一下继续传输。
  • 传输出错的时候:也就是停止位不为1。这个时候需要等待in变到高位,进入空闲状态,然后才能进行新的数据的传输。

我设计了状态转移框图如下:
在这里插入图片描述

  • IDLE:空闲状态,只要in为0,就开始进行传输。当复位、完成一个字节数据传输需要等待、未完成传输需要等待下一个数据传输的时候,进入该状态。
  • TRANS:进行数据传输。需要一个计数器来计算已经传输的位数,当传输8位后要判定结束位。结束位有效就完成传输,否则丢弃该数据,进入WAIT状态。
  • DONE:完成一个数据的传输,可以继续传输,或者等待。
  • WAIT:当传输的数据无效的时候,需要丢掉该数据,并进入WAIT状态。当in=1时,进入IDLE状态,准备进行下一个数据的传输。

三、代码实现

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 

	parameter IDLE = 2'd00, TRANS = 2'd01,DONE = 2'd10,WAIT = 2'd11;
	reg [1:0] state,next_state;
	reg [5:0] counter;
	//计数器
	always @(posedge clk) begin
		if (reset) begin
			counter <= 6'd0;	
		end
		else  begin
			if (state == TRANS)begin 
				counter <= counter + 1'd1;
			end
			else begin
				counter <= 6'd0;
			end
		end
	end
	//状态转移逻辑
	always @(*) begin
		case(state)
			IDLE:next_state <= in ? IDLE:TRANS;
			TRANS: begin
				if (counter == 6'd8) begin
					if (in == 1'd1) begin
						next_state <= DONE;
					end
					else begin
						next_state <= WAIT;
					end
				end
				else begin
					next_state <= TRANS;
				end
			end
			WAIT: next_state <= in ? IDLE : WAIT;	
			DONE: next_state <= in ? IDLE : TRANS;
		endcase
	end
	
	always @(posedge clk ) begin
		if (reset) begin
			state <= IDLE;
			
		end
		else begin
			state <= next_state;
		end
	end
	//输出
	assign done = (state == DONE) ;

endmodule

四、仿真波形

在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于 Verilog 串口接收模块的设计,我可以为您提供一些基本的思路和实现方法。 首先,串口接收模块的基本功能是从串口接收缓冲区中读取数据并将其保存到内部缓存中。其次,为了保证数据的正确性,需要对接收到的数据进行校验,如奇偶校验和校验。最后,需要向主模块发送一个信号表示数据已经接收完成。 针对这些要求,下面是一个简单的串口接收模块的 Verilog 代码: ```verilog module uart_rx( input clk, input rst, input rx, output reg [7:0] data, output reg done ); reg [7:0] buffer; reg [2:0] state; parameter IDLE = 3'd0; parameter START = 3'd1; parameter DATA = 3'd2; parameter PARITY = 3'd3; parameter STOP = 3'd4; always @(posedge clk) begin if (rst) begin state <= IDLE; buffer <= 0; data <= 0; done <= 0; end else begin case (state) IDLE: begin if (!rx) begin state <= START; end end START: begin state <= DATA; end DATA: begin buffer <= {buffer[6:0], rx}; state <= PARITY; end PARITY: begin state <= STOP; end STOP: begin if (rx) begin state <= IDLE; data <= buffer; done <= 1; end end endcase end end endmodule ``` 上述代码中,首先定义了一些常量,如空闲状态、开始状态、数据状态、奇偶校验状态和停止状态。接着使用有限状态机的方式来实现串口接收功能。在时钟上升沿时,根据当前状态机的状态,执行相应的操作。具体来说: - 在空闲状态下,如果检测到串口接收到数据,就进入开始状态。 - 在开始状态下,等待一个完整的字符传输的开始位,然后进入数据状态。 - 在数据状态下,连续接收 8 位数据,并将其保存到 buffer 中。 - 在奇偶校验状态下,如果需要进行奇偶校验,则进行校验,否则直接进入停止状态。 - 在停止状态下,等待一个完整的字符传输的停止位,然后将接收到的数据保存到 data 中,并设置 done 信号表示接收完成。 以上就是一个基本的 Verilog 串口接收模块的设计。需要注意的是,该代码只是一个基本的实现,实际应用中需要根据具体的需求进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值