`timescale 1 ns / 1 ps module eeg_emg_upload ( input clk , input rst_n , (*mark_debug="true"*)input [ 8-1:0] m_axis_eeg_tdata , (*mark_debug="true"*)input m_axis_eeg_tlast , (*mark_debug="true"*)input m_axis_eeg_tvalid , (*mark_debug="true"*)input [ 8-1:0] m_axis_emg_tdata , (*mark_debug="true"*)input m_axis_emg_tlast , (*mark_debug="true"*)input m_axis_emg_tvalid , (*mark_debug="true"*)input diff_pkt_data_sel , (*mark_debug="true"*)input [1:0] eeg_emg_sel , // eeg_emg_sel[1]:emg,eeg_emg_sel[0]:eeg (*mark_debug="true"*)input [15:0] eeg_send_package_num , (*mark_debug="true"*)input [15:0] emg_send_package_num , input stop_sample , (*mark_debug="true"*)output reg [7:0] eeg_emg_tdata , (*mark_debug="true"*)output reg eeg_emg_tvalid , (*mark_debug="true"*)output reg eeg_emg_tlast ); (*mark_debug="true"*)reg [15:0] eeg_data_cnt ; (*mark_debug="true"*)wire [8:0] axis_emg_fifo_tdata ; (*mark_debug="true"*)reg fifo_emg_rd_en ; (*mark_debug="true"*)reg fifo_emg_rd_en_dly ; (*mark_debug="true"*)reg [15:0] fifo_rd_en_cnt ; (*mark_debug="true"*)wire [8:0] fifo_rd_data ; (*mark_debug="true"*)reg [7:0] axis_emg_tdata_tmp ; (*mark_debug="true"*)reg axis_emg_tlast_tmp ; (*mark_debug="true"*)reg axis_emg_tvalid_tmp ; (*mark_debug="true"*)reg [7:0] axis_eeg_tdata_tmp ; (*mark_debug="true"*)reg axis_eeg_tlast_tmp ; (*mark_debug="true"*)reg axis_eeg_tvalid_tmp ; (*mark_debug="true"*)reg [7:0] eeg_emg_tdata_tmp ; (*mark_debug="true"*)reg eeg_emg_tvalid_tmp ; (*mark_debug="true"*)reg eeg_emg_tlast_tmp ; (*mark_debug="true"*)wire [ 8-1:0] msg_crc[0:1] ; (*mark_debug="true"*)wire [16-1:0] crc16_out ;//wire (*mark_debug="true"*)reg [16-1:0] crc16 ; (*mark_debug="true"*)reg crc_vld ; (*mark_debug="true"*)reg fifo_rst ; assign axis_emg_fifo_tdata[8:0]={m_axis_emg_tlast,m_axis_emg_tdata[7:0]}; assign crc16_out = crc16_d8(crc16, eeg_emg_tdata_tmp); always @(posedge clk or negedge rst_n) begin//eeg数据计数 if (!rst_n) begin fifo_rst <= 1'b1 ; end else begin fifo_rst <= stop_sample ; end end always @(posedge clk or negedge rst_n) begin//eeg数据计数 if (!rst_n) begin eeg_data_cnt[15:0] <= 16'b0 ; end else if(stop_sample)begin eeg_data_cnt[15:0] <= 16'b0 ; end else if(m_axis_eeg_tlast==1'b1)begin eeg_data_cnt[15:0] <= 16'b0 ; end else if(m_axis_eeg_tvalid==1'b1)begin eeg_data_cnt[15:0] <= eeg_data_cnt[15:0]+1'b1 ; end else begin eeg_data_cnt[15:0] <= eeg_data_cnt[15:0] ; end end always @(posedge clk or negedge rst_n) begin//emg 读使能打拍 if (!rst_n) begin fifo_emg_rd_en_dly <= 1'b0 ; end else if(stop_sample)begin fifo_emg_rd_en_dly <= 1'b0 ; end else begin fifo_emg_rd_en_dly <= fifo_emg_rd_en ; end end always @(posedge clk or negedge rst_n) begin//emg读使能产生?当fifo_emg_rd_en为1和fifo_rd_en_cnt[15:0]为emg_send_package_num[15:0]-1时,需要将其置为0,其它则用fifo_emg_rd_en if (!rst_n) begin fifo_emg_rd_en <= 1'b0; end else if(stop_sample)begin fifo_emg_rd_en <= 1'b0; end else if(eeg_emg_sel[1:0]==2'b11)begin if(m_axis_eeg_tlast==1'b1) fifo_emg_rd_en <= 1'b1; else if((fifo_emg_rd_en == 1'b1)&&(fifo_rd_en_cnt[15:0]==emg_send_package_num[15:0]-1)) fifo_emg_rd_en <= 1'b0; else fifo_emg_rd_en <= fifo_emg_rd_en ; end else if(eeg_emg_sel[1:0]==2'b10)begin if(m_axis_emg_tlast==1'b1) fifo_emg_rd_en <= 1'b1; else if((fifo_emg_rd_en == 1'b1)&&(fifo_rd_en_cnt[15:0]==emg_send_package_num[15:0]-1)) fifo_emg_rd_en <= 1'b0; else fifo_emg_rd_en <= fifo_emg_rd_en ; end else begin fifo_emg_rd_en <= 1'b0; end end always @(posedge clk or negedge rst_n) begin//emg读使能计数? if (!rst_n) begin fifo_rd_en_cnt[15:0] <= 16'b0; end else if(stop_sample)begin fifo_rd_en_cnt[15:0] <= 16'b0; end else if(fifo_emg_rd_en==1'b1)begin fifo_rd_en_cnt[15:0] <= fifo_rd_en_cnt[15:0]+1'b1 ; end else begin fifo_rd_en_cnt[15:0] <= 16'b0; end end always @(posedge clk or negedge rst_n) begin//emg valid_tmp和tdata_tmp产生 if (!rst_n) begin axis_emg_tvalid_tmp <= 1'b0 ; axis_emg_tdata_tmp[7:0] <= 8'b0 ; end else if(stop_sample)begin axis_emg_tvalid_tmp <= 1'b0 ; axis_emg_tdata_tmp[7:0] <= 8'b0 ; end else if(eeg_emg_sel[1:0]==2'b11)begin//当eeg和emg都有时? if(fifo_emg_rd_en_dly)begin if(fifo_rd_en_cnt[15:0] <= 16'd85)begin//去掉emg头 axis_emg_tvalid_tmp <= 1'b0 ; axis_emg_tdata_tmp[7:0] <= fifo_rd_data[7:0] ; end else if(fifo_rd_en_cnt[15:0]==emg_send_package_num[15:0]-16'd13)begin axis_emg_tdata_tmp[7:0] <= msg_crc[0][7:0]; end else if(fifo_rd_en_cnt[15:0]==emg_send_package_num[15:0]-16'd12)begin axis_emg_tdata_tmp[7:0] <= msg_crc[1][7:0]; end else begin axis_emg_tvalid_tmp <= 1'b1 ; axis_emg_tdata_tmp[7:0] <= fifo_rd_data[7:0] ; end end else begin axis_emg_tvalid_tmp <= 1'b0 ; axis_emg_tdata_tmp[7:0] <= fifo_rd_data[7:0] ; end end else if(eeg_emg_sel[1:0]==2'b10)begin//当只有emg时? axis_emg_tvalid_tmp <= fifo_emg_rd_en_dly ; axis_emg_tdata_tmp[7:0] <= fifo_rd_data[7:0] ; end else begin axis_emg_tvalid_tmp <= 1'b0; axis_emg_tdata_tmp[7:0] <= 8'b0 ; end end always @(posedge clk or negedge rst_n) begin//emg tlast_tmp产生 if (!rst_n) axis_emg_tlast_tmp <= 1'b0 ; else if(stop_sample)begin axis_emg_tlast_tmp <= 1'b0 ; end else if((eeg_emg_sel[1:0]==2'b11)||(eeg_emg_sel[1:0]==2'b10))begin//閲囬泦鏉垮拰emg閮芥湁鏃舵垨鑰呭彧鏈塭mg鏃? if((fifo_emg_rd_en==1'b0)&&(fifo_emg_rd_en_dly==1'b1)) axis_emg_tlast_tmp <= 1'b1 ; else axis_emg_tlast_tmp <= 1'b0 ; end else begin axis_emg_tlast_tmp <= 1'b0; end end always @(posedge clk or negedge rst_n) begin//eeg valid_tmp和data_tmp[7:0]产生 ,根据选择来判断,2'b11来判断 if (!rst_n) begin axis_eeg_tvalid_tmp <= 1'b0 ; axis_eeg_tdata_tmp[7:0] <= 8'b0 ; end else if(stop_sample)begin axis_eeg_tvalid_tmp <= 1'b0 ; axis_eeg_tdata_tmp[7:0] <= 8'b0 ; end else if(eeg_emg_sel[1:0]==2'b11)begin//当eeg和emg都有时? if(m_axis_eeg_tvalid)begin if(eeg_data_cnt[15:0] >= eeg_send_package_num[15:0]-16'd14)begin//去掉eeg的尾巴 axis_eeg_tvalid_tmp <= 1'b0 ; axis_eeg_tdata_tmp[7:0] <= axis_eeg_tdata_tmp[7:0] ; end else begin axis_eeg_tvalid_tmp <= 1'b1 ; axis_eeg_tdata_tmp[7:0] <= m_axis_eeg_tdata[7:0] ; end end else begin axis_eeg_tvalid_tmp <= 1'b0 ; axis_eeg_tdata_tmp[7:0] <= m_axis_eeg_tdata[7:0] ; end end else if(eeg_emg_sel[1:0]==2'b01)begin//当只有eeg时? axis_eeg_tvalid_tmp <= m_axis_eeg_tvalid ; axis_eeg_tdata_tmp[7:0] <= m_axis_eeg_tdata[7:0] ; end else begin axis_eeg_tvalid_tmp <= 1'b0; axis_eeg_tdata_tmp[7:0] <= 8'b0 ; end end always @(posedge clk or negedge rst_n) begin//emg tlast_tmp产生,先用stop_sample,然后根据选择的sel来判断如何做 if (!rst_n) axis_eeg_tlast_tmp <= 1'b0 ; else if(stop_sample)begin axis_eeg_tlast_tmp <= 1'b0 ; end else if(eeg_emg_sel[1:0]==2'b01)begin//当只有eeg时? axis_eeg_tlast_tmp <= m_axis_eeg_tlast ; end else begin axis_eeg_tlast_tmp <= 1'b0; end end always @(posedge clk or negedge rst_n) begin//emg valid_tmp和data_tmp[7:0]产生 if (!rst_n) begin eeg_emg_tvalid_tmp <= 1'b0 ; eeg_emg_tdata_tmp[7:0] <= 8'b0 ; eeg_emg_tlast_tmp <= 1'b0 ; end else if(stop_sample)begin eeg_emg_tvalid_tmp <= 1'b0 ; eeg_emg_tdata_tmp[7:0] <= 8'b0 ; eeg_emg_tlast_tmp <= 1'b0 ; end else if(eeg_emg_sel[1:0]==2'b11)begin//当eeg和emg都有时? if(axis_eeg_tvalid_tmp==1'b1)begin eeg_emg_tvalid_tmp <= axis_eeg_tvalid_tmp ; eeg_emg_tdata_tmp[7:0] <= axis_eeg_tdata_tmp[7:0] ; eeg_emg_tlast_tmp <= axis_eeg_tlast_tmp ; end else if(axis_emg_tvalid_tmp==1'b1)begin eeg_emg_tvalid_tmp <= axis_emg_tvalid_tmp ; eeg_emg_tdata_tmp[7:0] <= axis_emg_tdata_tmp[7:0] ; eeg_emg_tlast_tmp <= axis_emg_tlast_tmp ; end else begin eeg_emg_tvalid_tmp <= 1'b0 ; eeg_emg_tdata_tmp[7:0] <= eeg_emg_tdata_tmp[7:0] ; eeg_emg_tlast_tmp <= 1'b0 ; end end else if(eeg_emg_sel[1:0]==2'b01)begin //当只有eeg时? eeg_emg_tvalid_tmp <= axis_eeg_tvalid_tmp ; eeg_emg_tdata_tmp[7:0] <= axis_eeg_tdata_tmp[7:0] ; eeg_emg_tlast_tmp <= axis_eeg_tlast_tmp ; end else if(eeg_emg_sel[1:0]==2'b10)begin//当只有emg时? eeg_emg_tvalid_tmp <= axis_emg_tvalid_tmp ; eeg_emg_tdata_tmp[7:0] <= axis_emg_tdata_tmp[7:0] ; eeg_emg_tlast_tmp <= axis_emg_tlast_tmp ; end else begin eeg_emg_tvalid_tmp <= 1'b0 ; eeg_emg_tdata_tmp[7:0] <= 8'b0 ; eeg_emg_tlast_tmp <= 1'b0 ; end end always @(posedge clk or negedge rst_n) begin//主要计算eeg_emng_tlast if (!rst_n) begin eeg_emg_tvalid <= 1'b0 ; eeg_emg_tlast <= 1'b0 ; end else if(stop_sample)begin eeg_emg_tvalid <= 1'b0 ; eeg_emg_tlast <= 1'b0 ; end else begin //打拍? eeg_emg_tvalid <= eeg_emg_tvalid_tmp ; eeg_emg_tlast <= eeg_emg_tlast_tmp ; end end always @(posedge clk or negedge rst_n) begin// if (!rst_n) begin eeg_emg_tdata[7:0] <= 8'b0 ; end else if(stop_sample)begin eeg_emg_tdata[7:0] <= 8'b0 ; end else if((eeg_emg_sel[1:0]==2'b11)&&(diff_pkt_data_sel==1'b0))begin //eeg和emg都有时? diff_pkt_data_sel==1'b0 默认差分打包数据 1:选择差分8通道原始数据 if(eeg_emg_tvalid_tmp==1'b1)begin if(fifo_rd_en_cnt[15:0]==emg_send_package_num[15:0]-16'd11)begin eeg_emg_tdata[7:0] <= msg_crc[0][7:0]; end else if(fifo_rd_en_cnt[15:0]==emg_send_package_num[15:0]-16'd10)begin eeg_emg_tdata[7:0] <= msg_crc[1][7:0]; end else begin eeg_emg_tdata[7:0] <= eeg_emg_tdata_tmp[7:0] ; end end else begin eeg_emg_tdata[7:0] <= eeg_emg_tdata[7:0] ; end end else if(((eeg_emg_sel[1:0]==2'b10)&&(diff_pkt_data_sel==1'b0))||(eeg_emg_sel[1:0]==2'b01))begin eeg_emg_tdata[7:0] <= eeg_emg_tdata_tmp[7:0] ; end else begin eeg_emg_tdata[7:0] <= 8'b0 ; end end function automatic [15:0] crc16_d8; input [15:0] crcIn; input [7:0] data; begin crc16_d8[0] = crcIn[0] ^ crcIn[1] ^ crcIn[2] ^ crcIn[3] ^ crcIn[4] ^ crcIn[5] ^ crcIn[6] ^ crcIn[7] ^ crcIn[8] ^ data[0] ^ data[1] ^ data[2] ^ data[3] ^ data[4] ^ data[5] ^ data[6] ^ data[7]; crc16_d8[1] = crcIn[9]; crc16_d8[2] = crcIn[10]; crc16_d8[3] = crcIn[11]; crc16_d8[4] = crcIn[12]; crc16_d8[5] = crcIn[13]; crc16_d8[6] = crcIn[0] ^ crcIn[14] ^ data[0]; crc16_d8[7] = crcIn[0] ^ crcIn[1] ^ crcIn[15] ^ data[0] ^ data[1]; crc16_d8[8] = crcIn[1] ^ crcIn[2] ^ data[1] ^ data[2]; crc16_d8[9] = crcIn[2] ^ crcIn[3] ^ data[2] ^ data[3]; crc16_d8[10] = crcIn[3] ^ crcIn[4] ^ data[3] ^ data[4]; crc16_d8[11] = crcIn[4] ^ crcIn[5] ^ data[4] ^ data[5]; crc16_d8[12] = crcIn[5] ^ crcIn[6] ^ data[5] ^ data[6]; crc16_d8[13] = crcIn[6] ^ crcIn[7] ^ data[6] ^ data[7]; crc16_d8[14] = crcIn[0] ^ crcIn[1] ^ crcIn[2] ^ crcIn[3] ^ crcIn[4] ^ crcIn[5] ^ crcIn[6] ^ data[0] ^ data[1] ^ data[2] ^ data[3] ^ data[4] ^ data[5] ^ data[6]; crc16_d8[15] = crcIn[0] ^ crcIn[1] ^ crcIn[2] ^ crcIn[3] ^ crcIn[4] ^ crcIn[5] ^ crcIn[6] ^ crcIn[7] ^ data[0] ^ data[1] ^ data[2] ^ data[3] ^ data[4] ^ data[5] ^ data[6] ^ data[7]; end endfunction always @ (posedge clk or negedge rst_n) begin//主要计算crc_vld if (!rst_n)begin crc_vld <= 1'b0; end else if(stop_sample==1'b1)begin crc_vld <= 1'b0; end else if (eeg_emg_tlast_tmp==1'b1)begin crc_vld <= 1'b0; end else if(axis_eeg_tvalid_tmp | axis_emg_tvalid_tmp)begin//axis_record_tvalid_tmp==1'b1 crc_vld <= 1'b1; end else begin crc_vld <= crc_vld; end end always @ (posedge clk or negedge rst_n) begin//主要计算crc16 if (!rst_n)begin crc16 <= 16'hFFFF; end else if(stop_sample==1'b1)begin crc16 <= 16'hFFFF; end else if (crc_vld==1'b0)begin crc16 <= 16'hFFFF; end else if(eeg_emg_sel[1:0]==2'b01)begin//当只有eeg时? if(eeg_emg_tvalid_tmp==1'b1)begin if((eeg_data_cnt[15:0] == eeg_send_package_num[15:0]-16'd14)||(eeg_data_cnt[15:0] == eeg_send_package_num[15:0]-16'd13))begin crc16 <= crc16 ; end else begin crc16 <= crc16_out ; end end else begin crc16 <= crc16;//crc16_out ; end end else if((eeg_emg_sel[1:0]==2'b11)||(eeg_emg_sel[1:0]==2'b10))begin//eeg和emg都有时或者只有emg时? if(eeg_emg_tvalid_tmp==1'b1)begin if((fifo_rd_en_cnt[15:0]==emg_send_package_num[15:0]-16'd11)||(fifo_rd_en_cnt[15:0]==emg_send_package_num[15:0]-16'd10))begin crc16 <= crc16 ; end else begin crc16 <= crc16_out ; end end else begin crc16 <= crc16;//crc16_out ; end end else begin// crc16 <= crc16_out ; end end assign msg_crc[0] = crc16[15: 8]; assign msg_crc[1] = crc16[ 7: 0]; fifo_generator_0 u0_fifo_generator_0( .full ( ), .din (axis_emg_fifo_tdata[8:0]), .wr_en (m_axis_emg_tvalid ), .empty ( ), .dout (fifo_rd_data[8:0] ), .rd_en (fifo_emg_rd_en ), .rst (fifo_rst ),//~rst_n(20260902 change) .wr_clk(clk ), .rd_clk(clk ) ); endmodule