334 lines
11 KiB
Verilog
334 lines
11 KiB
Verilog
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
|