基于verlog语言的UART通信协议模块实现

前言

在此我就不对UART协议细节部分做介绍,网上相关的介绍太多了。目前通过串口调试助手成功实现板载时钟50MHz情况下最大波特率3000000 bit/s通信。

模块组成

顶层:uart_modu
底层:uart_tx_modu、uart_rx_modu

模块接口

顶层

uart_modu #(
   .CLK_FRE  (50)	,	//模块时钟,单位MHz
   .BAUD_RATE(115200)	//通信波特率
)
your_instance_name(
	.clk		(clk		)		,	//input[0:0]模块时钟输入
	.rst		(rst		)		,	//input[0:0]模块复位输入,高电平有效

	.i_tx_begin	(i_tx_begin	)		,	//input[0:0]开始发送信号输入
	.i_tx_data	(i_tx_data	)		,	//input[7:0]待发送数据输入
	.o_tx_done	(o_tx_done	)		,	//output[0:0]发送完成标志输出
	.o_tx_busy	(o_tx_busy	)		,	//output[0:0]模块忙碌标志
	.o_tx_pin	(o_tx_pin	)		,	//output[0:0]发送引脚

	.o_rx_data	(o_rx_data	)		,	//output[7:0]接收数据输出
	.o_rx_vald	(o_rx_vald	)		,	//output[0:0]接收数据有效标志
	.o_rx_done	(o_rx_done	)		,	//output[0:0]接收完成标志
	.o_rx_busy	(o_rx_busy	)		,	//output[0:0]模块忙碌标志
	.i_rx_pin	(i_rx_pin	)			//input[0:0]接收引脚
    );

底层

uart_tx_modu #(
   .CLK_FRE  (50)	,	//模块时钟,单位MHz
   .BAUD_RATE(115200)	//通信波特率
)
your_instance_name(
	.clk		(clk		),	//input[0:0]模块时钟输入
	.rst		(rst		),	//input[0:0]模块复位输入,高电平有效
	.tx_begin	(tx_begin	),	//input[0:0]开始发送信号输入
	.tx_data	(tx_data	),	//input[7:0]待发送数据输入
	.tx_done	(tx_done	),	//output[0:0]发送完成标志输出
	.tx_busy	(tx_busy	),	//output[0:0]模块忙碌标志
	.tx_pin		(tx_pin		)	//output[0:0]发送引脚
    );
uart_rx_modu #(
   .CLK_FRE  (50)	,	//模块时钟,单位MHz
   .BAUD_RATE(115200)	//通信波特率
)
your_instance_name(
	.clk		(clk		),	//input[0:0]模块时钟输入
	.rst		(rst		),	//input[0:0]模块复位输入,高电平有效
	.rx_data	(rx_data	),	//output[7:0]接收数据输出
	.rx_vald	(rx_vald	),	//output[0:0]接收数据有效标志
	.rx_done	(rx_done	),	//output[0:0]接收完成标志
	.rx_busy	(rx_busy	),	//output[0:0]模块忙碌标志
	.rx_pin		(rx_pin		)	//input[0:0]接收引脚
);

时许仿真

tx_modu

测试代码

module tx_debug();

localparam	CUN = 10;

always #(CUN) clk = ~clk;

reg		[0:0]	clk		 = 1'b0;
reg		[0:0]	rst		 = 1'b0;
reg		[0:0]	tx_begin = 1'b0;	
reg		[7:0]	tx_data	 = 8'hA5;
wire	[0:0]	tx_done	;
wire	[0:0]	tx_busy	;
wire	[0:0]	tx_pin 	;

initial begin 
	#(CUN*4)	rst		 = 1'b1;
	#(CUN*2)	rst		 = 1'b0;

	#(CUN*4)	tx_begin = 1'b1;
	#(CUN*2)	tx_begin = 1'b0;

end

uart_tx_modu #(
   .CLK_FRE  (50)	,		//模块时钟,单位MHz
   .BAUD_RATE(115200)		//通信波特率
)
uart_tx_debug(
	.clk		(clk		)	,	//input[0:0]模块时钟输入
	.rst		(rst		)	,	//input[0:0]模块复位输入,高电平有效
	.tx_begin	(tx_begin	)	,	//input[0:0]开始发送信号输入
	.tx_data	(tx_data	)	,	//input[7:0]待发送数据输入
	.tx_done	(tx_done	)	,	//output[0:0]发送完成标志输出
	.tx_busy	(tx_busy	)	,	//output[0:0]模块忙碌标志
	.tx_pin		(tx_pin		)		//output[0:0]发送引脚
    );
endmodule

仿真截图

发送模块时许仿真

rx_modu

仿真源代码

module rx_debug();

localparam	CUN = 10;

always #(CUN) clk = ~clk;

reg		[0:0]	clk = 1'b0;		//模块时钟输入
reg		[0:0]	rst = 1'b0;		//模块复位输入,高电平有效
wire	[7:0]	rx_data;		//接收数据输出
wire	[0:0]	rx_vald;		//接收数据有效标志
wire	[0:0]	rx_done;		//接收完成标志
wire	[0:0]	rx_busy;		//模块忙碌标志
reg		[0:0]	rx_pin = 1'b1;	//接收引脚


initial begin 
	#(CUN*4)	rst		 = 1'b1;
	#(CUN*2)	rst		 = 1'b0;
	
	#(CUN*4)	rx_pin	 = 1'b0; //
	#8680		rx_pin	 = 1'b1; //1
	#8680		rx_pin	 = 1'b0; //2
	#8680		rx_pin	 = 1'b1; //3 
	#8680		rx_pin	 = 1'b0; //4 
	#8680		rx_pin	 = 1'b1; //5 
	#8680		rx_pin	 = 1'b0; //6 
	#8680		rx_pin	 = 1'b1; //7 
	#8680		rx_pin	 = 1'b0; //8 
	#8680		rx_pin	 = 1'b1; //
end

uart_rx_modu #(
   .CLK_FRE  (50)	,	//模块时钟,单位MHz
   .BAUD_RATE(3000000)	//通信波特率
)
uart_tx_debug(
	.clk		(clk		),	//input[0:0]模块时钟输入
	.rst		(rst		),	//input[0:0]模块复位输入,高电平有效
	.rx_data	(rx_data	),	//output[7:0]接收数据输出
	.rx_vald	(rx_vald	),	//output[0:0]接收数据有效标志
	.rx_done	(rx_done	),	//output[0:0]接收完成标志
	.rx_busy	(rx_busy	),	//output[0:0]模块忙碌标志
	.rx_pin		(rx_pin		)	//input[0:0]接收引脚
    );
endmodule

仿真截图

接收模块时许仿真

源码

顶层

/*===============================================
//----------- Begin Cut here for uart_modu Template ---//
uart_modu #(
   .CLK_FRE  (50)	,	//模块时钟,单位MHz
   .BAUD_RATE(115200)	//通信波特率
)
your_instance_name(
	.clk		(clk		)		,	//input[0:0]模块时钟输入
	.rst		(rst		)		,	//input[0:0]模块复位输入,高电平有效

	.i_tx_begin	(i_tx_begin	)		,	//input[0:0]开始发送信号输入
	.i_tx_data	(i_tx_data	)		,	//input[7:0]待发送数据输入
	.o_tx_done	(o_tx_done	)		,	//output[0:0]发送完成标志输出
	.o_tx_busy	(o_tx_busy	)		,	//output[0:0]模块忙碌标志
	.o_tx_pin	(o_tx_pin	)		,	//output[0:0]发送引脚

	.o_rx_data	(o_rx_data	)		,	//output[7:0]接收数据输出
	.o_rx_vald	(o_rx_vald	)		,	//output[0:0]接收数据有效标志
	.o_rx_done	(o_rx_done	)		,	//output[0:0]接收完成标志
	.o_rx_busy	(o_rx_busy	)		,	//output[0:0]模块忙碌标志
	.i_rx_pin	(i_rx_pin	)			//input[0:0]接收引脚
    );
// INST_TAG_END ------ End uart_modu Template ---------
===============================================*/

module uart_modu#(
	parameter	[7:0]	CLK_FRE   = 50,		//The clock frequency at which the module works, in MHz
	parameter	[23:0]	BAUD_RATE = 115200	//Communication baud rate
)(
	input	wire[0:0]	clk			,	//模块时钟,单位MHz
	input	wire[0:0]	rst			,	//通信波特率
	
	input	wire[0:0]	i_tx_begin	,	//input[0:0]开始发送信号输入
	input	wire[7:0]	i_tx_data	,	//input[7:0]待发送数据输入
	output	wire[0:0]	o_tx_done	,	//output[0:0]发送完成标志输出
	output	wire[0:0]	o_tx_busy	,	//output[0:0]模块忙碌标志
	output	wire[0:0]	o_tx_pin	,	//output[0:0]发送引脚

	output	wire[7:0]	o_rx_data	,	//output[7:0]接收数据输出
	output	wire[0:0]	o_rx_vald	,	//output[0:0]接收数据有效标志
	output	wire[0:0]	o_rx_done	,	//output[0:0]接收完成标志
	output	wire[0:0]	o_rx_busy	,	//output[0:0]模块忙碌标志
	input	wire[0:0]	i_rx_pin		//input[0:0]接收引脚
    );

	wire	[0:0]	clk_i	;
	wire	[0:0]	rst_i	;
	wire	[0:0]	tx_begin;	
	wire	[0:0]	tx_data	;
	wire	[0:0]	tx_done	;
	wire	[0:0]	tx_busy	;
	wire	[0:0]	tx_pin	;	
	wire	[0:0]	rx_data	;
	wire	[0:0]	rx_vald	;
	wire	[0:0]	rx_done	;
	wire	[0:0]	rx_busy	;
	wire	[0:0]	rx_pin	;	
	
	assign	clk_i		= clk		;
	assign	rst_i		= rst       ;
	assign	tx_begin	= i_tx_begin;	
	assign	tx_data		= i_tx_data	;
	assign	o_tx_done	= tx_done	;
	assign	o_tx_busy	= tx_busy	;
	assign	o_tx_pin	= tx_pin	;
	assign	o_rx_data	= rx_data	;
	assign	o_rx_done	= rx_done	;
	assign	o_rx_busy	= rx_busy	;
	assign	rx_pin		= i_rx_pin  ;

uart_tx_modu #(
   .CLK_FRE  	(CLK_FRE	),	//模块时钟,单位MHz
   .BAUD_RATE	(BAUD_RATE	)	//通信波特率
)
uart_tx_modu_u(
	.clk		(clk_i		),	//input[0:0]模块时钟输入
	.rst		(rst_i		),	//input[0:0]模块复位输入,高电平有效
	.tx_begin	(tx_begin	),	//input[0:0]开始发送信号输入
	.tx_data	(tx_data	),	//input[7:0]待发送数据输入
	.tx_done	(tx_done	),	//output[0:0]发送完成标志输出
	.tx_busy	(tx_busy	),	//output[0:0]模块忙碌标志
	.tx_pin		(tx_pin		)	//output[0:0]发送引脚
    );

uart_rx_modu #(
   .CLK_FRE  	(CLK_FRE	),	//模块时钟,单位MHz
   .BAUD_RATE	(BAUD_RATE	)	//通信波特率
)
uart_rx_modu_u(
	.clk		(clk		),	//input[0:0]模块时钟输入
	.rst		(rst		),	//input[0:0]模块复位输入,高电平有效
	.rx_data	(rx_data	),	//output[7:0]接收数据输出
	.rx_vald	(rx_vald	),	//output[0:0]接收数据有效标志
	.rx_done	(rx_done	),	//output[0:0]接收完成标志
	.rx_busy	(rx_busy	),	//output[0:0]模块忙碌标志
	.rx_pin		(rx_pin		)	//input[0:0]接收引脚
    );
endmodule

底层

rx_modu
/*===============================================
//----------- Begin Cut here for usrt_rx_modu Template ---//
uart_rx_modu #(
   .CLK_FRE  (50)	,	//模块时钟,单位MHz
   .BAUD_RATE(115200)	//通信波特率
)
your_instance_name(
	.clk		(clk		),	//input[0:0]模块时钟输入
	.rst		(rst		),	//input[0:0]模块复位输入,高电平有效
	.rx_data	(rx_data	),	//output[7:0]接收数据输出
	.rx_vald	(rx_vald	),	//output[0:0]接收数据有效标志
	.rx_done	(rx_done	),	//output[0:0]接收完成标志
	.rx_busy	(rx_busy	),	//output[0:0]模块忙碌标志
	.rx_pin		(rx_pin		)	//input[0:0]接收引脚
    );
// INST_TAG_END ------ End usrt_rx_modu Template ---------
===============================================*/

module uart_rx_modu #(
	parameter	[7:0]	CLK_FRE   = 50,		//The clock frequency at which the module works, in MHz
	parameter	[23:0]	BAUD_RATE = 115200	//Communication baud rate
)(
	input	wire[0:0]	clk				,	//input[0:0]模块时钟输入
	input	wire[0:0]	rst				,	//input[0:0]模块复位输入,高电平有效

	output	wire[7:0]	rx_data			,	//output[7:0]接收数据输出
	output	wire[0:0]	rx_vald			,	//output[0:0]接收数据有效标志
	output	wire[0:0]	rx_done			,	//output[0:0]接收完成标志
	output	wire[0:0]	rx_busy			,	//output[0:0]模块忙碌标志

	input	wire[0:0]	rx_pin				//input[0:0]接收引脚
);

/*===========计算当前时钟与波特率下bit持续时钟周期==========*/
	localparam	[15:0]	BIT_CYCLE1 = CLK_FRE * 1_000_000 / BAUD_RATE;
	localparam	[15:0]	BIT_CYCLE2 = CLK_FRE * 1_000_000 / BAUD_RATE/2;
/************************************************************/

/*=========================定义状态=========================*/
	localparam	[1:0]	S_IDLE		= 2'd0;		//空闲状态
	localparam	[1:0]	S_START		= 2'd1;     //接收开始信号
	localparam	[1:0]	S_SEND		= 2'd2;     //接收数据
	localparam	[1:0]	S_STOP		= 2'd3;     //接收结束信号
/************************************************************/

/*=========================定义寄存器=========================*/
	wire	[0:0]		start				;	//开始信号上升沿标志
	reg		[1:0]		start_r2	= 2'd3	;	//检测寄存器
	reg		[2:0]		now_state	= 3'd0	; 	//当前状态寄存器
	reg		[2:0]		nex_state	= 3'd0	; 	//下一状态寄存器
	reg		[31:0]		time_cnt	= 32'd0	;	//bit周期计时器
	reg		[2:0]		bit_cnt		= 3'd0	;	//bit计数器
	reg		[2:0]		rx_bit_reg	= 3'd0	;	//
	reg		[7:0]		rx_data_reg = 8'd0	;
/************************************************************/

/*=========================输出信号=========================*/
	assign	rx_busy = (now_state == S_IDLE) ? 1'b0 : 1'b1;
	assign	rx_done = (now_state == S_STOP && time_cnt == BIT_CYCLE2- 'd1) ? 1'b1 : 1'b0;
	assign	rx_data = (bit_cnt == 3'd7 && time_cnt >= BIT_CYCLE2 + 'd4) ? rx_data_reg : 8'd0;
	assign	rx_vald = (bit_cnt == 3'd7 && (time_cnt == BIT_CYCLE1 - 'd4 || time_cnt == BIT_CYCLE1 - 'd3)) ? 1'b1 : 1'b0;
/************************************************************/

/*=========================捕获开始信号=========================*/
	always@ (posedge clk)
		begin 
			if(now_state == S_IDLE)
				start_r2 <= {start_r2[0],rx_pin};
			else 
				start_r2 <= 2'd3;
		end 
	assign	start = start_r2[1] & ~start_r2[0];
/************************************************************/

/*======================bit周期计时器=======================*/
	always@ (posedge clk)
		begin
			if(now_state == S_IDLE)
				time_cnt <= 32'd0;
			else if(time_cnt == BIT_CYCLE1 - 1'b1 || (now_state == S_START && time_cnt == BIT_CYCLE1 - 'd2))
				time_cnt <= 32'd0;
			else
				time_cnt <= time_cnt + 1'b1;
		end 
/************************************************************/

/*========================bit计数器=========================*/
	always@ (posedge clk)
		begin 
			if(now_state != S_SEND)
				bit_cnt <= 3'd0;
			else if(time_cnt == BIT_CYCLE1 - 1'b1)
				bit_cnt <= bit_cnt + 1'b1;
		end 
/************************************************************/

/*=================接收单bit数据并均值滤波==================*/
	always@ (posedge clk)
		begin 
			if(now_state == S_IDLE)
				rx_bit_reg <= 3'd0;
			else if(now_state == S_SEND && time_cnt == BIT_CYCLE1 - 'd2)
				rx_bit_reg <= 3'd0;
			else if(now_state == S_SEND && (time_cnt == BIT_CYCLE2 - 'd4 || time_cnt == BIT_CYCLE2 - 'd3 || time_cnt == BIT_CYCLE2 - 'd2 || time_cnt == BIT_CYCLE2 - 'd1 || time_cnt == BIT_CYCLE2		  || time_cnt == BIT_CYCLE2 + 'd1 || time_cnt == BIT_CYCLE2 + 'd2))
				rx_bit_reg <= rx_bit_reg + rx_pin;
			else 
				rx_bit_reg <= rx_bit_reg;
		end
/************************************************************/

/*=====================寄存接收到的数据=====================*/
	always@ (posedge clk)
		begin 
			if(now_state == S_IDLE)
				rx_data_reg <= 8'd0;
			else if(now_state == S_SEND && time_cnt == BIT_CYCLE2 + 'd4)
				rx_data_reg[bit_cnt] <= rx_bit_reg[2];
			else 
				rx_data_reg <= rx_data_reg;
		end
/************************************************************/

/*=========================状态转换=========================*/
	always@ (posedge clk or posedge rst)
		begin 
			if(rst)
				now_state <= S_IDLE;
			else 
				now_state <= nex_state;
		end 
/************************************************************/

/*=========================下一状态=========================*/
	always@ (*)
		begin 
			case(now_state)
				S_IDLE	:
					begin 
						if(start)
							nex_state = S_START;
						else 
							nex_state = S_IDLE;
					end 
				S_START	:
					begin 
						if(time_cnt == BIT_CYCLE1 - 'd2)
							nex_state = S_SEND;
						else 
							nex_state = S_START;
					end 
				S_SEND	:
					begin 
						if(time_cnt == BIT_CYCLE1 - 1'b1 && bit_cnt == 3'd7)
							nex_state = S_STOP;
						else 
							nex_state = S_SEND;
					end 
				S_STOP	:
					begin 
						if(time_cnt == BIT_CYCLE2)
							nex_state = S_IDLE;
						else 
							nex_state = S_STOP;
					end 
				default	:nex_state = S_IDLE;
			endcase
		end
/************************************************************/
endmodule
tx_modu
/*===============================================
//----------- Begin Cut here for uart_tx_modu Template ---//
uart_tx_modu #(
   .CLK_FRE  (50)	,	//模块时钟,单位MHz
   .BAUD_RATE(115200)	//通信波特率
)
your_instance_name(
	.clk		(clk		),	//input[0:0]模块时钟输入
	.rst		(rst		),	//input[0:0]模块复位输入,高电平有效
	.tx_begin	(tx_begin	),	//input[0:0]开始发送信号输入
	.tx_data	(tx_data	),	//input[7:0]待发送数据输入
	.tx_done	(tx_done	),	//output[0:0]发送完成标志输出
	.tx_busy	(tx_busy	),	//output[0:0]模块忙碌标志
	.tx_pin		(tx_pin		)	//output[0:0]发送引脚
    );
// INST_TAG_END ------ End uart_tx_modu Template ---------
===============================================*/

module uart_tx_modu#(
	parameter	[7:0]	CLK_FRE   = 50,		//The clock frequency at which the module works, in MHz
	parameter	[23:0]	BAUD_RATE = 115200	//Communication baud rate
)(
	input	wire[0:0]	clk				,	//input[0:0]模块时钟输入
	input	wire[0:0]	rst				,	//input[0:0]模块复位输入,高电平有效

	input	wire[0:0]	tx_begin		,	//input[0:0]开始发送信号输入
	input	wire[7:0]	tx_data			,	//input[7:0]待发送数据输入
	output	wire[0:0]	tx_done			,	//output[0:0]发送完成标志输出
	output	wire[0:0]	tx_busy			,	//output[0:0]模块忙碌标志

	output	wire[0:0]	tx_pin				//output[0:0]发送引脚
);

/*===========计算当前时钟与波特率下bit持续时钟周期==========*/
	localparam	[15:0]	BIT_CYCLE = CLK_FRE * 1_000_000 / BAUD_RATE;
/************************************************************/

/*=========================定义状态=========================*/
	localparam	[1:0]	S_IDLE		= 2'd0;		//空闲状态
	localparam	[1:0]	S_START		= 2'd1;     //发送开始信号
	localparam	[1:0]	S_SEND		= 2'd2;     //发送数据
	localparam	[1:0]	S_STOP		= 2'd3;     //发送结束信号
/************************************************************/

/*========================定义寄存器========================*/
	reg		[1:0]		start_r2	= 2'd0	;	//开始信号缓存器
	wire	[0:0]		start				;	//开始信号上升沿标志
	reg		[2:0]		now_state	= 3'd0	; 	//当前状态寄存器
	reg		[2:0]		nex_state	= 3'd0	; 	//下一状态寄存器
	reg		[31:0]		time_cnt	= 32'd0	;	//bit周期计时器
	reg		[2:0]		bit_cnt		= 3'd0	;	//bit计数器
	reg		[7:0]		tx_data_reg = 8'd0	;	//待发送数据寄存器
	reg		[0:0]		tx_reg		= 1'd1	;	//待发送bit寄存器
/************************************************************/

/*===================-=====输出端口=========================*/
	assign	tx_done = (now_state == S_STOP && time_cnt == BIT_CYCLE-1) ? 1'b1 : 1'b0;
	assign	tx_busy = (now_state == S_IDLE) ? 1'b0 : 1'b1;
	assign	tx_pin  = (now_state == S_IDLE) ? 1'b1 : tx_reg;
/************************************************************/

/*====================产生开始信号上升沿====================*/
	always@ (posedge clk)
		begin 
			if(now_state == S_IDLE)
				start_r2 <= {start_r2[0],tx_begin};
			else
				start_r2 <= 2'd0;
		end 
	assign	start = ~start_r2[1] & start_r2[0];
/************************************************************/

/*======================bit周期计时器=======================*/
	always@ (posedge clk)
		begin
			if(now_state == S_IDLE)
				time_cnt <= 32'd0;
			else if(time_cnt == BIT_CYCLE - 1'b1)
				time_cnt <= 32'd0;
			else
				time_cnt <= time_cnt + 1'b1;
		end 
/************************************************************/

/*========================bit计数器=========================*/
	always@ (posedge clk)
		begin 
			if(now_state != S_SEND)
				bit_cnt <= 3'd0;
			else if(time_cnt == BIT_CYCLE - 1'b1)
				bit_cnt <= bit_cnt + 1'b1;
		end 
/************************************************************/

/*======================寄存待发送数据======================*/
	always@ (posedge clk)
		begin 
			if(now_state == S_IDLE && nex_state == S_IDLE)
				tx_data_reg <= 8'd0;
			else if(now_state == S_IDLE && nex_state != S_IDLE)
				tx_data_reg <= tx_data;
			else 
				tx_data_reg <= tx_data_reg;
		end 
/************************************************************/

/*=========================产生输出=========================*/
	always@ (posedge clk)
		begin 
			if(now_state == S_IDLE)
				tx_reg <= 1'b1;
			else if(now_state == S_START)
				tx_reg <= 1'b0;
			else if(now_state == S_SEND)
				tx_reg <= tx_data_reg[bit_cnt];
			else if(now_state == S_STOP)
				tx_reg <= 1'b1;
		end 
/************************************************************/

/*=========================状态切换=========================*/
	always@ (posedge clk or posedge rst)
		begin 
			if(rst)
				now_state <= S_IDLE;
			else 
				now_state <= nex_state;
		end 
/************************************************************/

/*=======================产生下一状态=======================*/
	always@ (*)
		begin 
			case(now_state)
				S_IDLE	:
					begin 
						if(start)
							nex_state = S_START;
						else 
							nex_state = S_IDLE;
					end
				S_START	:
					begin 
						if(time_cnt == BIT_CYCLE - 1'b1)
							nex_state = S_SEND;
						else 
							nex_state = S_START;
					end
				S_SEND	:
					begin 
						if(time_cnt == BIT_CYCLE - 1'b1 && bit_cnt == 3'd7)
							nex_state = S_STOP;
						else 
							nex_state = S_SEND;
					end
				S_STOP	:
					begin 
						if(time_cnt == BIT_CYCLE - 1'b1)
							nex_state = S_IDLE;
						else 
							nex_state = S_STOP;
					end
				default	:begin nex_state = S_IDLE; end
			endcase
		end
/************************************************************/
endmodule

结束语

本人刚刚入坑FPGA 不久,在代码风格,设计逻辑上还有很多不足之处。欢迎各位大佬指出我的不住之处。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值