Files
BSI-901-fpga-software/c64_pro.srcs/sources_1/rtl/upload/upload_top_last.v
T
2024-10-28 13:14:49 +08:00

472 lines
14 KiB
Verilog

`timescale 1 ns / 1 ps
module upload_top#
(
parameter CLK_PERIOD = 10 ,
parameter CHANNLE_QTY = 64 ,
parameter PRE_MSG_LEN = 128
)
(
input clk ,
input rst_n ,
input [13-1:0] bram_addr ,
input bram_clk ,
input [32-1:0] bram_din ,
output [32-1:0] bram_dout ,
input bram_en ,
input bram_rst ,
input [ 4-1:0] bram_we ,
output interrupt ,
input [32-1:0] s_axis_trigger_tdata ,
input s_axis_trigger_tvalid ,
output reg s_axis_trigger_tready ,
input [32-1:0] s_axis_eeg16_tdata ,
input s_axis_eeg16_tlast ,
output s_axis_eeg16_tready ,
input s_axis_eeg16_tvalid ,
input [32-1:0] s_axis_eeg24_tdata ,
input s_axis_eeg24_tlast ,
output s_axis_eeg24_tready ,
input s_axis_eeg24_tvalid ,
input [32-1:0] s_axis_emg_tdata ,
input s_axis_emg_tlast ,
output s_axis_emg_tready ,
input s_axis_emg_tvalid ,
input [48-1:0] accel_data ,
input m_axis_record_tfull ,
output reg [ 8-1:0] m_axis_record_tdata ,
output reg [ 1-1:0] m_axis_record_tkeep ,
output reg m_axis_record_tlast ,
input m_axis_record_tready ,
output reg m_axis_record_tvalid ,
output [ 4-1:0] debug_sig
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam ST_IDLE = 4'd0 ;
localparam ST_MSG_HEAD = 4'd1 ;
localparam ST_WAIT = 4'd2 ;
localparam ST_READ_TRIGGER = 4'd3 ;
localparam ST_MSG_TRIGGER = 4'd4 ;
localparam ST_MSG_RECORD = 4'd5 ;
localparam ST_MSG_END = 4'd6 ;
localparam ST_ADDITIONAL = 4'd7 ;
localparam ADDL_NUM = 12 ;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
wire pulse_ms ;
wire [64-1:0] run_time_ms ;
wire reset_package_id ;
wire [32-1:0] package_overtime_ms ;
reg [32-1:0] overtime_ms ;
reg [32-1:0] package_id ;
wire [ 8*PRE_MSG_LEN-1:0] pre_message_array ;
wire [ 8-1:0] pre_message[0:PRE_MSG_LEN-1];
wire [ 8-1:0] pre_message_length ;
reg [ 4-1:0] cstate ;
reg [ 4-1:0] nstate ;
wire [ 8*CHANNLE_QTY-1:0] ch_mapping2pc_array ;
wire [ CHANNLE_QTY-1:0] upload_ch_array ;
wire select_eeg24 ;
wire [16-1:0] message_end ;
reg [32-1:0] trigger_word ;
wire [ 8-1:0] trigger_byte[0:3] ;
wire [ 8-1:0] msg_end[0:1] ;
wire [32-1:0] upload_round_qty_set ;
reg [32-1:0] upload_round_qty ;
reg [32-1:0] upload_bytes_cnt ;
wire [32-1:0] upload_bytes_cnt_add1 ;
reg [32-1:0] upload_rounds_cnt ;
reg [32-1:0] upload_record_bytes_cnt ;
wire [16-1:0] crc16_out ;
reg [16-1:0] crc16 ;
wire [ 8-1:0] upload_addl[0:ADDL_NUM-1] ;
reg [ 8-1:0] byte_cnt ;
wire [ 8-1:0] m_axis_eeg_tdata ;
wire m_axis_eeg_tlast ;
reg m_axis_eeg_tready ;
wire m_axis_eeg_tvalid ;
reg upload_break ;
reg upload_disable ;
wire [ 4-1:0] debug_sig_sort ;
genvar i;
//*****************************************************************************
// Instantiation
//*****************************************************************************
upload_config#
(
.CHANNLE_QTY ( CHANNLE_QTY ),
.PRE_MSG_LEN ( PRE_MSG_LEN )
)
u_upload_config
(
.clk ( clk ),
.rst_n ( rst_n ),
.bram_addr ( bram_addr ),
.bram_clk ( bram_clk ),
.bram_din ( bram_din ),
.bram_dout ( bram_dout ),
.bram_en ( bram_en ),
.bram_rst ( bram_rst ),
.bram_we ( bram_we ),
.pre_message_array ( pre_message_array ),
.pre_message_length ( pre_message_length ),
.upload_round_qty_set ( upload_round_qty_set ),
.ch_mapping2pc_array ( ch_mapping2pc_array ),
.upload_ch_array ( upload_ch_array ),
.select_eeg24 ( select_eeg24 ),
.reset_package_id ( reset_package_id ),
.package_overtime_ms ( package_overtime_ms ),
.message_end ( message_end ) //TODO: unused
);
upload_sort#
(
.CLK_PERIOD ( CLK_PERIOD ),
.CHANNLE_QTY ( CHANNLE_QTY )
)
u_upload_sort
(
.clk ( clk ),
.rst_n ( rst_n ),
.ch_mapping2pc_array ( ch_mapping2pc_array ),
.upload_ch_array ( upload_ch_array ),
.select_eeg24 ( 1'b1 ),
//------------------------------------------ PL logic
.s_axis_eeg16_tdata ( s_axis_eeg16_tdata ),
.s_axis_eeg16_tlast ( s_axis_eeg16_tlast ),
.s_axis_eeg16_tready ( s_axis_eeg16_tready ),
.s_axis_eeg16_tvalid ( s_axis_eeg16_tvalid ),
.s_axis_eeg24_tdata ( s_axis_eeg24_tdata ),
.s_axis_eeg24_tlast ( s_axis_eeg24_tlast ),
.s_axis_eeg24_tready ( s_axis_eeg24_tready ),
.s_axis_eeg24_tvalid ( s_axis_eeg24_tvalid ),
//------------------------------------------ PC logic
.m_axis_eeg_tdata ( m_axis_eeg_tdata ),
.m_axis_eeg_tlast ( m_axis_eeg_tlast ),
.m_axis_eeg_tready ( m_axis_eeg_tready ),
.m_axis_eeg_tvalid ( m_axis_eeg_tvalid ),
.debug_sig_sort ( debug_sig_sort )
);
run_time#
(
.CLK_PERIOD ( CLK_PERIOD )
)
u_run_time
(
.clk ( clk ),
.rst_n ( rst_n ),
.pulse_ms ( pulse_ms ),
.run_time_ms ( run_time_ms )
);
//*****************************************************************************
// Function
//*****************************************************************************
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
if( !rst_n ) cstate <= ST_IDLE;
else cstate <= nstate;
end
always@( * ) begin
case ( cstate )
ST_IDLE:
if ( m_axis_eeg_tvalid )
nstate <= ST_MSG_HEAD;
else
nstate <= ST_IDLE;
ST_MSG_HEAD:
if ( byte_cnt == pre_message_length - 1 )
nstate <= ST_WAIT;
else
nstate <= ST_MSG_HEAD;
ST_WAIT:
if ( upload_rounds_cnt == upload_round_qty || overtime_ms == package_overtime_ms )
nstate <= ST_MSG_END;
else if ( m_axis_record_tfull && !upload_disable )
nstate <= ST_MSG_END;
else if ( m_axis_eeg_tvalid )
nstate <= ST_READ_TRIGGER;
else
nstate <= ST_WAIT;
ST_READ_TRIGGER:
nstate <= ST_MSG_TRIGGER;
ST_MSG_TRIGGER:
if ( byte_cnt == 4-1 )
nstate <= ST_MSG_RECORD;
else
nstate <= ST_MSG_TRIGGER;
ST_MSG_RECORD:
if ( m_axis_eeg_tready && m_axis_eeg_tvalid && m_axis_eeg_tlast )
nstate <= ST_WAIT;
else
nstate <= ST_MSG_RECORD;
ST_MSG_END:
if ( byte_cnt == 2-1 )
nstate <= ST_ADDITIONAL;
else
nstate <= ST_MSG_END;
ST_ADDITIONAL:
if ( byte_cnt == ADDL_NUM-1 )
nstate <= upload_break? ST_WAIT:ST_IDLE;
else
nstate <= ST_ADDITIONAL;
default:
nstate <= ST_IDLE;
endcase
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
upload_break <= 1'b0;
else if ( cstate == ST_WAIT && (upload_rounds_cnt != upload_round_qty && overtime_ms != package_overtime_ms) && m_axis_record_tfull && !upload_disable )
upload_break <= 1'b1;
else if ( cstate == ST_ADDITIONAL && nstate != ST_ADDITIONAL )
upload_break <= 1'b0;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
upload_disable <= 1'b0;
else if ( cstate == ST_ADDITIONAL && nstate != ST_ADDITIONAL )
upload_disable <= m_axis_record_tfull;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
package_id <= 0;
else if ( reset_package_id )
package_id <= 0;
else if ( cstate == ST_MSG_END && nstate == ST_ADDITIONAL )
package_id <= package_id + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
upload_round_qty <= 0;
else if ( cstate == ST_IDLE )
upload_round_qty <= upload_round_qty_set;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
s_axis_trigger_tready <= 1'b0;
else if ( nstate == ST_READ_TRIGGER )
s_axis_trigger_tready <= 1'b1;
else
s_axis_trigger_tready <= 1'b0;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
trigger_word <= 0;
else if ( s_axis_trigger_tvalid && s_axis_trigger_tready )
trigger_word <= s_axis_trigger_tdata;
else if ( cstate != ST_MSG_TRIGGER )
trigger_word <= 0;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
m_axis_eeg_tready <= 1'b0;
else if ( cstate == ST_MSG_RECORD || nstate == ST_MSG_RECORD )
m_axis_eeg_tready <= 1'b1;
else
m_axis_eeg_tready <= 1'b0;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
upload_rounds_cnt <= 0;
else if ( cstate == ST_IDLE )
upload_rounds_cnt <= 0;
else if ( m_axis_eeg_tready && m_axis_eeg_tvalid && m_axis_eeg_tlast )
upload_rounds_cnt <= upload_rounds_cnt + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
overtime_ms <= 0;
else if ( m_axis_eeg_tvalid )
overtime_ms <= 0;
else if ( pulse_ms )
overtime_ms <= overtime_ms + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
byte_cnt <= 0;
else if ( cstate != nstate )
byte_cnt <= 0;
else
byte_cnt <= byte_cnt + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
m_axis_record_tdata <= 0;
m_axis_record_tkeep <= 1'b1;
m_axis_record_tvalid <= 1'b0;
end else if ( cstate == ST_MSG_HEAD ) begin
m_axis_record_tdata <= pre_message[byte_cnt];
m_axis_record_tvalid <= upload_disable? 1'b0:1;
end else if ( cstate == ST_MSG_TRIGGER ) begin
m_axis_record_tdata <= trigger_byte[byte_cnt];
m_axis_record_tvalid <= upload_disable? 1'b0:1;
end else if ( cstate == ST_MSG_RECORD && m_axis_eeg_tvalid && m_axis_eeg_tready ) begin
m_axis_record_tdata <= m_axis_eeg_tdata;
m_axis_record_tvalid <= upload_disable? 1'b0:1;
end else if ( cstate == ST_MSG_END ) begin
m_axis_record_tdata <= msg_end[byte_cnt];
m_axis_record_tvalid <= upload_disable? 1'b0:1;
end else if ( cstate == ST_ADDITIONAL ) begin
m_axis_record_tdata <= upload_addl[byte_cnt];
m_axis_record_tvalid <= upload_disable? 1'b0:1;
end else
m_axis_record_tvalid <= 1'b0;
end
always @ ( posedge clk ) begin
if ( cstate == ST_IDLE )
crc16 <= 16'hFFFF;
else if ( cstate != ST_MSG_END && m_axis_record_tvalid && m_axis_record_tready )
crc16 <= crc16_out;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
m_axis_record_tlast <= 1'b0;
end else if ( cstate == ST_ADDITIONAL && (byte_cnt == ADDL_NUM-1) ) begin
m_axis_record_tlast <= 1'b1;
end else
m_axis_record_tlast <= 1'b0;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
upload_bytes_cnt <= 0;
else if ( cstate == ST_IDLE )
upload_bytes_cnt <= 0;
else if ( (cstate != ST_ADDITIONAL) && m_axis_record_tvalid && m_axis_record_tready )
upload_bytes_cnt <= upload_bytes_cnt + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
upload_record_bytes_cnt <= 0;
else if ( cstate == ST_IDLE )
upload_record_bytes_cnt <= 0;
else if ( cstate == ST_MSG_RECORD && m_axis_eeg_tvalid && m_axis_eeg_tready )
upload_record_bytes_cnt <= upload_record_bytes_cnt + 1'b1;
end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
//pre_message[21:14] is run_time_ms
//pre_message[26:23] is package_id
generate
for(i=0;i<PRE_MSG_LEN;i=i+1) begin : pre_msg
if ( i > 13 && i < 22 )
assign pre_message[i] = run_time_ms[8*(i-14)+7 : 8*(i-14)];
else if ( i > 22 && i < 27 )
assign pre_message[i] = package_id[8*(i-23)+7 : 8*(i-23)];
else
assign pre_message[i] = pre_message_array[8*i+7 : 8*i];
end
endgenerate
assign trigger_byte[0] = trigger_word[ 7: 0];
assign trigger_byte[1] = trigger_word[15: 8];
assign trigger_byte[2] = trigger_word[23:16];
assign trigger_byte[3] = trigger_word[31:24];
assign crc16_out = crc16_d8(crc16, m_axis_record_tdata);
assign msg_end[0] = crc16[15: 8];
assign msg_end[1] = crc16[ 7: 0];
assign upload_bytes_cnt_add1 = upload_bytes_cnt + 1'b1;
assign upload_addl[ 0] = upload_bytes_cnt_add1[ 7: 0];
assign upload_addl[ 1] = upload_bytes_cnt_add1[15: 8];
assign upload_addl[ 2] = upload_bytes_cnt_add1[23:16];
assign upload_addl[ 3] = upload_bytes_cnt_add1[31:24];
assign upload_addl[ 4] = upload_rounds_cnt[ 7: 0];
assign upload_addl[ 5] = upload_rounds_cnt[15: 8];
assign upload_addl[ 6] = upload_rounds_cnt[23:16];
assign upload_addl[ 7] = upload_rounds_cnt[31:24];
assign upload_addl[ 8] = upload_record_bytes_cnt[ 7: 0];
assign upload_addl[ 9] = upload_record_bytes_cnt[15: 8];
assign upload_addl[10] = upload_record_bytes_cnt[23:16];
assign upload_addl[11] = upload_record_bytes_cnt[31:24];
assign debug_sig[0] = m_axis_record_tvalid;
assign debug_sig[1] = m_axis_record_tready;
assign debug_sig[2] = m_axis_record_tfull;
assign debug_sig[3] = 1'b0;
endmodule