Verilog实现串口接收多帧数据

  • 格式:pdf
  • 大小:40.51 KB
  • 文档页数:8

Verilog实现串⼝接收多帧数据

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company:

// Engineer:

//

// Create Date: 19:50:45 04/19/2015

// Design Name:

// Module Name: Serial_Decoder

// Project Name:

// Target Devices:

// Tool versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//////////////////////////////////////////////////////////////////////////////////

module Serial_Decoder(

input wire clk_seri, //串⼝时钟,⽤于从串⼝发送命令给FPGA

input wire rst,

input wire RxD,

output reg[1:0] modu_sel, //BPSK,QPSK,8PSK选择

output reg[13:0] ser_asf, //由串⼝发过来的asf

output reg[31:0] ser_ftw, //由串⼝发过来的ftw

output reg cmd_done, //上位机给FPGA发送指令结束

output reg[31:0] dina, //ROM存储器,⽤于存储外部PN码

output reg wea,

output reg[1:0] addra

);

reg cmd_rdy;//指令接收完成

reg [3:0] instr_code;//⽤于分辨命令,是asf还是ftw还是外部PN码reg [31:0] cmd_data; //接收从上层发过来的命令

wire RxD_data_ready;

wire [7:0] RxD_data;

reg [1:0] instr_cnt;

reg data_rec_valid;

reg data_rec_busy;

reg [1:0] data_cnt;

//instance

receiver i_receiver(

.clk(clk_seri),

.RxD(RxD),

.RxD_data_ready(RxD_data_ready),

.RxD_data_error(),

.RxD_data(RxD_data)

);

//*********上位机发命令给FPGA************//

always @ (posedge clk_seri)

begin

if(rst)

begin

instr_cnt <= 0;

data_rec_valid <= 0;

end

else if(RxD_data_ready && !data_rec_busy)

case(instr_cnt)

2'd0:

if(RxD_data == 8'h55)

begin

instr_cnt <= 2'd1;

data_rec_valid <= 0;

end

else

begin

instr_cnt <= 2'd0;

data_rec_valid <= 0;end

2'd1:

if(RxD_data == 8'h55)

begin

instr_cnt <= 2'd2;

data_rec_valid <= 0;

end

else

begin

instr_cnt <= 2'd0;

data_rec_valid <= 0;

end

2'd2:

if(RxD_data == 8'h55)

begin

instr_cnt <= 2'd3;

data_rec_valid <= 0;

end

else

begin

instr_cnt <= 2'd0;

data_rec_valid <= 0;

end

2'd3:

if(RxD_data == 8'h55)

begin

instr_cnt <= 2'd3;

data_rec_valid <= 0;

end

else

begin

instr_cnt <= 2'd0;

data_rec_valid <= 1;

instr_code <= RxD_data[3:0]; //⽤来分辨各命令

enddefault:

begin

instr_cnt <= 2'd0;

data_rec_valid <= 0;

end

endcase

else

data_rec_valid <= 0;

end

always @ (posedge clk_seri)

begin

if(rst)

begin

data_cnt <= 2'd0;

data_rec_busy <= 0;

cmd_rdy <= 0;

end

else if(data_rec_valid)

begin

data_cnt <= 0;

data_rec_busy <= 1;

cmd_rdy <= 0;

end

else if(RxD_data_ready && data_rec_busy)

case(data_cnt)

2'd0:

begin

data_cnt <= 2'd1;

data_rec_busy <= 1;

cmd_rdy <= 0;

cmd_data[31:24]<= RxD_data;

end

2'd1:

begin

data_cnt <= 2'd2;data_rec_busy <= 1;

cmd_rdy <= 0;

cmd_data[23:16]<= RxD_data;

end

2'd2:

begin

data_cnt <= 2'd3;

data_rec_busy <= 1;

cmd_rdy <= 0;

cmd_data[15:8] <= RxD_data;

end

2'd3:

begin

data_cnt <= 2'd0;

data_rec_busy <= 0;

cmd_rdy <= 1; //命令接收完毕

cmd_data[7:0] <= RxD_data;

end

default:

begin

data_cnt <= 2'd0;

data_rec_busy <= 0;

cmd_rdy <= 0;

end

endcase

else

cmd_rdy <= 0;

end

//*********分辨命令*********//

always @ (posedge clk_seri)

begin

if(rst)

begin

cmd_done <= 0;

modu_sel <= 0;ser_asf <= 0;

ser_ftw <= 0;

end

else if(cmd_rdy)

begin

case(instr_code)

4'h6:

begin

ser_ftw <= cmd_data;

cmd_done <= 0;

end

4'h7:

begin

modu_sel <= cmd_data[25:24];

cmd_done <= 0;

end

4'h8:

begin

ser_asf <= cmd_data[13:0];

cmd_done <= 0;

end

4'hF:

cmd_done <= 1; //上位机命令发送结束default:;

endcase

end

else

begin

ser_ftw <= ser_ftw;

ser_asf <= ser_asf;

modu_sel<= modu_sel;

cmd_done<= cmd_done;

end

end

always @ (posedge clk_seri)

beginif(rst)

begin

dina <= 0;

wea <= 1;

addra <= 0;

end

else if(cmd_rdy)

begin

case(instr_code)

//********A--D是外部PN码,将其存⼊ROM中********//

4'hA:

begin

dina <= cmd_data;

wea <= 1;

addra <= 2'd0;

end

4'hB:

begin

dina <= cmd_data;

wea <= 1;

addra <= 2'd1;

end

4'hC:

begin

dina <= cmd_data;

wea <= 1;

addra <= 2'd2;

end

4'hD:

begin

dina <= cmd_data;

addra <= 2'd3;

wea <= 0;

end

default:;