手写一个uart协议——rs232(未完)

先了解一下关于uart和rs232的基础知识

文章目录

本篇内容:

一、RS232的回环测试

上位机由串口助手通过 rx 线往 FPGA 发 8 比特数据,当 FPGA接收到 8 比特数据后,再通过 tx 线把接收到的 8 比特数据给上位机发回去,要求上位机接收到的数据和上位机发送的数据一样,并且保证连续发送也没问题。

1.1模块整体架构


1.2 rx模块设计

1.2.1 波形设计

1.2.2代码实现与tb

代码:

matlab 复制代码
module uart_rx(
    input wire clk,
    input wire rst,
    input wire rx,
    output reg [7:0]po_data,
    output reg po_flag
    );

parameter CNT_END=100;  //9600bps cnt=5207  sim时,cnt=100;
parameter CNT_END_HALF=CNT_END/2;

reg rx_t;
reg rx_tt;
reg rx_tt_reg;
reg [12:0] cnt;
reg cnt_flag;
reg bit_flag;
reg [3:0]bit_cnt;
// rx_t
always @(posedge clk) begin 
    if(rst==1'b1) begin
        rx_t <= 'd1;
    end 
    else begin
         rx_t<=rx ;
    end
end

// rx_tt
always @(posedge clk) begin 
    if(rst==1'b1) begin
        rx_tt <= 'd1;
    end 
    else begin
         rx_tt<=rx_t ;
    end
end

// rx_tt_reg
always @(posedge clk) begin 
    if(rst==1'b1) begin
        rx_tt_reg <= 'd1;
    end 
    else begin
         rx_tt_reg<=rx_tt ;
    end
end

//cnt
always @(posedge clk) begin 
    if(rst==1'b1) begin
         cnt<= 'd0;
    end 
    else if (cnt_flag==1'b1 && cnt==CNT_END) begin
        cnt<='d0;
    end
    else if (cnt_flag==1'b1) begin
        cnt<=cnt+1'b1;
    end
    else if (bit_cnt=='d8 && bit_flag==1'b1) begin
        cnt<='d0;
    end
end

//bit_flag
always @(posedge clk) begin 
    if(rst==1'b1) begin
        bit_flag <= 'd0;
    end 
    else if (cnt_flag==1'b1 && cnt==CNT_END_HALF) begin
        bit_flag<='d1;
    end
    else 
        bit_flag<='d0;
end

// cnt_flag
always @(posedge clk) begin 
    if(rst==1'b1) begin
        cnt_flag <= 'd0;
    end 
    else if (rx_tt==1'b0 && rx_tt_reg==1'b1) begin
        cnt_flag<='d1;
    end
    else if (bit_cnt=='d8 && cnt==CNT_END_HALF) begin
        cnt_flag<='d0;
    end
end

// bit_cnt
always @(posedge clk) begin 
    if(rst==1'b1) begin
       bit_cnt  <= 'd0;
    end 
    else if (bit_cnt=='d8 && bit_flag==1'b1) begin
        bit_cnt<='d0;
    end
    else if (bit_flag==1'b1) begin
        bit_cnt<=bit_cnt+1'b1;
    end
  
end

// po_data
always @(posedge clk) begin 
    if(rst==1'b1) begin
        po_data <= 'd0;
    end 
    else if (bit_cnt>0 && bit_flag==1'b1) begin
        po_data<={rx,po_data[7:1]};
    end
end

// po_flag
always @(posedge clk) begin 
    if(rst==1'b1) begin
         po_flag<= 'd0;
    end 
    else if (bit_cnt=='d8 && bit_flag==1'b1) begin
        po_flag<='d1;
    end
    else 
        po_flag<='d0;
end
endmodule

tb:

matlab 复制代码
`timescale 1ns / 1ps

module tb_rx();
	reg clk;
	reg rst;
	reg rx;
	wire [7:0] po_data;
	wire po_flag;

	initial begin
		clk=0;
		rst=1;
		#100
		rst=0;
	end

	initial begin
		rx=1;//空闲状态
		#100
		gen_rx();
		
	end


//这里模拟发送20帧数据,每次发送8个0~1的任意数,发送前rx拉低,表示起始位
//由于9600波特率需要计数5207次,为了仿真方便,假设只需要计数100次。
	task gen_rx;
		integer i;
		integer j;
		begin		
			for (j = 0; j < 20; j=j+1) begin
				rx=0;
				for ( i = 0; i < 8; i=i+1) begin  
					repeat(100) begin //每隔100周期发送1bit数据;
						@(posedge clk);  
					end
					rx={$random};
				end
				rx=1; //每发送完一帧数据后,rx恢复空闲状态,维持10个周期后继续发送数据,直到发够20帧数据。
			repeat(10) begin
				@(posedge clk);
			end		
			end
	    end
			
	endtask 

	always #5 clk=~clk;

		uart_rx inst_uart_rx (
			.clk     (clk),
			.rst     (rst),
			.rx      (rx),
			.po_data (po_data),
			.po_flag (po_flag)
		);

endmodule

1.2.4 仿真

1.3 tx模块设计

1.3.1波形设计

相关推荐
吉他英雄一里13 小时前
FPGA--RAM
fpga开发
szxinmai主板定制专家14 小时前
储能 EMS、微网控制器选型:RK3588、RK3576、RK3568+FPGA 怎么选?多网、多 CAN、EMC 设计权衡
人工智能·深度学习·机器学习·fpga开发·工业网关·rk3576·电力网关
XMAIPC_Robot15 小时前
ARM+FPGA+AI船舶/工业自动化控制器EMC测试等级解析(IEC60533/IEC60945)
arm开发·人工智能·fpga开发·zynq·arm+fpga·rk3588+fpga
ALINX技术博客16 小时前
ALINX 亮相 2026 工博会,聚焦 FPGA 行业应用场景
ai·fpga开发·射频工程
星夜离尘561 天前
FPGA 复位回归实验:双时钟停钟、释放中重入与消费端首拍自检
fpga开发
szxinmai主板定制专家1 天前
ZYNQ 数据采集方案踩坑总结:电力强电磁干扰、工业现场多协议适配优化
运维·人工智能·fpga开发·机器人·zynq
幻智星科技1 天前
一个开源的纯FPGA网口采集卡
网络协议·fpga开发·udp
bobuddy1 天前
硬件加速三件套:emulator-FPGA 原型-云仿真
fpga开发
szxinmai主板定制专家1 天前
软硬协同!ZYNQ 高速多通道同步采集,变电站 / 工厂设备状态监测方案详解
人工智能·深度学习·机器学习·fpga开发·zynq·rk3576
FPGA小徐1 天前
FPGA 8阶LFSR加扰/解扰器设计
fpga开发