FPGA-직렬 통신 수신 모듈(송신 수신 모듈)

10973 단어 FPGA 칼럼
수신 모듈은 전송 모듈과 유사합니다.
수신하는 과정에서 수신 데이터의 정확성을 확보하기 위해 단일 시계의 보트율을 주파수로 나눈다. 단일 시계 신호에서 16번 주파수를 나눈다. 데이터 수집을 통해 데이터의 정확성을 확보했다. 이곳의 코드 사상은 소메고의 코드 작성 사상을 참고했다.
수신 모듈의 유효성 검사를 전송하려면 다음과 같이 하십시오.
여기에 발송된 검증은 PC단을 통해 발송되고 개발판에서 먼저 데이터를 받은 다음에 발송된다. 만약에 문자열이나 특수한 지령을 검증하면 상태기나 유사한 상태기의 사상으로 설계한다.
여기에 퀘스트가 요구하는 수신 모듈의 검증 기본 퀘스트와 코드만 붙입니다
작업 요구사항:
PC 포트에서 명령을 전송하여 단일 문자와 문자열을 감지합니다
I Like FPGA led 전체가 켜져 있는 경우, 잘못된 led가 깜박일 경우 단일 문자를 보낼 때 LED 램프를 사용하여 해당 문자의 ASCII 코드를 표시합니다.
직렬 수신 모듈:
module uart_rxd(clk,rst_n,bps_set,rxd,data_byte,rxd_finish,uart_state
    );
	input           clk       ;//    
	input           rst_n     ;//    
	input     [1:0] bps_set   ;//     
	input           rxd       ;//    
	output    [7:0] data_byte ;//    
	output          rxd_finish;//      
	output          uart_state;//      
	reg       [7:0] data_byte ;
	reg             rxd_finish;
	reg             uart_state;
	parameter       BPS_4800    =16'd324,
                    BPS_9600    =16'd162,
					BPS_19200   =16'd80 ,
                    BPS_115200  =16'd13 ;
	
	//     
	reg rxd_s0,rxd_s1;  //     
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			rxd_s0<=1'b0;
			rxd_s1<=1'b0;
		end
		else begin
			rxd_s0<=rxd;
			rxd_s1<=rxd_s0;
		end
	end
	reg rxd_temp0,rxd_temp1;//     
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			rxd_temp0<=1'b0;
			rxd_temp1<=1'b0;
		end
		else begin
			rxd_temp0<=rxd_s1;
			rxd_temp1<=rxd_temp0;
		end
	end
	
	wire rxd_negedge =~rxd_temp0&rxd_temp1;
	
	reg [15:0] div_cnt;
	reg [15:0] time_div;
	//       
	always@(*)begin
		if(rst_n==1'b0)begin
			time_div=BPS_9600;
		end
		else begin
			case(bps_set)
				2'b00: time_div = BPS_4800;
				2'b01: time_div = BPS_9600;
				2'b10: time_div = BPS_19200;
				2'b11: time_div = BPS_115200;
				default:time_div = BPS_9600;
			endcase
		end
	end
	//       
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			div_cnt<=1'b0;
		end
		else if(uart_state==1'b1)begin
			if(div_cnt==time_div)begin
				div_cnt<=1'b0;
			end
			else begin
				div_cnt<=div_cnt+1'b1;
			end
		end
		else begin
			div_cnt<=1'b0;
		end
	end
	//       
	reg bps_clk;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			bps_clk<=1'b0;
		end
		else if(div_cnt==time_div)begin
			bps_clk<=1'b1;
		end
		else begin
			bps_clk<=1'b0;
		end
	end
	//bps    
	reg [7:0] bps_cnt;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			bps_cnt<=8'd0;
		end
		else if(rxd_finish==1'b1||(bps_cnt==8'd12 && (Start>3'd3)))begin
			bps_cnt<=8'd0;
		end
		else if(bps_clk==1'b1)begin
			bps_cnt<=bps_cnt+1'b1;
		end
		else begin
			bps_cnt<=bps_cnt;
		end
	end
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			rxd_finish=1'b0;
		end
		else if(bps_cnt==8'd159)begin
			rxd_finish=1'b1;
		end
		else begin
			rxd_finish=1'b0;
		end
	end
	
	//       
	reg [2:0] r_data_byte[7:0];
	reg [2:0]Start,Stop;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			Start<=3'd0;
			r_data_byte[0]<=3'd0;
			r_data_byte[1]<=3'd0;
			r_data_byte[2]<=3'd0;
			r_data_byte[3]<=3'd0;
			r_data_byte[4]<=3'd0;
			r_data_byte[5]<=3'd0;
			r_data_byte[6]<=3'd0;
			r_data_byte[7]<=3'd0;
			Stop<=3'd0;
		end
		else if(bps_clk==1'b1)begin
			if(bps_cnt==1'b0)begin
				Start<=3'd0;
				r_data_byte[0]<=3'd0;
				r_data_byte[1]<=3'd0;
				r_data_byte[2]<=3'd0;
				r_data_byte[3]<=3'd0;
				r_data_byte[4]<=3'd0;
				r_data_byte[5]<=3'd0;
				r_data_byte[6]<=3'd0;
				r_data_byte[7]<=3'd0;
				Stop<=3'd0;
			end
			if(16'd6<=bps_cnt&&bps_cnt<=16'd12)begin
				Start<=Start+rxd_s1;
			end
			else if(16'd22<=bps_cnt&&bps_cnt<=16'd28)begin
				r_data_byte[0]<=r_data_byte[0]+rxd_s1;
			end
			else if(16'd38<=bps_cnt&&bps_cnt<=16'd44)begin
				r_data_byte[1]<=r_data_byte[1]+rxd_s1;
			end
			else if(16'd54<=bps_cnt&&bps_cnt<=16'd60)begin
				r_data_byte[2]<=r_data_byte[2]+rxd_s1;
			end
			else if(16'd70<=bps_cnt&&bps_cnt<=16'd76)begin
				r_data_byte[3]<=r_data_byte[3]+rxd_s1;
			end
			else if(16'd86<=bps_cnt&&bps_cnt<=16'd92)begin
				r_data_byte[4]<=r_data_byte[4]+rxd_s1;
			end
			else if(16'd102<=bps_cnt&&bps_cnt<=16'd108)begin
				r_data_byte[5]<=r_data_byte[5]+rxd_s1;
			end
			else if(16'd118<=bps_cnt&&bps_cnt<=16'd124)begin
				r_data_byte[6]<=r_data_byte[6]+rxd_s1;
			end
			else if(16'd134<=bps_cnt&&bps_cnt<=16'd140)begin
				r_data_byte[7]<=r_data_byte[7]+rxd_s1;
			end
			else if(16'd150<=bps_cnt&&bps_cnt<=16'd156)begin
				Stop<=Stop+rxd_s1;
			end
		end
		else;
	end
	
		always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			data_byte<=8'd0;
		end
		else if(bps_cnt==8'd159)begin
			data_byte[0]<=(r_data_byte[0]>3'd3)?1'b1:1'b0;
			data_byte[1]<=(r_data_byte[1]>3'd3)?1'b1:1'b0;
			data_byte[2]<=(r_data_byte[2]>3'd3)?1'b1:1'b0;
			data_byte[3]<=(r_data_byte[3]>3'd3)?1'b1:1'b0;
			data_byte[4]<=(r_data_byte[4]>3'd3)?1'b1:1'b0;
			data_byte[5]<=(r_data_byte[5]>3'd3)?1'b1:1'b0;
			data_byte[6]<=(r_data_byte[6]>3'd3)?1'b1:1'b0;
			data_byte[7]<=(r_data_byte[7]>3'd3)?1'b1:1'b0;
		end
		else begin
			data_byte<=data_byte;
		end
	end
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			uart_state<=1'b0;
		end
		else if(rxd_negedge==1'b1)begin
			uart_state<=1'b1;
		end
		else if(rxd_finish==1'b1||(bps_cnt==8'd12 && (Start>3'd3)))begin
			uart_state<=1'b0;
		end
		else begin
			uart_state<=uart_state;
		end
	end

endmodule

 
문자 버퍼 모듈:
module uart_dat_buf(clk,rst_n,rxd_sel,rxd_finish,rxd_state,data_byte,led
    );
	input           clk       ;//    
	input           rst_n     ;//    
	input           rxd_sel   ;//    
	input           rxd_finish;//          
	input           rxd_state ;//      
	input     [7:0] data_byte ;
	
	output reg[7:0] led       ;
	
	parameter       TIME = 25'd2500_0000,
					S0 =4'd0,
					S1 =4'd1,
					S2 =4'd2,
					S3 =4'd3,
					S4 =4'd4,
					S5 =4'd5,
					S6 =4'd6,
					S7 =4'd7,
					S8 =4'd8,
					S9 =4'd9,
					S10=4'd10,
					ERROR =4'd15;
	//      
	reg       [7:0] data_byte_temp;
	always@(*)begin
		if(rst_n==1'b0)begin
			data_byte_temp=8'd0;
		end
		else if(rxd_state==1'b1)begin
			data_byte_temp=data_byte;
		end
		else begin
			data_byte_temp=data_byte_temp;
		end
	end
	//    
	reg [3:0] state_c;
	reg [3:0] state_n;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			state_c<=S0;
		end
		else if(rxd_state==1'b1)begin
			state_c<=state_c;
		end
		else begin
			state_c<=state_n;
		end
	end
	//    
	always@(*)begin
		if(rst_n==1'b0)begin
			state_n=S0;
		end
		else if(rxd_sel==1'b0&&rxd_state==1'b1)begin
			case(state_c)
				S0 :
					if(data_byte_temp=="I")begin
						state_n=S1;
					end
					else begin
						state_n=ERROR;
					end
				S1 :
					if(data_byte_temp==" ")begin
						state_n=S2;
					end
					else begin
						state_n=ERROR;
					end
				S2 :
					if(data_byte_temp=="L")begin
						state_n=S3;
					end
					else begin
						state_n=ERROR;
					end
				S3 :
					if(data_byte_temp=="i")begin
						state_n=S4;
					end
					else begin
						state_n=ERROR;
					end
				S4 :
					if(data_byte_temp=="k")begin
						state_n=S5;
					end
					else begin
						state_n=ERROR;
					end
				S5 :
					if(data_byte_temp=="e")begin
						state_n=S6;
					end
					else begin
						state_n=ERROR;
					end
				S6 :
					if(data_byte_temp==" ")begin
						state_n=S7;
					end
					else begin
						state_n=ERROR;
					end
				S7 :
					if(data_byte_temp=="F")begin
						state_n=S8;
					end
					else begin
						state_n=ERROR;
					end
				S8 :
					if(data_byte_temp=="P")begin
						state_n=S9;
					end
					else begin
						state_n=ERROR;
					end
				S9 :
					if(data_byte_temp=="G")begin
						state_n=S10;
					end
					else begin
						state_n=ERROR;
					end
				S10:
					if(data_byte_temp=="A")begin
						state_n=S0;
					end
					else begin
						state_n=ERROR;
					end
				ERROR:if(data_byte_temp=="I")begin
						state_n=S1;
					end
					else begin
						state_n=ERROR;
					end
				default:state_n=S0;
			endcase
		end
		else begin
			state_n=state_n;
		end
	end
	
	reg [1:0] flag_led;
	//    
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			flag_led<=2'd3;
		end
		else if(rxd_sel==1'b1)begin
			flag_led<=2'b10;
		end
		else if(rxd_sel==1'b0)begin
			if(state_c==ERROR)begin
				flag_led<=2'b01;
			end
			else if(state_c==S10)begin
				flag_led<=2'b00;
			end
			else begin
				flag_led<=flag_led;
			end
		end
		else begin
			flag_led<=2'b11;
		end
	end
	//  led  
	reg  [24:0] cnt;//       
	//              
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			cnt <=25'd0;
		end
		else if(cnt ==TIME-1'b1)begin
			cnt <=1'b0;
		end
		else if(flag_led==2'b01)begin
			cnt <=cnt + 1'b1;
		end
		else begin
			cnt <=25'd0;
		end
	end
	
	//led   
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			led<=8'b1111_1111;
		end
		else if(flag_led==2'b10)begin
			led<=data_byte_temp;
		end
		else if(flag_led==2'b00)begin
			led<=8'b0000_0000;
		end
		else if(flag_led==2'b01)begin
			if(cnt

 
최상위 파일:
module uart_rxd_top(ext_clk_25m,ext_rst_n,uart_rx,led,switch0
    );
	input ext_clk_25m	;//    
	input ext_rst_n		;//    
	input uart_rx		;//      
	input switch0		;//    
	
	output [7:0]led		;//led  
	
	wire [7:0]data_byte;
	wire uart_state;
	wire rxd_finish;
	
	uart_rxd u_r1(
	.clk(ext_clk_25m),
	.rst_n(ext_rst_n),
	.bps_set(1), 
	.rxd(uart_rx),
	.data_byte(data_byte),
	.rxd_finish(rxd_finish),
	.uart_state(uart_state)
    );
	
	uart_dat_buf u_dat1(
	.clk(ext_clk_25m),
	.rst_n(ext_rst_n),
	.rxd_sel(switch0),
	.rxd_finish(rxd_finish),
	.rxd_state(uart_state),
	.data_byte(data_byte),
	.led(led)
    );

endmodule

좋은 웹페이지 즐겨찾기