2026-01-09 19:36:54 +08:00
|
|
|
|
module status_to_udp (
|
|
|
|
|
|
input clk,
|
|
|
|
|
|
input reset,
|
|
|
|
|
|
input status_report_en,
|
|
|
|
|
|
|
|
|
|
|
|
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,
|
2026-01-09 21:46:56 +08:00
|
|
|
|
|
|
|
|
|
|
// UDP0发送FIFO接口(负责TOE)
|
|
|
|
|
|
input udp_app_send_fifo_rden_0,
|
|
|
|
|
|
output [7:0] udp_app_send_fifo_rddata_0,
|
|
|
|
|
|
output [11:0] udp_app_send_fifo_rdcnt_0,
|
|
|
|
|
|
output udp_app_send_fifo_empty_0,
|
2026-01-09 19:36:54 +08:00
|
|
|
|
|
2026-01-09 21:46:56 +08:00
|
|
|
|
// UDP1发送FIFO接口(负责3块板子)
|
|
|
|
|
|
input udp_app_send_fifo_rden_1,
|
|
|
|
|
|
output [7:0] udp_app_send_fifo_rddata_1,
|
|
|
|
|
|
output [11:0] udp_app_send_fifo_rdcnt_1,
|
|
|
|
|
|
output udp_app_send_fifo_empty_1
|
2026-01-09 19:36:54 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// =========================== 参数定义 ===========================
|
|
|
|
|
|
reg [3:0] A_state; // 需要4位,因为增加了WAIT_CMU_VALID等状态
|
|
|
|
|
|
localparam IDLE = 4'd0;
|
|
|
|
|
|
localparam WAIT_READ = 4'd1;
|
|
|
|
|
|
localparam RECV_TOE = 4'd2;
|
|
|
|
|
|
localparam WAIT_CMU_VALID = 4'd3; // 新增:等待CMU valid
|
|
|
|
|
|
localparam RECV_CMU = 4'd4;
|
|
|
|
|
|
localparam WAIT_XYZ_VALID = 4'd5; // 新增:等待XYZ valid
|
|
|
|
|
|
localparam RECV_XYZ = 4'd6;
|
|
|
|
|
|
localparam WAIT_DAQ_VALID = 4'd7; // 新增:等待DAQ valid
|
|
|
|
|
|
localparam RECV_DAQ = 4'd8;
|
|
|
|
|
|
|
2026-01-09 21:46:56 +08:00
|
|
|
|
reg [3:0] S_state;
|
|
|
|
|
|
localparam SEND_IDLE = 4'd0;
|
|
|
|
|
|
localparam SEND_TOE_HEAD_LENGTH = 4'd1;
|
|
|
|
|
|
localparam SEND_TOE_DATA_1 = 4'd2;
|
|
|
|
|
|
localparam SEND_TOE_DATA_LENGTH = 4'd3;
|
|
|
|
|
|
localparam SEND_TOE_DATA_2 = 4'd4;
|
|
|
|
|
|
localparam SEND_CRC_TOE = 4'd5;
|
|
|
|
|
|
localparam SEND_INFO_HEAD_LENGTH = 4'd6;
|
|
|
|
|
|
localparam SEND_INFO_DATA = 4'd7;
|
|
|
|
|
|
localparam SEND_CRC_INFO = 4'd8;
|
2026-01-09 19:36:54 +08:00
|
|
|
|
|
|
|
|
|
|
// =========================== 寄存器定义 ===========================
|
|
|
|
|
|
reg [31:0] data_buffer;
|
|
|
|
|
|
reg [1:0] byte_counter;
|
|
|
|
|
|
reg buffer_valid;
|
|
|
|
|
|
|
|
|
|
|
|
// FIFO相关信号
|
2026-01-09 21:46:56 +08:00
|
|
|
|
reg fifo_wr_en; //udp1
|
2026-01-09 19:36:54 +08:00
|
|
|
|
reg [31:0] fifo_wr_data;
|
2026-01-09 21:46:56 +08:00
|
|
|
|
reg fifo_wr_en_TOE; //udp0
|
|
|
|
|
|
reg [31:0] fifo_wr_data_TOE;
|
|
|
|
|
|
|
2026-01-09 19:36:54 +08:00
|
|
|
|
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 send_finish;
|
|
|
|
|
|
reg [31:0] crc32_calc;
|
|
|
|
|
|
reg info_recv_flag;
|
|
|
|
|
|
reg [15:0] Info_data_bytes_num;
|
|
|
|
|
|
reg [15:0] Info_data_bytes_num_reg;
|
|
|
|
|
|
|
|
|
|
|
|
// 超时计数器
|
|
|
|
|
|
reg [7:0] wait_timeout_cnt;
|
|
|
|
|
|
|
|
|
|
|
|
// 轮询计数器
|
|
|
|
|
|
reg [1:0] poll_counter;
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
2026-01-09 21:46:56 +08:00
|
|
|
|
// =========================== FIFO ===========================
|
|
|
|
|
|
|
|
|
|
|
|
//512 depth 32to8 --responsible for UDP0(TOE)
|
|
|
|
|
|
fifo_generator_32to8 fifo_32to8_TOE (
|
|
|
|
|
|
.clk(clk), // input wire clk
|
|
|
|
|
|
.rst(reset), // input wire rst
|
|
|
|
|
|
.wr_en(fifo_wr_en_TOE), // input wire wr_en
|
|
|
|
|
|
.din(fifo_wr_data_TOE), // input wire [31 : 0] din
|
|
|
|
|
|
.full(), // output wire full
|
|
|
|
|
|
|
|
|
|
|
|
.rd_en(udp_app_send_fifo_rden_0), // input wire rd_en
|
|
|
|
|
|
.dout(udp_app_send_fifo_rddata_0), // output wire [7 : 0] dout
|
|
|
|
|
|
.empty(udp_app_send_fifo_empty_0), // output wire empty
|
|
|
|
|
|
.rd_data_count(udp_app_send_fifo_rdcnt_0), // output wire [11 : 0] rd_data_count
|
2026-01-09 19:36:54 +08:00
|
|
|
|
|
2026-01-09 21:46:56 +08:00
|
|
|
|
.wr_rst_busy(), // output wire wr_rst_busy
|
|
|
|
|
|
.rd_rst_busy() // output wire rd_rst_busy
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
//512 depth 32to8 --responsible for UDP1(state_info)
|
|
|
|
|
|
fifo_generator_32to8 fifo_32to8_INFO (
|
2026-01-09 19:36:54 +08:00
|
|
|
|
.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
|
2026-01-09 21:46:56 +08:00
|
|
|
|
.full(), // output wire full
|
2026-01-09 19:36:54 +08:00
|
|
|
|
|
2026-01-09 21:46:56 +08:00
|
|
|
|
.rd_en(udp_app_send_fifo_rden_1), // input wire rd_en
|
|
|
|
|
|
.dout(udp_app_send_fifo_rddata_1), // output wire [7 : 0] dout
|
|
|
|
|
|
.empty(udp_app_send_fifo_empty_1), // output wire empty
|
|
|
|
|
|
.rd_data_count(udp_app_send_fifo_rdcnt_1), // output wire [11 : 0] rd_data_count
|
2026-01-09 19:36:54 +08:00
|
|
|
|
|
|
|
|
|
|
.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
|
|
|
|
|
|
.srst(reset), // input wire srst
|
|
|
|
|
|
.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
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
//32 to 32
|
|
|
|
|
|
fifo_generator_32to32 info_cache_fifo (
|
|
|
|
|
|
.clk(clk), // input wire clk
|
|
|
|
|
|
.srst(reset), // input wire srst
|
|
|
|
|
|
.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
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// ILA实例化(调试用)
|
|
|
|
|
|
ila_00 ila_udp_data (
|
|
|
|
|
|
.clk(clk), // input wire clk
|
|
|
|
|
|
.probe0({
|
|
|
|
|
|
reset,
|
|
|
|
|
|
fifo_wr_en,
|
|
|
|
|
|
fifo_wr_data,
|
|
|
|
|
|
TOE_reg_dout,
|
|
|
|
|
|
TOE_reg_out_valid,
|
|
|
|
|
|
TOE_rec_fifo_rden,
|
|
|
|
|
|
TOE_rec_fifo_dout,
|
|
|
|
|
|
TOE_rec_fifo_empty,
|
|
|
|
|
|
info_cache_fifo_din,
|
|
|
|
|
|
info_cache_fifo_wren,
|
|
|
|
|
|
info_cache_fifo_rden,
|
|
|
|
|
|
info_cache_fifo_dout,
|
|
|
|
|
|
info_cache_fifo_empty,
|
|
|
|
|
|
TOE_ready_Data,
|
|
|
|
|
|
TOE_ready_Data_valid,
|
|
|
|
|
|
info_recv_flag,
|
|
|
|
|
|
send_busy,
|
|
|
|
|
|
A_state,
|
|
|
|
|
|
S_state,
|
|
|
|
|
|
crc32_calc,
|
|
|
|
|
|
TOE_payload,
|
|
|
|
|
|
Info_data_bytes_num,
|
|
|
|
|
|
Info_data_bytes_num_reg,
|
|
|
|
|
|
wait_timeout_cnt,
|
|
|
|
|
|
poll_counter
|
|
|
|
|
|
})
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// =========================== 仲裁存储状态机 ===========================
|
|
|
|
|
|
always @(posedge clk) begin
|
|
|
|
|
|
if (reset) begin
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
TOE_ready_Data <= 64'b0;
|
|
|
|
|
|
TOE_ready_Data_valid <= 1'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;
|
|
|
|
|
|
send_busy <= 1'b0;
|
|
|
|
|
|
CMU_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
XYZ_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
DAQ_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
wait_timeout_cnt <= 8'b0;
|
|
|
|
|
|
poll_counter <= 2'b00;
|
|
|
|
|
|
end else begin
|
|
|
|
|
|
case (A_state)
|
|
|
|
|
|
IDLE: begin //0
|
|
|
|
|
|
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;
|
|
|
|
|
|
XYZ_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
DAQ_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
Info_data_bytes_num <= 16'b0;
|
|
|
|
|
|
wait_timeout_cnt <= 8'b0;
|
|
|
|
|
|
|
|
|
|
|
|
if (send_finish) begin
|
|
|
|
|
|
send_busy <= 1'b0;
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
// 优先级仲裁:TOE > 状态信息板卡
|
|
|
|
|
|
if ((!TOE_rec_fifo_empty) && (!send_busy)) begin
|
|
|
|
|
|
A_state <= WAIT_READ;
|
|
|
|
|
|
TOE_rec_fifo_rden <= 1'b1;
|
|
|
|
|
|
end else if (status_report_en && (!send_busy)) begin
|
|
|
|
|
|
// 轮询不同的板卡:按照CMU->XYZ->DAQ的顺序
|
|
|
|
|
|
case (poll_counter)
|
|
|
|
|
|
2'b00: begin // CMU
|
|
|
|
|
|
A_state <= WAIT_CMU_VALID;
|
|
|
|
|
|
CMU_Status_Info_ready <= 1'b1;
|
|
|
|
|
|
end
|
|
|
|
|
|
2'b01: begin // XYZ
|
|
|
|
|
|
A_state <= WAIT_XYZ_VALID;
|
|
|
|
|
|
XYZ_Status_Info_ready <= 1'b1;
|
|
|
|
|
|
end
|
|
|
|
|
|
2'b10: begin // DAQ
|
|
|
|
|
|
A_state <= WAIT_DAQ_VALID;
|
|
|
|
|
|
DAQ_Status_Info_ready <= 1'b1;
|
|
|
|
|
|
end
|
|
|
|
|
|
default: begin
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
poll_counter <= 2'b00;
|
|
|
|
|
|
end
|
|
|
|
|
|
endcase
|
|
|
|
|
|
end else begin
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
WAIT_READ: begin //1
|
|
|
|
|
|
A_state <= RECV_TOE;
|
|
|
|
|
|
TOE_rec_fifo_rden <= 1'b0;
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
RECV_TOE: begin //2
|
|
|
|
|
|
TOE_ready_Data[63] <= 1'b1; // 读标志位
|
|
|
|
|
|
TOE_ready_Data[56:52] <= 5'h02; // 新增
|
|
|
|
|
|
TOE_ready_Data[49:48] <= TOE_rec_fifo_dout[65:64]; // CID
|
|
|
|
|
|
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;
|
|
|
|
|
|
poll_counter <= 2'b00; // 重置轮询计数器
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
WAIT_CMU_VALID: begin //3
|
|
|
|
|
|
wait_timeout_cnt <= wait_timeout_cnt + 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (CMU_Status_Info_valid) begin
|
|
|
|
|
|
wait_timeout_cnt <= 8'b0;
|
|
|
|
|
|
A_state <= RECV_CMU;
|
|
|
|
|
|
info_cache_fifo_wren <= 1'b1;
|
|
|
|
|
|
info_cache_fifo_din <= CMU_Status_Info_data;
|
|
|
|
|
|
Info_data_bytes_num <= Info_data_bytes_num + 4;
|
|
|
|
|
|
end else if (wait_timeout_cnt > 8'd10) begin // 超时10个周期
|
|
|
|
|
|
wait_timeout_cnt <= 8'b0;
|
|
|
|
|
|
CMU_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
poll_counter <= poll_counter + 1; // 尝试下一个板卡
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
RECV_CMU: begin //4
|
|
|
|
|
|
// 保持ready为高,直到last信号到来
|
|
|
|
|
|
CMU_Status_Info_ready <= 1'b1;
|
|
|
|
|
|
if(CMU_Status_Info_valid) info_cache_fifo_wren <= 1'b1;
|
|
|
|
|
|
else info_cache_fifo_wren <= 1'b0;
|
|
|
|
|
|
info_cache_fifo_din <= CMU_Status_Info_data;
|
2026-01-09 19:42:43 +08:00
|
|
|
|
if (CMU_Status_Info_valid) begin /////valid可能为高低高低交替,所以计数也要加判断逻辑,以免多计数。
|
2026-01-09 19:36:54 +08:00
|
|
|
|
Info_data_bytes_num <= Info_data_bytes_num + 4;
|
2026-01-09 19:42:43 +08:00
|
|
|
|
end
|
2026-01-09 19:36:54 +08:00
|
|
|
|
if (CMU_Status_Info_last) begin
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
CMU_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
// info_cache_fifo_wren <= 1'b0;
|
|
|
|
|
|
send_busy <= 1'b1; // 拿到数立马进行发送状态
|
|
|
|
|
|
info_recv_flag <= 1'b1;
|
|
|
|
|
|
poll_counter <= 2'b00; // 重置轮询计数器
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
WAIT_XYZ_VALID: begin //5
|
|
|
|
|
|
wait_timeout_cnt <= wait_timeout_cnt + 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (XYZ_Status_Info_valid) begin
|
|
|
|
|
|
wait_timeout_cnt <= 8'b0;
|
|
|
|
|
|
A_state <= RECV_XYZ;
|
|
|
|
|
|
info_cache_fifo_wren <= 1'b1;
|
|
|
|
|
|
info_cache_fifo_din <= XYZ_Status_Info_data;
|
|
|
|
|
|
Info_data_bytes_num <= Info_data_bytes_num + 4;
|
|
|
|
|
|
end else if (wait_timeout_cnt > 8'd10) begin // 超时10个周期
|
|
|
|
|
|
wait_timeout_cnt <= 8'b0;
|
|
|
|
|
|
XYZ_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
poll_counter <= poll_counter + 1; // 尝试下一个板卡
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
RECV_XYZ: begin //6
|
|
|
|
|
|
XYZ_Status_Info_ready <= 1'b1;
|
|
|
|
|
|
if(XYZ_Status_Info_valid) info_cache_fifo_wren <= 1'b1;
|
|
|
|
|
|
else info_cache_fifo_wren <= 1'b0;
|
|
|
|
|
|
info_cache_fifo_din <= XYZ_Status_Info_data;
|
2026-01-09 19:42:43 +08:00
|
|
|
|
if (XYZ_Status_Info_valid) begin /////valid可能为高低高低交替,所以计数也要加判断逻辑,以免多计数。
|
2026-01-09 19:36:54 +08:00
|
|
|
|
Info_data_bytes_num <= Info_data_bytes_num + 4;
|
2026-01-09 19:42:43 +08:00
|
|
|
|
end
|
2026-01-09 19:36:54 +08:00
|
|
|
|
|
|
|
|
|
|
if (XYZ_Status_Info_last) begin
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
XYZ_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
// info_cache_fifo_wren <= 1'b0;
|
|
|
|
|
|
send_busy <= 1'b1;
|
|
|
|
|
|
info_recv_flag <= 1'b1;
|
|
|
|
|
|
poll_counter <= 2'b00; // 重置轮询计数器
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
WAIT_DAQ_VALID: begin //7
|
|
|
|
|
|
wait_timeout_cnt <= wait_timeout_cnt + 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (DAQ_Status_Info_valid) begin
|
|
|
|
|
|
wait_timeout_cnt <= 8'b0;
|
|
|
|
|
|
A_state <= RECV_DAQ;
|
|
|
|
|
|
info_cache_fifo_wren <= 1'b1;
|
|
|
|
|
|
info_cache_fifo_din <= DAQ_Status_Info_data;
|
|
|
|
|
|
Info_data_bytes_num <= Info_data_bytes_num + 4;
|
|
|
|
|
|
end else if (wait_timeout_cnt > 8'd10) begin // 超时10个周期
|
|
|
|
|
|
wait_timeout_cnt <= 8'b0;
|
|
|
|
|
|
DAQ_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
poll_counter <= 2'b00; // 轮询回到CMU
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
RECV_DAQ: begin //8
|
|
|
|
|
|
DAQ_Status_Info_ready <= 1'b1;
|
|
|
|
|
|
if(DAQ_Status_Info_valid) info_cache_fifo_wren <= 1'b1;
|
|
|
|
|
|
else info_cache_fifo_wren <= 1'b0;
|
|
|
|
|
|
info_cache_fifo_din <= DAQ_Status_Info_data;
|
2026-01-09 19:42:43 +08:00
|
|
|
|
if (DAQ_Status_Info_valid) begin /////valid可能为高低高低交替,所以计数也要加判断逻辑,以免多计数。
|
2026-01-09 19:36:54 +08:00
|
|
|
|
Info_data_bytes_num <= Info_data_bytes_num + 4;
|
2026-01-09 19:42:43 +08:00
|
|
|
|
end
|
2026-01-09 19:36:54 +08:00
|
|
|
|
|
|
|
|
|
|
if (DAQ_Status_Info_last) begin
|
|
|
|
|
|
A_state <= IDLE;
|
|
|
|
|
|
DAQ_Status_Info_ready <= 1'b0;
|
|
|
|
|
|
// info_cache_fifo_wren <= 1'b0;
|
|
|
|
|
|
send_busy <= 1'b1;
|
|
|
|
|
|
info_recv_flag <= 1'b1;
|
|
|
|
|
|
poll_counter <= 2'b00; // 重置轮询计数器
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
default: A_state <= IDLE;
|
|
|
|
|
|
endcase
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
// =========================== 发送状态机 ===========================
|
|
|
|
|
|
always @(posedge clk or posedge reset) begin
|
|
|
|
|
|
if(reset) begin
|
|
|
|
|
|
S_state <= SEND_IDLE;
|
|
|
|
|
|
fifo_wr_en <= 1'b0;
|
|
|
|
|
|
fifo_wr_data <= 32'b0;
|
2026-01-09 21:46:56 +08:00
|
|
|
|
fifo_wr_en_TOE <= 1'b0;//udp0
|
|
|
|
|
|
fifo_wr_data_TOE <= 32'b0;
|
2026-01-09 19:36:54 +08:00
|
|
|
|
crc32_calc <= 32'hFFFFFFFF;
|
|
|
|
|
|
info_cache_fifo_rden <= 1'b0;
|
|
|
|
|
|
TOE_payload <= 64'b0;
|
|
|
|
|
|
send_finish <= 1'b0;
|
|
|
|
|
|
Info_data_bytes_num_reg <= 1'b0;
|
|
|
|
|
|
end else begin
|
|
|
|
|
|
case(S_state)
|
|
|
|
|
|
SEND_IDLE: begin //0
|
|
|
|
|
|
fifo_wr_en <= 1'b0;
|
|
|
|
|
|
fifo_wr_data <= 32'b0;
|
2026-01-09 21:46:56 +08:00
|
|
|
|
fifo_wr_en_TOE <= 1'b0;//udp0
|
|
|
|
|
|
fifo_wr_data_TOE <= 32'b0;
|
2026-01-09 19:36:54 +08:00
|
|
|
|
crc32_calc <= 32'hFFFFFFFF;
|
|
|
|
|
|
send_finish <= 1'b0;
|
|
|
|
|
|
Info_data_bytes_num_reg <= 1'b0;
|
|
|
|
|
|
info_cache_fifo_rden <= 1'b0;
|
|
|
|
|
|
|
|
|
|
|
|
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'b1;
|
|
|
|
|
|
Info_data_bytes_num_reg <= Info_data_bytes_num;
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
SEND_TOE_HEAD_LENGTH: begin //1
|
2026-01-09 21:46:56 +08:00
|
|
|
|
fifo_wr_en_TOE <= 1'b1;
|
|
|
|
|
|
fifo_wr_data_TOE <= 32'h4547000c;
|
2026-01-09 19:36:54 +08:00
|
|
|
|
S_state <= SEND_TOE_DATA_1;
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
SEND_TOE_DATA_1: begin //2
|
2026-01-09 21:46:56 +08:00
|
|
|
|
fifo_wr_en_TOE <= 1'b1;
|
|
|
|
|
|
fifo_wr_data_TOE <= TOE_payload[63:32];
|
2026-01-09 19:36:54 +08:00
|
|
|
|
crc32_calc <= calc_crc32(TOE_payload[63:32], crc32_calc);
|
|
|
|
|
|
S_state <= SEND_TOE_DATA_LENGTH;
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
SEND_TOE_DATA_LENGTH: begin //3
|
2026-01-09 21:46:56 +08:00
|
|
|
|
fifo_wr_en_TOE <= 1'b1;
|
|
|
|
|
|
fifo_wr_data_TOE <= 32'd4; // 固定四字节长度
|
2026-01-09 19:36:54 +08:00
|
|
|
|
crc32_calc <= calc_crc32(32'd4, crc32_calc);
|
|
|
|
|
|
S_state <= SEND_TOE_DATA_2;
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
SEND_TOE_DATA_2: begin //4
|
2026-01-09 21:46:56 +08:00
|
|
|
|
fifo_wr_en_TOE <= 1'b1;
|
|
|
|
|
|
fifo_wr_data_TOE <= TOE_payload[31:0];
|
2026-01-09 19:36:54 +08:00
|
|
|
|
crc32_calc <= calc_crc32(TOE_payload[31:0], crc32_calc);
|
2026-01-09 21:46:56 +08:00
|
|
|
|
S_state <= SEND_CRC_TOE;
|
2026-01-09 19:36:54 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
2026-01-09 21:46:56 +08:00
|
|
|
|
SEND_CRC_TOE: begin //5
|
|
|
|
|
|
fifo_wr_en_TOE <= 1'b1;
|
|
|
|
|
|
fifo_wr_data_TOE <= crc32_calc;
|
2026-01-09 19:36:54 +08:00
|
|
|
|
S_state <= SEND_IDLE;
|
|
|
|
|
|
send_finish <= 1'b1;
|
|
|
|
|
|
info_cache_fifo_rden <= 1'b0;
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
SEND_INFO_HEAD_LENGTH: begin //6
|
|
|
|
|
|
fifo_wr_en <= 1'b1;
|
|
|
|
|
|
fifo_wr_data[31:16] <= 16'h494e; // "IN"
|
|
|
|
|
|
fifo_wr_data[15:0] <= Info_data_bytes_num_reg;
|
2026-01-09 19:42:43 +08:00
|
|
|
|
crc32_calc <= 32'hFFFFFFFF; //be ready to caculate crc
|
2026-01-09 19:36:54 +08:00
|
|
|
|
S_state <= SEND_INFO_DATA;
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
SEND_INFO_DATA: begin //7
|
|
|
|
|
|
fifo_wr_en <= 1'b1;
|
|
|
|
|
|
fifo_wr_data <= info_cache_fifo_dout;
|
|
|
|
|
|
crc32_calc <= calc_crc32(info_cache_fifo_dout, crc32_calc);
|
|
|
|
|
|
|
|
|
|
|
|
if(info_cache_fifo_empty) begin
|
|
|
|
|
|
info_cache_fifo_rden <= 1'b0;
|
2026-01-09 21:46:56 +08:00
|
|
|
|
S_state <= SEND_CRC_INFO;
|
2026-01-09 19:36:54 +08:00
|
|
|
|
end else begin
|
|
|
|
|
|
info_cache_fifo_rden <= 1'b1;
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
2026-01-09 21:46:56 +08:00
|
|
|
|
|
|
|
|
|
|
SEND_CRC_INFO: begin //8
|
|
|
|
|
|
fifo_wr_en <= 1'b1;
|
|
|
|
|
|
fifo_wr_data <= crc32_calc;
|
|
|
|
|
|
S_state <= SEND_IDLE;
|
|
|
|
|
|
send_finish <= 1'b1;
|
|
|
|
|
|
info_cache_fifo_rden <= 1'b0;
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2026-01-09 19:36:54 +08:00
|
|
|
|
|
|
|
|
|
|
default: S_state <= SEND_IDLE;
|
|
|
|
|
|
endcase
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
// =========================== CRC32计算函数 ===========================
|
|
|
|
|
|
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
|