UDP_data_process/status_to_udp.v

334 lines
11 KiB
Verilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module status_to_udp (
input clk,
input reset,
input TOE_reg_out_valid,
input [65:0] TOE_reg_dout,
// 通信板(CMU)状态信息接口
output reg CMU_Status_Info_ready,
input CMU_Status_Info_valid,
input CMU_Status_Info_last,
input [31:0] CMU_Status_Info_data,
// 调控板(XYZ)状态信息接口
output reg XYZ_Status_Info_ready,
input XYZ_Status_Info_valid,
input XYZ_Status_Info_last,
input [31:0] XYZ_Status_Info_data,
// 读出板(DAQ)状态信息接口
output reg DAQ_Status_Info_ready,
input DAQ_Status_Info_valid,
input DAQ_Status_Info_last,
input [31:0] DAQ_Status_Info_data,
// UDP发送FIFO接口
input udp_app_send_fifo_rden,
output [7:0] udp_app_send_fifo_rddata,
output [11:0] udp_app_send_fifo_rdcnt,
output udp_app_send_fifo_empty
);
// =========================== 参数定义 ===========================
reg [2:0] A_state;
localparam IDLE = 3'd0;
localparam WAIT_READ =3'd1;
localparam RECV_TOE = 3'd2;
localparam RECV_CMU = 3'd3;
localparam RECV_XYZ = 3'd4;
localparam RECV_DAQ = 3'd5;
reg [2:0]S_state;
localparam SEND_IDLE = 3'd0;
localparam SEND_TOE_HEAD_LENGTH = 3'd1;
localparam SEND_TOE_DATA_1 = 3'd2;
localparam SEND_TOE_DATA_2 = 3'd3;
localparam SEND_CRC = 3'd4;
localparam SEND_INFO_HEAD_LENGTH = 3'd5;
localparam SEND_INFO_DATA = 3'd6;
// =========================== 寄存器定义 ===========================
reg [31:0] data_buffer;
reg [1:0] byte_counter;
reg buffer_valid;
// FIFO相关信号
reg fifo_wr_en;
reg [31:0] fifo_wr_data;
wire fifo_full;
wire TOE_rec_fifo_empty;
reg TOE_rec_fifo_rden;
wire [65:0]TOE_rec_fifo_dout;
reg [63:0]TOE_ready_Data;
reg TOE_ready_Data_valid;
reg [63:0]TOE_payload;
reg [31:0]CMU_Status_data;
reg send_busy;
reg [31:0]crc32_calc;
reg info_recv_flag;
reg [15:0]Info_data_bytes_num;
// =========================== FIFO实例化 ===========================
//512 depth 32to8
fifo_generator_32to8 fifo_32to8 (
.clk(clk), // input wire clk
.rst(reset), // input wire rst
.wr_en(fifo_wr_en), // input wire wr_en
.din(fifo_wr_data), // input wire [31 : 0] din
.full(), // output wire full
.rd_en(udp_app_send_fifo_rden), // input wire rd_en
.dout(udp_app_send_fifo_rddata), // output wire [7 : 0] doutCMU
.empty(udp_app_send_fifo_empty), // output wire empty
.rd_data_count(udp_app_send_fifo_rdcnt), // output wire [11 : 0] rd_data_count
.wr_rst_busy(), // output wire wr_rst_busy
.rd_rst_busy() // output wire rd_rst_busy
);
//256 depth 66 to 66
fifo_generator_66to66 TOE_rec_fifo (
.clk(clk), // input wire clk
.din(TOE_reg_dout), // input wire [65 : 0] din
.wr_en(TOE_reg_out_valid), // input wire wr_en
.rd_en(TOE_rec_fifo_rden), // input wire rd_en
.dout(TOE_rec_fifo_dout), // output wire [65 : 0] dout
.full(), // output wire full
.empty(TOE_rec_fifo_empty) // output wire empty
);
reg [31:0]info_cache_fifo_din;
reg info_cache_fifo_wren;
reg info_cache_fifo_rden;
wire [31:0]info_cache_fifo_dout;
wire info_cache_fifo_full;
wire info_cache_fifo_empty;
//32 to 32
fifo_generator_32to32 info_cache_fifo (
.clk(clk), // input wire clk
.din(info_cache_fifo_din), // input wire [31 : 0] din
.wr_en(info_cache_fifo_wren), // input wire wr_en
.rd_en(info_cache_fifo_rden), // input wire rd_en
.dout(info_cache_fifo_dout), // output wire [31 : 0] dout
.full(info_cache_fifo_full), // output wire full
.empty(info_cache_fifo_empty) // output wire empty
);
// =========================== 仲裁存储状态机 ===========================
always @(posedge clk or posedge reset) begin
if (reset)begin
A_state <= IDLE;
TOE_ready_Data <= 64'b0;
TOE_rec_fifo_rden <= 1'b0;
info_cache_fifo_din <= 32'b0;
info_cache_fifo_wren <= 1'b0;
info_recv_flag <= 1'b0;
Info_data_bytes_num <= 16'b0;
end
else
begin
case (A_state)
IDLE: begin
TOE_ready_Data <= 64'b0;
TOE_ready_Data_valid <=1'b0;
info_cache_fifo_wren <= 1'b0;
info_cache_fifo_din <= 32'b0;
info_recv_flag = 1'b0;
CMU_Status_Info_ready <=1'b0;
DAQ_Status_Info_ready <=1'b0;
XYZ_Status_Info_ready <=1'b0;
// 优先级仲裁TOE >CMU > XYZ > DAQ
if((!TOE_rec_fifo_empty) &&(!send_busy))begin
A_state <= WAIT_READ;
TOE_rec_fifo_rden <= 1'b1;
end
else if (CMU_Status_Info_valid &&(!send_busy))begin
A_state <= RECV_CMU;
end
else if (XYZ_Status_Info_valid &&(!send_busy))begin
A_state <= RECV_XYZ;
end
else if (DAQ_Status_Info_valid &&(!send_busy))begin
A_state <= RECV_DAQ;
end
else
A_state <= IDLE;
end
WAIT_READ : begin
A_state <= RECV_TOE;
TOE_rec_fifo_rden <= 1'b0;
end
RECV_TOE: begin
//执行TOE发送操作
TOE_ready_Data[53:52]<=TOE_rec_fifo_dout[65:64];
TOE_ready_Data[48]<= 1'b1;
TOE_ready_Data[47:32]<=TOE_rec_fifo_dout[47:32];
TOE_ready_Data[31:0] <= TOE_rec_fifo_dout[31:0];
TOE_ready_Data_valid <= 1'b1;
send_busy <= 1'b1; //拿到数立马进行发送状态
A_state <= IDLE;
end
RECV_CMU: begin
CMU_Status_Info_ready <=1'b1;
info_cache_fifo_wren <= 1'b1;
info_cache_fifo_din <= CMU_Status_Info_data;
Info_data_bytes_num <= Info_data_bytes_num + 3'd4;
if (CMU_Status_Info_last)begin
A_state <= IDLE;
send_busy <= 1'b1; //拿到数立马进行发送状态
info_recv_flag = 1'b1;
end
end
RECV_XYZ: begin
XYZ_Status_Info_ready <=1'b1;
info_cache_fifo_wren <= 1'b1;
info_cache_fifo_din <= XYZ_Status_Info_data;
Info_data_bytes_num <= Info_data_bytes_num + 3'd4;
if (XYZ_Status_Info_last)begin
A_state <= IDLE;
send_busy <= 1'b1; //拿到数立马进行发送状态
info_recv_flag = 1'b1;
end
end
RECV_DAQ: begin //5
DAQ_Status_Info_ready <=1'b1;
info_cache_fifo_wren <= 1'b1;
info_cache_fifo_din <= DAQ_Status_Info_data;
Info_data_bytes_num <= Info_data_bytes_num + 3'd4;
if (DAQ_Status_Info_last)begin
A_state <= IDLE;
send_busy <= 1'b1; //拿到数立马进行发送状态
info_recv_flag = 1'b1;
end
end
default: A_state <= IDLE;
endcase
end
end
//发送状态机
always @(posedge clk or posedge reset) begin
if(reset)begin
S_state <= SEND_IDLE;
send_busy <=1'b0;
fifo_wr_en<= 1'b0;
fifo_wr_data <= 32'b0;
crc32_calc <= 32'hFFFFFFFF;
info_cache_fifo_rden <= 1'b0;
TOE_payload <= 64'b0;
end
else begin
case(S_state)
SEND_IDLE : begin
fifo_wr_en <= 1'b0;
fifo_wr_data <= 32'b0;
crc32_calc <= 32'hFFFFFFFF;
if(TOE_ready_Data_valid) begin
TOE_payload <= TOE_ready_Data;
S_state <= SEND_TOE_HEAD_LENGTH;
end
else if(info_recv_flag) begin
S_state <= SEND_INFO_HEAD_LENGTH;
info_cache_fifo_rden <= 1;
end
end
SEND_TOE_HEAD_LENGTH :begin
fifo_wr_en <=1;
fifo_wr_data <= 32'h45470008;
S_state <= SEND_TOE_DATA_1;
end
SEND_TOE_DATA_1 : begin
fifo_wr_en <=1;
fifo_wr_data <= TOE_payload[63:32];
crc32_calc <= calc_crc32(TOE_payload[63:32],crc32_calc);
S_state <= SEND_TOE_DATA_2;
end
SEND_TOE_DATA_2 : begin
fifo_wr_en <=1;
fifo_wr_data <= TOE_payload[31:0];
crc32_calc <= calc_crc32(TOE_payload[31:0],crc32_calc);
S_state <= SEND_CRC;
end
SEND_CRC : begin //
fifo_wr_en <=1;
fifo_wr_data <= crc32_calc;
S_state <= SEND_IDLE;
send_busy <= 1'b0;
info_cache_fifo_rden <= 1'b0;
end
SEND_INFO_HEAD_LENGTH : begin //5
fifo_wr_en <=1;
fifo_wr_data[31:16] <= 32'h494e;
fifo_wr_data[15:0] <= Info_data_bytes_num;
Info_data_bytes_num <= 16'b0; //用完就清零
S_state <= SEND_INFO_DATA;
end
SEND_INFO_DATA : begin //6
fifo_wr_en <=1;
fifo_wr_data <= info_cache_fifo_dout;
crc32_calc <= calc_crc32(info_cache_fifo_dout,crc32_calc);
if(info_cache_fifo_empty)begin
S_state <= SEND_CRC;
end
end
endcase
end
end
// // =========================== FIFO写入控制 ===========================
//CRC32计算函数生成多项式G(x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1初始值0xffffffff。
function [31:0] calc_crc32;
input [31:0] data;
input [31:0] crc;
reg [31:0] new_crc;
integer i;
localparam [31:0] POLY = 32'h04C11DB7;
begin
new_crc = crc ^ data;
for (i = 0; i < 32; i = i + 1) begin
if (new_crc[31]) begin
new_crc = (new_crc << 1) ^ POLY;
end else begin
new_crc = new_crc << 1;
end
end
calc_crc32 = new_crc;
end
endfunction
endmodule