手写一个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波形设计

相关推荐
ZYNQRFSOC4 小时前
基于安路PH2A系列FPGA的JESD204B接口测试
嵌入式硬件·fpga开发
szxinmai主板定制专家6 小时前
基于RK3588超小体积,轻巧,长续航的无人机AI模块,支持视频跟踪
arm开发·人工智能·嵌入式硬件·fpga开发·无人机
unicrom_深圳市由你创科技20 小时前
多 FPGA 之间如何同步与通信?
fpga开发
LCMICRO-133108477461 天前
长芯微LCMDC7616完全P2P替代AD7616,16通道16位模数转换器(ADC)
stm32·嵌入式硬件·fpga开发·硬件工程·模数转换器adc·电力线监测
又菜又爱玩的东哥1 天前
【Verilog 3-8译码器设计与仿真:深入理解case语句与组合逻辑】
fpga开发
Risehuxyc1 天前
<= 是Verilog中的非阻塞赋值操作符
fpga开发
扣脑壳的FPGAer1 天前
傅里叶级数、傅里叶变换、Z变换、数字滤波器
fpga开发·信号处理
Risehuxyc1 天前
HDL中assigned 与 always 有什么区别?
fpga开发
我爱C编程1 天前
【3.5】固定旋转因子系数乘法模块的FPGA实现1——45°旋转因子和高阶蝶形修正因子
fpga开发·固定旋转因子·旋转因子
Terasic友晶科技2 天前
答疑解惑 | DE25-Nano开发板串口在访问FPGA端外设LED时卡死,无任何反应
fpga开发·串口·led·de25-nano