Loading .settings/com.elphel.vdt.cocotb.prefs +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ cocotb_@_CocotbExtraFiles=glbl.v<-@\#\#@-> cocotb_@_CocotbIncludeDir=${verilog_project_loc}/includes<-@\#\#@->${verilog_project_loc}/ddr3<-@\#\#@->${verilog_project_loc}/x393_sata<-@\#\#@->${verilog_project_loc}/x393_sata/host<-@\#\#@-> cocotb_@_CocotbMODULE=x393_cocotb_server<-@\#\#@-> cocotb_@_CocotbTESTCASE=run_test<-@\#\#@-> cocotb_@_GTKWaveSavFile=x393_cocotb_02.sav cocotb_@_GTKWaveSavFile=x393_cocotb_03.sav cocotb_@_GrepFindErr=error|ERROR cocotb_@_GrepFindErrWarn=error|warning|ERROR|WARNING cocotb_@_PatternInfo=.*[\\s.](\\w*\\.py)\:([0-9]+)\\s*\\S*\\s*\\S*\\s*(.*) Loading cocotb/x393_cocotb_03.sav +791 −33 File changed.Preview size limit exceeded, changes collapsed. Show changes cocotb/x393_dut.v +214 −2 Original line number Diff line number Diff line Loading @@ -679,8 +679,6 @@ module x393_dut#( wire [ 9:0] gpio_pins; // inout[9:0] ([8]-synco0,[7]-syncio0,[6]-synco1,[9]-syncio1) // Connect trigger outs to triggets in (#10 needed for Icarus) assign #10 gpio_pins[7] = gpio_pins[8]; assign #10 gpio_pins[9] = gpio_pins[6]; // DDR3 signals wire SDRST; Loading Loading @@ -1714,5 +1712,219 @@ simul_axi_hp_wr #( assign x393_i.ps7_i.FCLKCLK= {4{CLK}}; assign x393_i.ps7_i.FCLKRESETN= {RST,~RST,RST,~RST}; `define TEST_IMU assign #10 gpio_pins[7] = gpio_pins[8]; `ifndef TEST_IMU assign #10 gpio_pins[9] = gpio_pins[6]; `endif `ifdef TEST_IMU // localparam X313_WA_IOPINS_EN_IMU_OUT= 'hc0000000; // localparam X313_WA_IOPINS_DIS_IMU_OUT='h80000000; //SuppressThisWarning Veditor UNUSED // localparam X313_WA_IMU_CTRL= 'h7f; // localparam X313_WA_IMU_DATA= 'h7e; // localparam X313_RA_IMU_DATA= 'h7e; // read fifo word, advance pointer (32 reads w/o ready check) // localparam X313_RA_IMU_STATUS= 'h7f; // LSB==ready // localparam IMU_PERIOD= 'h800; // normal period // localparam IMU_AUTO_PERIOD= 'hffff0000; // period defined by IMU ready localparam IMU_BIT_DURATION= 'h3; // actual F(scl) will be F(xclk)/2/(IMU_BIT_DURATION+1) localparam IMU_READY_PERIOD=100000; //100usec localparam IMU_NREADY_DURATION=10000; //10usec localparam IMU_GPS_BIT_PERIOD='h18; // 20; // serial communication duration of a bit (in system clocks) // use start of trigger as a timestamp (in async mode to prevent timestamp jitter) // parameter X313_WA_DCR1_EARLYTRIGEN='hc; //OBSOLETE! // parameter X313_WA_DCR1_EARLYTRIGDIS='h8; `endif `ifdef TEST_IMU //wire [11:0] EXT; // bidirectional //reg TEST_CPU_WR_OK; //reg TEST_CPU_RD_OK; reg SERIAL_BIT = 1'b1; reg GPS1SEC = 1'b0; reg ODOMETER_PULSE= 1'b0; integer SERIAL_DATA_FD; // @SuppressThisWarning VEditor reg IMU_DATA_READY; wire IMU_SCL=gpio_pins[0]; wire IMU_SDA=gpio_pins[1]; wire IMU_MOSI=gpio_pins[2]; wire IMU_MISO=gpio_pins[3]; // @SuppressThisWarning VEditor just for simulation reg IMU_EN; wire IMU_ACTIVE; // @SuppressThisWarning VEditor just for simulation wire IMU_NMOSI=!IMU_MOSI; wire [5:1] IMU_TAPS; reg IMU_LATE_ACKN = 0; reg IMU_SCLK = 1; reg IMU_MOSI_REVA; reg IMU_103695REVA = 1; wire IMU_MOSI_OUT; wire IMU_SCLK_OUT; reg RS232_SENDING_BYTE; // @SuppressThisWarning VEditor just for simulation reg RS232_SENDING_PAUSE; // @SuppressThisWarning VEditor just for simulation `endif `ifdef TEST_IMU initial begin SERIAL_DATA_FD=$fopen({`ROOTPATH,"/input_data/gps_data.dat"},"r"); #10000; while (!$feof (SERIAL_DATA_FD)) begin repeat (18*IMU_BIT_DURATION) begin wait (axi_hclk); wait (~axi_hclk); end // was 20 send_serial_line; send_serial_bit('h0a); send_serial_pause; // was not here GPS1SEC=1'b1; send_serial_line; send_serial_bit('h0a); GPS1SEC=1'b0; send_serial_line; send_serial_bit('h0a); send_serial_pause; send_serial_pause; ODOMETER_PULSE=1'b1; send_serial_pause; ODOMETER_PULSE=1'b0; // repeat (20) send_serial_pause; end end `endif `ifdef TEST_IMU assign IMU_MOSI_OUT=IMU_103695REVA? IMU_MOSI_REVA : IMU_MOSI; assign IMU_SCLK_OUT=IMU_103695REVA?(IMU_SCLK):IMU_SCL; always @ (posedge IMU_SDA) begin IMU_EN<=IMU_MOSI; end wire IMU_CS=IMU_103695REVA?!IMU_ACTIVE:!(IMU_EN &&IMU_SDA); reg IMU_MOSI_D; always @ (posedge IMU_SCLK_OUT) begin // IMU_MOSI_D<=IMU_MOSI; IMU_MOSI_D<=IMU_MOSI_OUT; end reg [15:0] IMU_LOOPBACK; always @ (negedge IMU_SCLK_OUT) begin if (!IMU_CS) IMU_LOOPBACK[15:0]<={IMU_LOOPBACK[14:0],IMU_MOSI_D}; end assign gpio_pins[3]=IMU_CS?IMU_DATA_READY:IMU_LOOPBACK[15]; PULLUP i_IMU_SDA (.O(IMU_SDA)); PULLUP i_IMU_SCL (.O(IMU_SCL)); initial begin // SERIAL_DATA_FD=$fopen("gps_data.dat","r"); end always begin #(IMU_READY_PERIOD-IMU_NREADY_DURATION) IMU_DATA_READY=1'b0; #(IMU_NREADY_DURATION) IMU_DATA_READY=1'b1; end assign gpio_pins[4]=SERIAL_BIT; assign gpio_pins[5]=GPS1SEC; // assign gpio_pins[6]=ODOMETER_PULSE; assign gpio_pins[9]=ODOMETER_PULSE; oneshot i_oneshot (.trigger(IMU_NMOSI), .out(IMU_ACTIVE)); dly5taps i_dly5taps (.dly_in(IMU_NMOSI), .dly_out(IMU_TAPS[5:1])); always @ (negedge IMU_ACTIVE or posedge IMU_TAPS[5]) if (!IMU_ACTIVE) IMU_LATE_ACKN<= 1'b0; else IMU_LATE_ACKN<= 1'b1; always @ (negedge IMU_LATE_ACKN or posedge IMU_TAPS[4]) if (!IMU_LATE_ACKN) IMU_SCLK<= 1'b1; else IMU_SCLK<= ~IMU_SCLK; always @ (negedge IMU_SCLK) IMU_MOSI_REVA <= IMU_NMOSI; task send_serial_bit; input [7:0] data_byte; reg [7:0] d; begin RS232_SENDING_BYTE <= 1; d <= data_byte; wait (axi_hclk); wait (~axi_hclk); // SERIAL_BIT should be 1 here // Send start bit SERIAL_BIT <= 1'b0; repeat (IMU_GPS_BIT_PERIOD) begin wait (axi_hclk); wait (~axi_hclk); end // Send 8 data bits, LSB first repeat (8) begin SERIAL_BIT <= d[0]; #1 d[7:0] <= {1'b0,d[7:1]}; repeat (IMU_GPS_BIT_PERIOD) begin wait (axi_hclk); wait (~axi_hclk); end end // Send stop bit SERIAL_BIT <= 1'b1; RS232_SENDING_BYTE <= 0; // before stop bit repeat (IMU_GPS_BIT_PERIOD) begin wait (axi_hclk); wait (~axi_hclk); end end endtask task send_serial_pause; begin RS232_SENDING_PAUSE <= 1; wait (axi_hclk); wait (~axi_hclk); SERIAL_BIT <= 1'b1; repeat (16) begin repeat (IMU_GPS_BIT_PERIOD) begin wait (axi_hclk); wait (~axi_hclk); end end RS232_SENDING_PAUSE <= 0; end endtask // SERIAL_DATA_FD=$fopen("gps_data.dat","r"); task send_serial_line; integer char; begin char=0; while (!$feof (SERIAL_DATA_FD) && (char != 'h0a)) begin char=$fgetc(SERIAL_DATA_FD); send_serial_bit(char); end end endtask `endif endmodule module oneshot(trigger, out); input trigger; output out; reg out; event start; parameter duration=4000; initial out= 0; always @ (posedge trigger) begin disable timeout; #0 -> start; end always @start begin : timeout out = 1; # duration out = 0; end endmodule module dly5taps (dly_in, dly_out); input dly_in; output [5:1] dly_out; reg [5:1] dly_out; parameter dly=6; // delay per tap, ns always @ (dly_in) # dly dly_out[1] <= dly_in; always @ (dly_out[1]) # dly dly_out[2] <= dly_out[1]; always @ (dly_out[2]) # dly dly_out[3] <= dly_out[2]; always @ (dly_out[3]) # dly dly_out[4] <= dly_out[3]; always @ (dly_out[4]) # dly dly_out[5] <= dly_out[4]; endmodule logger/event_logger.v +46 −24 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ module event_logger#( // byte-parallel timestamps from 4 sensors channels (in triggered mode all are the same, different only in free running mode) // each may generate logger event, channel number encoded in bits 25:24 of the external microseconds input [3:0] sof_mclk, // start of frame (per-channel) to filter out non-first timestamps input ts_stb_chn0, // @mclk 1 clock before ts_rcv_data is valid input [7:0] ts_data_chn0, // @mclk byte-wide serialized timestamp message received or local Loading Loading @@ -133,8 +134,8 @@ module event_logger#( reg we_config_gps; // bits 6:3, 7 - enable - {ext,invert, slot[1:0]} slot==0 - disable reg we_config_msg; // bits 12:8,13 - enable - {invert,extinp[3:0]} extinp[3:0]=='hf' - disable reg we_config_syn; // bit 14, 15 - enable - enable logging external timestamps reg we_config_rst; // bit 14, 15 - enable - enable logging external timestamps reg we_config_debug; // bit 14, 15 - enable - enable logging external timestamps reg we_config_rst; // bit 14, 15 - enable - reset reg we_config_debug; // bit 14, 15 - enable - debug bits set reg we_bitHalfPeriod; Loading @@ -159,7 +160,7 @@ module event_logger#( reg [3:0] config_gps_mclk; reg [4:0] config_msg_mclk; reg [3:0] config_syn_mclk; reg config_rst_mclk; reg config_rst_mclk = 0; reg [3:0] config_debug_mclk; reg [15:0] bitHalfPeriod_mclk; Loading Loading @@ -212,6 +213,8 @@ module event_logger#( wire cmd_we; wire cmd_status; reg [3:0] timestamps_en; // enable timestamp to go through (first after sof) assign ext_en = {{(GPIO_N-5){1'b0}}, (config_imu[1:0]==2'h2)?1'b1:1'b0, 1'b0, Loading Loading @@ -241,6 +244,9 @@ module event_logger#( assign timestamp_request[1]=config_gps[3]? (config_gps[2]?nmea_sent_start:gps_ts_stb):gps_pulse1sec_single; always @ (posedge mclk) begin timestamps_en <= enable_syn_mclk & (sof_mclk | (timestamps_en & ~{ts_stb_chn3, ts_stb_chn2,ts_stb_chn1, ts_stb_chn0})); end // filter gps_pulse1sec always @ (posedge xclk) begin Loading @@ -257,9 +263,24 @@ module event_logger#( gps_pulse1sec_single <= !gps_pulse1sec_denoise[1] && gps_pulse1sec_denoise[0]; end always @ (posedge mclk or posedge mrst) begin // was negedge we_d <= !mrst && cmd_we && !cmd_a; we_imu <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_IMU); we_gps <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_GPS); we_message <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_MSG); we_period <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_PERIOD); we_bit_duration <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_BIT_DURATION); we_bitHalfPeriod<= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_BIT_HALF_PERIOD); we_config_imu <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_IMU]; we_config_gps <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_GPS]; we_config_msg <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_MSG]; we_config_syn <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_SYN]; we_config_rst <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_EN]; we_config_debug <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_DBG]; end always @ (posedge mclk) begin // was negedge if (cmd_we) cmd_data_r <= cmd_data; // valid next after cmd_we; /* we_d <= cmd_we && !cmd_a; we_imu <= cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_IMU); we_gps <= cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_GPS); Loading @@ -273,6 +294,7 @@ module event_logger#( we_config_syn <= cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_SYN]; we_config_rst <= cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_EN]; we_config_debug <= cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_DBG]; */ if (we_config_imu) config_imu_mclk[1:0] <= cmd_data_r[LOGGER_CONF_IMU - 1 -: LOGGER_CONF_IMU_BITS]; // bits 1:0, 2 - enable slot[1:0] if (we_config_gps) config_gps_mclk[3:0] <= cmd_data_r[LOGGER_CONF_GPS - 1 -: LOGGER_CONF_GPS_BITS]; // bits 6:3, 7 - enable - {ext,inver, slot[1:0]} slot==0 - disable Loading Loading @@ -405,14 +427,14 @@ fixed-length de-noise circuitry with latency 256*T(xclk) (~3usec) .xclk (xclk), // half frequency (80 MHz nominal) .mrst (mrst), // @mclk - sync reset .xrst (xrst), // @xclk - sync reset .en_chn_mclk (enable_syn_mclk), // enable module operation, if 0 - reset .ts_stb_chn0 (ts_stb_chn0), // input .en_chn_mclk (enable_syn_mclk), // input[3:0] enable module operation, if 0 - reset .ts_stb_chn0 (ts_stb_chn0 && timestamps_en[0]), // input .ts_data_chn0 (ts_data_chn0), // input[7:0] .ts_stb_chn1 (ts_stb_chn1), // input .ts_stb_chn1 (ts_stb_chn1 && timestamps_en[1]), // input .ts_data_chn1 (ts_data_chn1), // input[7:0] .ts_stb_chn2 (ts_stb_chn2), // input .ts_stb_chn2 (ts_stb_chn2 && timestamps_en[2]), // input .ts_data_chn2 (ts_data_chn2), // input[7:0] .ts_stb_chn3 (ts_stb_chn3), // input .ts_stb_chn3 (ts_stb_chn3 && timestamps_en[3]), // input .ts_data_chn3 (ts_data_chn3), // input[7:0] .ts (timestamp_request[2]), // timestamop request .rdy (channel_ready[2]), // data ready Loading logger/imu_exttime393.v +34 −16 Original line number Diff line number Diff line Loading @@ -73,15 +73,17 @@ module imu_exttime393( reg [ 4:0] raddr; wire en_mclk = |en_chn_mclk; wire [3:0] ts_stb = {ts_stb_chn3, ts_stb_chn2, ts_stb_chn1, ts_stb_chn0}; wire [3:0] ts_got; // timestamp transferred to the channel FIFO reg en; reg rd_stb_r; reg rd_start; // 1 xclk pulse at the readout start wire rd_start_mclk; reg ts_full; // internal 4 x 16 fifo is full (or getting full) reg ts_pend; // ts fifo waiting to be rdead out reg [3:0] in_full; // input fifo has (or is acquiring) timestamp wire pre_copy_w; reg [1:0] copy_selected; // copying from the winner of 4 input fifos to the x16 output fifo reg [1:0] copy_selected; // copying from the winner of 4 input FIFOs to the x16 output fifo reg copy_started; reg [2:0] copy_cntr; // byte counter for copying reg [1:0] sel_chn; // selected channel Loading @@ -90,11 +92,11 @@ module imu_exttime393( wire [3:0] chn_pri_w; wire [1:0] chn_enc_w; reg [15:0] ts_ram [0:3]; // inner timestamp x16 memory that receives timestamp from one of the 4 input channel fifos reg [15:0] ts_ram [0:3]; // inner timestamp x16 memory that receives timestamp from one of the 4 input channel FIFOs wire [31:0] dout_chn; wire [7:0] copy_data; // data from the selected input fifos reg [7:0] copy_data_r; // low byte of the timestamp data being copied from one of the input fifos to the ts_ram reg [7:0] copy_data_r; // low byte of the timestamp data being copied from one of the input FIFOs to the ts_ram reg rd_stb_mclk; assign chn_pri_w = {in_full[3] & ~(|in_full[2:0]), in_full[2] & ~(|in_full[1:0]), in_full[1] & ~in_full[0], Loading @@ -110,14 +112,24 @@ module imu_exttime393( always @ (posedge mclk) begin copy_started <= pre_copy_started; rd_stb_mclk <= rd_stb; if (!en_mclk) ts_full <= 0; else if (pre_copy_started) ts_full <= 1; // turns on before in_full[*] - || will have no glitches else if (rd_start_mclk) ts_full <= 0; // else if (rd_start_mclk) ts_full <= 0; else if (!ts_pend && !rd_stb_mclk) ts_full <= 0; if (!en_mclk) ts_pend <= 0; else if (pre_copy_started) ts_pend <= 1; else if (rd_stb_mclk) ts_pend <= 0; if (!en_mclk) in_full <= 0; else in_full <= en_chn_mclk & (ts_stb | (in_full & ~(chn1hot & {4{copy_started}}))); else in_full <= en_chn_mclk & (ts_got | (in_full & ~(chn1hot & {4{copy_started}}))); copy_selected <= {copy_selected[0], pre_copy_w | (copy_selected[0] & ~(©_cntr[2:1]))}; // off at count 6 // copy_selected <= {copy_selected[0], (|en_chn_mclk) & (pre_copy_w | (copy_selected[0] & ~(©_cntr[2:1])))}; // off at count 6 copy_selected <= {copy_selected[0], (|en_chn_mclk) & (pre_copy_w | (copy_selected[0] & (copy_cntr[2] | ~copy_cntr[1] )))}; // off at count 2 if (pre_copy_w) sel_chn <= chn_enc_w; Loading Loading @@ -145,6 +157,10 @@ module imu_exttime393( else if (rd_stb && (raddr[1:0]==2'h3)) rdy <= 1'b0; end dly_var #(.WIDTH(1),.DLY_WIDTH(4)) ts_got0_i (.clk(mclk),.rst(~en_chn_mclk[0]), .dly(4'h7), .din(ts_stb[0]),.dout(ts_got[0])); dly_var #(.WIDTH(1),.DLY_WIDTH(4)) ts_got1_i (.clk(mclk),.rst(~en_chn_mclk[1]), .dly(4'h7), .din(ts_stb[1]),.dout(ts_got[1])); dly_var #(.WIDTH(1),.DLY_WIDTH(4)) ts_got2_i (.clk(mclk),.rst(~en_chn_mclk[2]), .dly(4'h7), .din(ts_stb[2]),.dout(ts_got[2])); dly_var #(.WIDTH(1),.DLY_WIDTH(4)) ts_got3_i (.clk(mclk),.rst(~en_chn_mclk[3]), .dly(4'h7), .din(ts_stb[3]),.dout(ts_got[3])); timestamp_fifo timestamp_fifo_chn0_i ( Loading @@ -155,7 +171,7 @@ module imu_exttime393( .din (ts_data_chn0), // input[7:0] .aclk (mclk), // input .arst (mrst), // input .advance (ts_stb[0]), // enough time .advance (ts_got[0]), // enough time .rclk (mclk), // input .rrst (mrst), // input .rstb (pre_copy_started && (sel_chn == 2'h0)),// input Loading @@ -170,7 +186,7 @@ module imu_exttime393( .din (ts_data_chn1), // input[7:0] .aclk (mclk), // input .arst (mrst), // input .advance (ts_stb[1]), // enough time .advance (ts_got[1]), // enough time .rclk (mclk), // input .rrst (mrst), // input .rstb (pre_copy_started && (sel_chn == 2'h1)),// input Loading @@ -185,7 +201,7 @@ module imu_exttime393( .din (ts_data_chn2), // input[7:0] .aclk (mclk), // input .arst (mrst), // input .advance (ts_stb[2]), // enough time .advance (ts_got[2]), // enough time .rclk (mclk), // input .rrst (mrst), // input .rstb (pre_copy_started && (sel_chn == 2'h2)),// input Loading @@ -200,7 +216,7 @@ module imu_exttime393( .din (ts_data_chn3), // input[7:0] .aclk (mclk), // input .arst (mrst), // input .advance (ts_stb[3]), // enough time .advance (ts_got[3]), // enough time .rclk (mclk), // input .rrst (mrst), // input .rstb (pre_copy_started && (sel_chn == 2'h3)),// input Loading @@ -208,10 +224,12 @@ module imu_exttime393( ); pulse_cross_clock i_rd_start_mclk (.rst(xrst), .src_clk(xclk), .dst_clk(mclk), .in_pulse(rd_start), .out_pulse(rd_start_mclk),.busy()); // pulse_cross_clock i_rd_start_mclk (.rst(xrst), .src_clk(xclk), .dst_clk(mclk), .in_pulse(rd_start), .out_pulse(rd_start_mclk),.busy()); pulse_cross_clock i_rd_start_mclk (.rst(!en), .src_clk(xclk), .dst_clk(mclk), .in_pulse(rd_start), .out_pulse(rd_start_mclk),.busy()); // generate timestamp request as soon as one of the sub-channels starts copying. That time stamp will be stored for this (ext) channel pulse_cross_clock i_ts (.rst(mrst), .src_clk(mclk), .dst_clk(xclk), .in_pulse(pre_copy_w), .out_pulse(ts),.busy()); // pulse_cross_clock i_ts (.rst(mrst), .src_clk(mclk), .dst_clk(xclk), .in_pulse(pre_copy_w), .out_pulse(ts),.busy()); pulse_cross_clock i_ts (.rst(en_chn_mclk == 0), .src_clk(mclk), .dst_clk(xclk), .in_pulse(pre_copy_w), .out_pulse(ts),.busy()); endmodule Loading
.settings/com.elphel.vdt.cocotb.prefs +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ cocotb_@_CocotbExtraFiles=glbl.v<-@\#\#@-> cocotb_@_CocotbIncludeDir=${verilog_project_loc}/includes<-@\#\#@->${verilog_project_loc}/ddr3<-@\#\#@->${verilog_project_loc}/x393_sata<-@\#\#@->${verilog_project_loc}/x393_sata/host<-@\#\#@-> cocotb_@_CocotbMODULE=x393_cocotb_server<-@\#\#@-> cocotb_@_CocotbTESTCASE=run_test<-@\#\#@-> cocotb_@_GTKWaveSavFile=x393_cocotb_02.sav cocotb_@_GTKWaveSavFile=x393_cocotb_03.sav cocotb_@_GrepFindErr=error|ERROR cocotb_@_GrepFindErrWarn=error|warning|ERROR|WARNING cocotb_@_PatternInfo=.*[\\s.](\\w*\\.py)\:([0-9]+)\\s*\\S*\\s*\\S*\\s*(.*) Loading
cocotb/x393_cocotb_03.sav +791 −33 File changed.Preview size limit exceeded, changes collapsed. Show changes
cocotb/x393_dut.v +214 −2 Original line number Diff line number Diff line Loading @@ -679,8 +679,6 @@ module x393_dut#( wire [ 9:0] gpio_pins; // inout[9:0] ([8]-synco0,[7]-syncio0,[6]-synco1,[9]-syncio1) // Connect trigger outs to triggets in (#10 needed for Icarus) assign #10 gpio_pins[7] = gpio_pins[8]; assign #10 gpio_pins[9] = gpio_pins[6]; // DDR3 signals wire SDRST; Loading Loading @@ -1714,5 +1712,219 @@ simul_axi_hp_wr #( assign x393_i.ps7_i.FCLKCLK= {4{CLK}}; assign x393_i.ps7_i.FCLKRESETN= {RST,~RST,RST,~RST}; `define TEST_IMU assign #10 gpio_pins[7] = gpio_pins[8]; `ifndef TEST_IMU assign #10 gpio_pins[9] = gpio_pins[6]; `endif `ifdef TEST_IMU // localparam X313_WA_IOPINS_EN_IMU_OUT= 'hc0000000; // localparam X313_WA_IOPINS_DIS_IMU_OUT='h80000000; //SuppressThisWarning Veditor UNUSED // localparam X313_WA_IMU_CTRL= 'h7f; // localparam X313_WA_IMU_DATA= 'h7e; // localparam X313_RA_IMU_DATA= 'h7e; // read fifo word, advance pointer (32 reads w/o ready check) // localparam X313_RA_IMU_STATUS= 'h7f; // LSB==ready // localparam IMU_PERIOD= 'h800; // normal period // localparam IMU_AUTO_PERIOD= 'hffff0000; // period defined by IMU ready localparam IMU_BIT_DURATION= 'h3; // actual F(scl) will be F(xclk)/2/(IMU_BIT_DURATION+1) localparam IMU_READY_PERIOD=100000; //100usec localparam IMU_NREADY_DURATION=10000; //10usec localparam IMU_GPS_BIT_PERIOD='h18; // 20; // serial communication duration of a bit (in system clocks) // use start of trigger as a timestamp (in async mode to prevent timestamp jitter) // parameter X313_WA_DCR1_EARLYTRIGEN='hc; //OBSOLETE! // parameter X313_WA_DCR1_EARLYTRIGDIS='h8; `endif `ifdef TEST_IMU //wire [11:0] EXT; // bidirectional //reg TEST_CPU_WR_OK; //reg TEST_CPU_RD_OK; reg SERIAL_BIT = 1'b1; reg GPS1SEC = 1'b0; reg ODOMETER_PULSE= 1'b0; integer SERIAL_DATA_FD; // @SuppressThisWarning VEditor reg IMU_DATA_READY; wire IMU_SCL=gpio_pins[0]; wire IMU_SDA=gpio_pins[1]; wire IMU_MOSI=gpio_pins[2]; wire IMU_MISO=gpio_pins[3]; // @SuppressThisWarning VEditor just for simulation reg IMU_EN; wire IMU_ACTIVE; // @SuppressThisWarning VEditor just for simulation wire IMU_NMOSI=!IMU_MOSI; wire [5:1] IMU_TAPS; reg IMU_LATE_ACKN = 0; reg IMU_SCLK = 1; reg IMU_MOSI_REVA; reg IMU_103695REVA = 1; wire IMU_MOSI_OUT; wire IMU_SCLK_OUT; reg RS232_SENDING_BYTE; // @SuppressThisWarning VEditor just for simulation reg RS232_SENDING_PAUSE; // @SuppressThisWarning VEditor just for simulation `endif `ifdef TEST_IMU initial begin SERIAL_DATA_FD=$fopen({`ROOTPATH,"/input_data/gps_data.dat"},"r"); #10000; while (!$feof (SERIAL_DATA_FD)) begin repeat (18*IMU_BIT_DURATION) begin wait (axi_hclk); wait (~axi_hclk); end // was 20 send_serial_line; send_serial_bit('h0a); send_serial_pause; // was not here GPS1SEC=1'b1; send_serial_line; send_serial_bit('h0a); GPS1SEC=1'b0; send_serial_line; send_serial_bit('h0a); send_serial_pause; send_serial_pause; ODOMETER_PULSE=1'b1; send_serial_pause; ODOMETER_PULSE=1'b0; // repeat (20) send_serial_pause; end end `endif `ifdef TEST_IMU assign IMU_MOSI_OUT=IMU_103695REVA? IMU_MOSI_REVA : IMU_MOSI; assign IMU_SCLK_OUT=IMU_103695REVA?(IMU_SCLK):IMU_SCL; always @ (posedge IMU_SDA) begin IMU_EN<=IMU_MOSI; end wire IMU_CS=IMU_103695REVA?!IMU_ACTIVE:!(IMU_EN &&IMU_SDA); reg IMU_MOSI_D; always @ (posedge IMU_SCLK_OUT) begin // IMU_MOSI_D<=IMU_MOSI; IMU_MOSI_D<=IMU_MOSI_OUT; end reg [15:0] IMU_LOOPBACK; always @ (negedge IMU_SCLK_OUT) begin if (!IMU_CS) IMU_LOOPBACK[15:0]<={IMU_LOOPBACK[14:0],IMU_MOSI_D}; end assign gpio_pins[3]=IMU_CS?IMU_DATA_READY:IMU_LOOPBACK[15]; PULLUP i_IMU_SDA (.O(IMU_SDA)); PULLUP i_IMU_SCL (.O(IMU_SCL)); initial begin // SERIAL_DATA_FD=$fopen("gps_data.dat","r"); end always begin #(IMU_READY_PERIOD-IMU_NREADY_DURATION) IMU_DATA_READY=1'b0; #(IMU_NREADY_DURATION) IMU_DATA_READY=1'b1; end assign gpio_pins[4]=SERIAL_BIT; assign gpio_pins[5]=GPS1SEC; // assign gpio_pins[6]=ODOMETER_PULSE; assign gpio_pins[9]=ODOMETER_PULSE; oneshot i_oneshot (.trigger(IMU_NMOSI), .out(IMU_ACTIVE)); dly5taps i_dly5taps (.dly_in(IMU_NMOSI), .dly_out(IMU_TAPS[5:1])); always @ (negedge IMU_ACTIVE or posedge IMU_TAPS[5]) if (!IMU_ACTIVE) IMU_LATE_ACKN<= 1'b0; else IMU_LATE_ACKN<= 1'b1; always @ (negedge IMU_LATE_ACKN or posedge IMU_TAPS[4]) if (!IMU_LATE_ACKN) IMU_SCLK<= 1'b1; else IMU_SCLK<= ~IMU_SCLK; always @ (negedge IMU_SCLK) IMU_MOSI_REVA <= IMU_NMOSI; task send_serial_bit; input [7:0] data_byte; reg [7:0] d; begin RS232_SENDING_BYTE <= 1; d <= data_byte; wait (axi_hclk); wait (~axi_hclk); // SERIAL_BIT should be 1 here // Send start bit SERIAL_BIT <= 1'b0; repeat (IMU_GPS_BIT_PERIOD) begin wait (axi_hclk); wait (~axi_hclk); end // Send 8 data bits, LSB first repeat (8) begin SERIAL_BIT <= d[0]; #1 d[7:0] <= {1'b0,d[7:1]}; repeat (IMU_GPS_BIT_PERIOD) begin wait (axi_hclk); wait (~axi_hclk); end end // Send stop bit SERIAL_BIT <= 1'b1; RS232_SENDING_BYTE <= 0; // before stop bit repeat (IMU_GPS_BIT_PERIOD) begin wait (axi_hclk); wait (~axi_hclk); end end endtask task send_serial_pause; begin RS232_SENDING_PAUSE <= 1; wait (axi_hclk); wait (~axi_hclk); SERIAL_BIT <= 1'b1; repeat (16) begin repeat (IMU_GPS_BIT_PERIOD) begin wait (axi_hclk); wait (~axi_hclk); end end RS232_SENDING_PAUSE <= 0; end endtask // SERIAL_DATA_FD=$fopen("gps_data.dat","r"); task send_serial_line; integer char; begin char=0; while (!$feof (SERIAL_DATA_FD) && (char != 'h0a)) begin char=$fgetc(SERIAL_DATA_FD); send_serial_bit(char); end end endtask `endif endmodule module oneshot(trigger, out); input trigger; output out; reg out; event start; parameter duration=4000; initial out= 0; always @ (posedge trigger) begin disable timeout; #0 -> start; end always @start begin : timeout out = 1; # duration out = 0; end endmodule module dly5taps (dly_in, dly_out); input dly_in; output [5:1] dly_out; reg [5:1] dly_out; parameter dly=6; // delay per tap, ns always @ (dly_in) # dly dly_out[1] <= dly_in; always @ (dly_out[1]) # dly dly_out[2] <= dly_out[1]; always @ (dly_out[2]) # dly dly_out[3] <= dly_out[2]; always @ (dly_out[3]) # dly dly_out[4] <= dly_out[3]; always @ (dly_out[4]) # dly dly_out[5] <= dly_out[4]; endmodule
logger/event_logger.v +46 −24 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ module event_logger#( // byte-parallel timestamps from 4 sensors channels (in triggered mode all are the same, different only in free running mode) // each may generate logger event, channel number encoded in bits 25:24 of the external microseconds input [3:0] sof_mclk, // start of frame (per-channel) to filter out non-first timestamps input ts_stb_chn0, // @mclk 1 clock before ts_rcv_data is valid input [7:0] ts_data_chn0, // @mclk byte-wide serialized timestamp message received or local Loading Loading @@ -133,8 +134,8 @@ module event_logger#( reg we_config_gps; // bits 6:3, 7 - enable - {ext,invert, slot[1:0]} slot==0 - disable reg we_config_msg; // bits 12:8,13 - enable - {invert,extinp[3:0]} extinp[3:0]=='hf' - disable reg we_config_syn; // bit 14, 15 - enable - enable logging external timestamps reg we_config_rst; // bit 14, 15 - enable - enable logging external timestamps reg we_config_debug; // bit 14, 15 - enable - enable logging external timestamps reg we_config_rst; // bit 14, 15 - enable - reset reg we_config_debug; // bit 14, 15 - enable - debug bits set reg we_bitHalfPeriod; Loading @@ -159,7 +160,7 @@ module event_logger#( reg [3:0] config_gps_mclk; reg [4:0] config_msg_mclk; reg [3:0] config_syn_mclk; reg config_rst_mclk; reg config_rst_mclk = 0; reg [3:0] config_debug_mclk; reg [15:0] bitHalfPeriod_mclk; Loading Loading @@ -212,6 +213,8 @@ module event_logger#( wire cmd_we; wire cmd_status; reg [3:0] timestamps_en; // enable timestamp to go through (first after sof) assign ext_en = {{(GPIO_N-5){1'b0}}, (config_imu[1:0]==2'h2)?1'b1:1'b0, 1'b0, Loading Loading @@ -241,6 +244,9 @@ module event_logger#( assign timestamp_request[1]=config_gps[3]? (config_gps[2]?nmea_sent_start:gps_ts_stb):gps_pulse1sec_single; always @ (posedge mclk) begin timestamps_en <= enable_syn_mclk & (sof_mclk | (timestamps_en & ~{ts_stb_chn3, ts_stb_chn2,ts_stb_chn1, ts_stb_chn0})); end // filter gps_pulse1sec always @ (posedge xclk) begin Loading @@ -257,9 +263,24 @@ module event_logger#( gps_pulse1sec_single <= !gps_pulse1sec_denoise[1] && gps_pulse1sec_denoise[0]; end always @ (posedge mclk or posedge mrst) begin // was negedge we_d <= !mrst && cmd_we && !cmd_a; we_imu <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_IMU); we_gps <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_GPS); we_message <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_MSG); we_period <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_PERIOD); we_bit_duration <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_BIT_DURATION); we_bitHalfPeriod<= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_BIT_HALF_PERIOD); we_config_imu <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_IMU]; we_config_gps <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_GPS]; we_config_msg <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_MSG]; we_config_syn <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_SYN]; we_config_rst <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_EN]; we_config_debug <= !mrst && cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_DBG]; end always @ (posedge mclk) begin // was negedge if (cmd_we) cmd_data_r <= cmd_data; // valid next after cmd_we; /* we_d <= cmd_we && !cmd_a; we_imu <= cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_IMU); we_gps <= cmd_we && !cmd_a && (ctrl_addr[6:5] == LOGGER_PAGE_GPS); Loading @@ -273,6 +294,7 @@ module event_logger#( we_config_syn <= cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_SYN]; we_config_rst <= cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_EN]; we_config_debug <= cmd_we && !cmd_a && (ctrl_addr[6:0] == LOGGER_CONFIG) && cmd_data[LOGGER_CONF_DBG]; */ if (we_config_imu) config_imu_mclk[1:0] <= cmd_data_r[LOGGER_CONF_IMU - 1 -: LOGGER_CONF_IMU_BITS]; // bits 1:0, 2 - enable slot[1:0] if (we_config_gps) config_gps_mclk[3:0] <= cmd_data_r[LOGGER_CONF_GPS - 1 -: LOGGER_CONF_GPS_BITS]; // bits 6:3, 7 - enable - {ext,inver, slot[1:0]} slot==0 - disable Loading Loading @@ -405,14 +427,14 @@ fixed-length de-noise circuitry with latency 256*T(xclk) (~3usec) .xclk (xclk), // half frequency (80 MHz nominal) .mrst (mrst), // @mclk - sync reset .xrst (xrst), // @xclk - sync reset .en_chn_mclk (enable_syn_mclk), // enable module operation, if 0 - reset .ts_stb_chn0 (ts_stb_chn0), // input .en_chn_mclk (enable_syn_mclk), // input[3:0] enable module operation, if 0 - reset .ts_stb_chn0 (ts_stb_chn0 && timestamps_en[0]), // input .ts_data_chn0 (ts_data_chn0), // input[7:0] .ts_stb_chn1 (ts_stb_chn1), // input .ts_stb_chn1 (ts_stb_chn1 && timestamps_en[1]), // input .ts_data_chn1 (ts_data_chn1), // input[7:0] .ts_stb_chn2 (ts_stb_chn2), // input .ts_stb_chn2 (ts_stb_chn2 && timestamps_en[2]), // input .ts_data_chn2 (ts_data_chn2), // input[7:0] .ts_stb_chn3 (ts_stb_chn3), // input .ts_stb_chn3 (ts_stb_chn3 && timestamps_en[3]), // input .ts_data_chn3 (ts_data_chn3), // input[7:0] .ts (timestamp_request[2]), // timestamop request .rdy (channel_ready[2]), // data ready Loading
logger/imu_exttime393.v +34 −16 Original line number Diff line number Diff line Loading @@ -73,15 +73,17 @@ module imu_exttime393( reg [ 4:0] raddr; wire en_mclk = |en_chn_mclk; wire [3:0] ts_stb = {ts_stb_chn3, ts_stb_chn2, ts_stb_chn1, ts_stb_chn0}; wire [3:0] ts_got; // timestamp transferred to the channel FIFO reg en; reg rd_stb_r; reg rd_start; // 1 xclk pulse at the readout start wire rd_start_mclk; reg ts_full; // internal 4 x 16 fifo is full (or getting full) reg ts_pend; // ts fifo waiting to be rdead out reg [3:0] in_full; // input fifo has (or is acquiring) timestamp wire pre_copy_w; reg [1:0] copy_selected; // copying from the winner of 4 input fifos to the x16 output fifo reg [1:0] copy_selected; // copying from the winner of 4 input FIFOs to the x16 output fifo reg copy_started; reg [2:0] copy_cntr; // byte counter for copying reg [1:0] sel_chn; // selected channel Loading @@ -90,11 +92,11 @@ module imu_exttime393( wire [3:0] chn_pri_w; wire [1:0] chn_enc_w; reg [15:0] ts_ram [0:3]; // inner timestamp x16 memory that receives timestamp from one of the 4 input channel fifos reg [15:0] ts_ram [0:3]; // inner timestamp x16 memory that receives timestamp from one of the 4 input channel FIFOs wire [31:0] dout_chn; wire [7:0] copy_data; // data from the selected input fifos reg [7:0] copy_data_r; // low byte of the timestamp data being copied from one of the input fifos to the ts_ram reg [7:0] copy_data_r; // low byte of the timestamp data being copied from one of the input FIFOs to the ts_ram reg rd_stb_mclk; assign chn_pri_w = {in_full[3] & ~(|in_full[2:0]), in_full[2] & ~(|in_full[1:0]), in_full[1] & ~in_full[0], Loading @@ -110,14 +112,24 @@ module imu_exttime393( always @ (posedge mclk) begin copy_started <= pre_copy_started; rd_stb_mclk <= rd_stb; if (!en_mclk) ts_full <= 0; else if (pre_copy_started) ts_full <= 1; // turns on before in_full[*] - || will have no glitches else if (rd_start_mclk) ts_full <= 0; // else if (rd_start_mclk) ts_full <= 0; else if (!ts_pend && !rd_stb_mclk) ts_full <= 0; if (!en_mclk) ts_pend <= 0; else if (pre_copy_started) ts_pend <= 1; else if (rd_stb_mclk) ts_pend <= 0; if (!en_mclk) in_full <= 0; else in_full <= en_chn_mclk & (ts_stb | (in_full & ~(chn1hot & {4{copy_started}}))); else in_full <= en_chn_mclk & (ts_got | (in_full & ~(chn1hot & {4{copy_started}}))); copy_selected <= {copy_selected[0], pre_copy_w | (copy_selected[0] & ~(©_cntr[2:1]))}; // off at count 6 // copy_selected <= {copy_selected[0], (|en_chn_mclk) & (pre_copy_w | (copy_selected[0] & ~(©_cntr[2:1])))}; // off at count 6 copy_selected <= {copy_selected[0], (|en_chn_mclk) & (pre_copy_w | (copy_selected[0] & (copy_cntr[2] | ~copy_cntr[1] )))}; // off at count 2 if (pre_copy_w) sel_chn <= chn_enc_w; Loading Loading @@ -145,6 +157,10 @@ module imu_exttime393( else if (rd_stb && (raddr[1:0]==2'h3)) rdy <= 1'b0; end dly_var #(.WIDTH(1),.DLY_WIDTH(4)) ts_got0_i (.clk(mclk),.rst(~en_chn_mclk[0]), .dly(4'h7), .din(ts_stb[0]),.dout(ts_got[0])); dly_var #(.WIDTH(1),.DLY_WIDTH(4)) ts_got1_i (.clk(mclk),.rst(~en_chn_mclk[1]), .dly(4'h7), .din(ts_stb[1]),.dout(ts_got[1])); dly_var #(.WIDTH(1),.DLY_WIDTH(4)) ts_got2_i (.clk(mclk),.rst(~en_chn_mclk[2]), .dly(4'h7), .din(ts_stb[2]),.dout(ts_got[2])); dly_var #(.WIDTH(1),.DLY_WIDTH(4)) ts_got3_i (.clk(mclk),.rst(~en_chn_mclk[3]), .dly(4'h7), .din(ts_stb[3]),.dout(ts_got[3])); timestamp_fifo timestamp_fifo_chn0_i ( Loading @@ -155,7 +171,7 @@ module imu_exttime393( .din (ts_data_chn0), // input[7:0] .aclk (mclk), // input .arst (mrst), // input .advance (ts_stb[0]), // enough time .advance (ts_got[0]), // enough time .rclk (mclk), // input .rrst (mrst), // input .rstb (pre_copy_started && (sel_chn == 2'h0)),// input Loading @@ -170,7 +186,7 @@ module imu_exttime393( .din (ts_data_chn1), // input[7:0] .aclk (mclk), // input .arst (mrst), // input .advance (ts_stb[1]), // enough time .advance (ts_got[1]), // enough time .rclk (mclk), // input .rrst (mrst), // input .rstb (pre_copy_started && (sel_chn == 2'h1)),// input Loading @@ -185,7 +201,7 @@ module imu_exttime393( .din (ts_data_chn2), // input[7:0] .aclk (mclk), // input .arst (mrst), // input .advance (ts_stb[2]), // enough time .advance (ts_got[2]), // enough time .rclk (mclk), // input .rrst (mrst), // input .rstb (pre_copy_started && (sel_chn == 2'h2)),// input Loading @@ -200,7 +216,7 @@ module imu_exttime393( .din (ts_data_chn3), // input[7:0] .aclk (mclk), // input .arst (mrst), // input .advance (ts_stb[3]), // enough time .advance (ts_got[3]), // enough time .rclk (mclk), // input .rrst (mrst), // input .rstb (pre_copy_started && (sel_chn == 2'h3)),// input Loading @@ -208,10 +224,12 @@ module imu_exttime393( ); pulse_cross_clock i_rd_start_mclk (.rst(xrst), .src_clk(xclk), .dst_clk(mclk), .in_pulse(rd_start), .out_pulse(rd_start_mclk),.busy()); // pulse_cross_clock i_rd_start_mclk (.rst(xrst), .src_clk(xclk), .dst_clk(mclk), .in_pulse(rd_start), .out_pulse(rd_start_mclk),.busy()); pulse_cross_clock i_rd_start_mclk (.rst(!en), .src_clk(xclk), .dst_clk(mclk), .in_pulse(rd_start), .out_pulse(rd_start_mclk),.busy()); // generate timestamp request as soon as one of the sub-channels starts copying. That time stamp will be stored for this (ext) channel pulse_cross_clock i_ts (.rst(mrst), .src_clk(mclk), .dst_clk(xclk), .in_pulse(pre_copy_w), .out_pulse(ts),.busy()); // pulse_cross_clock i_ts (.rst(mrst), .src_clk(mclk), .dst_clk(xclk), .in_pulse(pre_copy_w), .out_pulse(ts),.busy()); pulse_cross_clock i_ts (.rst(en_chn_mclk == 0), .src_clk(mclk), .dst_clk(xclk), .in_pulse(pre_copy_w), .out_pulse(ts),.busy()); endmodule