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