diff --git a/Alchitry_projects/Mojo_v3/source/camera_trigger.luc b/Alchitry_projects/Mojo_v3/source/camera_trigger.luc index 6b19256..3c4dd31 100644 --- a/Alchitry_projects/Mojo_v3/source/camera_trigger.luc +++ b/Alchitry_projects/Mojo_v3/source/camera_trigger.luc @@ -1,24 +1,24 @@ /****************************************************************************** This module generates two TTL signals intended at triggering a camera and - lasers. The camera trigger output can be used directly to trigger a camera, - while the laser trigger output can be processed by a laser_trigger module. + lasers. The fire trigger output can be used directly to trigger a camera, + while the exposure trigger output can be processed by a laser_trigger module. It takes several parameters: * start: the output signals are only generated when start is HIGH, they are 0 otherwise. - * trigger_pulse: pulse length of the camera trigger signal. - * trigger_period: pulse period of the camera trigger signal. - * trigger_exposure: pulse length of the laser trigger signal. - * trigger_delay: delay of the laser trigger signal with respect to the camera - trigger. + * pulse: pulse length of the fire trigger signal. + * readout: period between the end of exposure and the next fire pulse. + * exposure: pulse length of the exposure trigger signal. + * delay: delay of theexposure trigger signal with respect to the fire trigger. Outputs: - * trigger_camera: camera trigger signal. - * trigger_lasers: laser trigger signal, intended to be fed to a laser_trigger - module. + * fire_trigger: camera fire signal. + * exposure_trigger: camera exposure signal, intended to trigger laser_trigger + modules. Example: - <-------------period------------> + readout + <-> <-pulse-> --------- --------- high | | | | @@ -38,17 +38,17 @@ module camera_trigger ( input clk, // clock input rst, // reset input start, - input trigger_pulse[16], // pulse length of the camera trigger - input trigger_period[16], // period of the camera trigger - input trigger_exposure[16], // exposure of a camera frame (for the lasers) - input trigger_delay[16], // delay for the laser exposure - output trigger_camera, - output trigger_lasers + input pulse[20], // pulse length of the camera trigger + input readout[16], // period between the end of the exposure and the next fire + input exposure[20], // exposure of a camera frame (for the lasers) + input delay[16], // delay for the laser exposure + output fire_trigger, + output exposure_trigger ) { - // 16 bits -> maximum of 6.5s with NM_CYCLES = 10000, since clock cycle = 100MHz - const NM_CYCLES = 10000; // convert to NM_CYCLES x 1e-8 = ~100 us - const DELAY_CYCLES = 1000; // ~10 us + // 16 bits -> maximum of 65.535 ms with US_CYCLES = 100, since clock cycle = 100MHz + // 20 bits -> maximum of 1.048575 s + const US_CYCLES = 100; // US_CYCLES x 1e-8 = ~1 us var pulse_cycle; var period_cycle; var exposure_cycle; @@ -56,21 +56,21 @@ module camera_trigger ( .clk(clk){ .rst(rst) { - // If x is the number of bits of trigger_length/trigger_delay/exposure + // If x is the number of bits of pulse/delay/exposure/readout // i.e. Nbits(trigger_length) = X - // Then, we must have Nbits(counter) > log2((2^X-1)*NM_CYCLES+1) - // For X=16 and NM_CYCLES = 10000, it yields Nbits(counter) > 29.3 - // For X=16 and DELAY_CYCLES = 1000, it yields Nbits(counter) > 25.9 - dff counter[30]; // cycles counter - dff delay_counter[26]; // delay counter + // Then, we must have Nbits(counter) > log2((2^X-1)*CYCLES+1) + // x=20 and US_CYCLES=100 => Nbits(counter) > 26.6 + // x=16 and US_CYCLES=100 => Nbits(counter) > 22.6 + dff counter[27]; // cycles counter + dff delay_counter[23]; // delay counter } } always { - pulse_cycle = trigger_pulse*NM_CYCLES; - period_cycle = trigger_period*NM_CYCLES; - exposure_cycle = trigger_exposure*NM_CYCLES; - delay_cycle = trigger_delay*DELAY_CYCLES; + pulse_cycle = pulse*US_CYCLES; + period_cycle = (delay+readout+exposure)*US_CYCLES; + exposure_cycle = exposure*US_CYCLES; + delay_cycle = delay*US_CYCLES; // increase counters until they max out if (!&counter.q){ @@ -87,7 +87,7 @@ module camera_trigger ( } // set output signals - trigger_camera = counter.q < pulse_cycle; - trigger_lasers = delay_counter.q > delay_cycle && counter.q < delay_cycle+exposure_cycle; + fire_trigger = counter.q < pulse_cycle; + exposure_trigger = delay_counter.q > delay_cycle && counter.q < delay_cycle+exposure_cycle; } } diff --git a/Alchitry_projects/Mojo_v3/source/laser_trigger.luc b/Alchitry_projects/Mojo_v3/source/laser_trigger.luc index b4041f9..da6b28b 100644 --- a/Alchitry_projects/Mojo_v3/source/laser_trigger.luc +++ b/Alchitry_projects/Mojo_v3/source/laser_trigger.luc @@ -25,7 +25,7 @@ module laser_trigger ( input rst, // reset input cam_sig, input mod[3], - input dura[16], + input dura[20], input seq[16], input sync[4], output lasersignal @@ -44,10 +44,15 @@ module laser_trigger ( .rst(rst) { dff sig_sync[4]; dff sig_old; - dff count_sig[23]; + dff count_sig[27]; }} always { + // If x is the number of bits of dura + // i.e. Nbits(dura) = X + // Then, we must have Nbits(counter) > log2((2^X-1)*NM_CYCLES+1) + // X=20, NM_CYCLES=100 => Nbits(count_sig) > 26.6 + // X=16, NM_CYCLES=100 => Nbits(count_sig) > 22.6 plength = dura*NM_CYCLES; sig_sync.d[0] = cam_sig; diff --git a/Alchitry_projects/Mojo_v3/source/mojo_top.luc b/Alchitry_projects/Mojo_v3/source/mojo_top.luc index 19d8963..c64ece8 100644 --- a/Alchitry_projects/Mojo_v3/source/mojo_top.luc +++ b/Alchitry_projects/Mojo_v3/source/mojo_top.luc @@ -68,17 +68,17 @@ module mojo_top ( const ADDR_DUR = NUM_LASERS; // 8 const ADDR_SEQ = ADDR_DUR+NUM_LASERS; // 16 const ADDR_TTL = ADDR_SEQ+NUM_LASERS; // 24 - const ADDR_SERVOS = ADDR_TTL+NUM_TTL; // 29 - const ADDR_PWM = ADDR_SERVOS+NUM_SERVOS; // 36 + const ADDR_SERVOS = ADDR_TTL+NUM_TTL; // 28 + const ADDR_PWM = ADDR_SERVOS+NUM_SERVOS; // 35 - const ADDR_ACTIVE_TRIGGER = ADDR_PWM+NUM_PWM; // 41 - const ADDR_START_TRIGGER = ADDR_ACTIVE_TRIGGER+1; // 42 - const ADDR_CAM_PULSE = ADDR_START_TRIGGER+1; // 43 - const ADDR_CAM_PERIOD = ADDR_CAM_PULSE+1; // 44 - const ADDR_CAM_EXPO = ADDR_CAM_PERIOD+1; // 45 - const ADDR_LASER_DELAY = ADDR_CAM_EXPO+1; // 46 + const ADDR_ACTIVE_TRIGGER = ADDR_PWM+NUM_PWM; // 40 + const ADDR_START_TRIGGER = ADDR_ACTIVE_TRIGGER+1; // 41 + const ADDR_CAM_PULSE = ADDR_START_TRIGGER+1; // 42 + const ADDR_CAM_READOUT = ADDR_CAM_PULSE+1; // 43 + const ADDR_CAM_EXPO = ADDR_CAM_READOUT+1; // 44 + const ADDR_LASER_DELAY = ADDR_CAM_EXPO+1; // 45 - const ADDR_AI = ADDR_LASER_DELAY+1;// 47 + const ADDR_AI = ADDR_LASER_DELAY+1;// 46 const ADDR_VERSION = 200; const ADDR_ID = 201; @@ -103,17 +103,17 @@ module mojo_top ( signal_sync framesync; // to synchronize all lasers on the same frame counter dff sequence[NUM_LASERS][16]; - dff duration[NUM_LASERS][16]; + dff duration[NUM_LASERS][20]; dff mode[NUM_LASERS][3]; // main trigger - camera_trigger trigger; + camera_trigger camera; dff active_trigger; dff start_trigger; - dff cam_pulse[16]; // pulse length of the camera trigger signal - dff cam_period[16]; // period of the camera trigger signal - dff cam_exposure[16]; // camera exposure - dff laser_delay[16]; // laser trigger delay + dff cam_pulse[20]; // pulse length of the camera fire signal + dff cam_readout[16]; // period between two frames + dff cam_exposure[20]; // camera exposure + dff cam_delay[16]; // laser trigger delay // ttls dff ttl[NUM_TTL]; @@ -181,7 +181,7 @@ module mojo_top ( if (reg.regOut.address < ADDR_MODE+NUM_LASERS) { // Laser modes mode.d[reg.regOut.address-ADDR_MODE] = reg.regOut.data[2:0]; } else if (reg.regOut.address < ADDR_DUR+NUM_LASERS) { // Laser duration - duration.d[reg.regOut.address-ADDR_DUR] = reg.regOut.data[15:0]; + duration.d[reg.regOut.address-ADDR_DUR] = reg.regOut.data[19:0]; } else if (reg.regOut.address < ADDR_SEQ+NUM_LASERS) { // Laser sequence sequence.d[reg.regOut.address-ADDR_SEQ] = reg.regOut.data[15:0]; } else if (reg.regOut.address < ADDR_TTL+NUM_TTL){ // TTL @@ -197,13 +197,13 @@ module mojo_top ( } else if (reg.regOut.address == ADDR_START_TRIGGER){ // Camera trigger start start_trigger.d = reg.regOut.data[0]; } else if (reg.regOut.address == ADDR_CAM_PULSE){ // Camera trigger length - cam_pulse.d = reg.regOut.data[15:0]; - } else if (reg.regOut.address == ADDR_CAM_PERIOD){ // Camera trigger period - cam_period.d = reg.regOut.data[15:0]; + cam_pulse.d = reg.regOut.data[19:0]; + } else if (reg.regOut.address == ADDR_CAM_READOUT){ // Camera inter frame period + cam_readout.d = reg.regOut.data[15:0]; } else if (reg.regOut.address == ADDR_CAM_EXPO){ // Exposure length - cam_exposure.d = reg.regOut.data[15:0]; + cam_exposure.d = reg.regOut.data[19:0]; } else if (reg.regOut.address == ADDR_LASER_DELAY){ // Laser trigger delay - laser_delay.d = reg.regOut.data[15:0]; + cam_delay.d = reg.regOut.data[15:0]; } } else { // read if (reg.regOut.address < ADDR_MODE+NUM_LASERS) { // Laser modes @@ -233,15 +233,15 @@ module mojo_top ( } else if (reg.regOut.address == ADDR_CAM_PULSE) { // Camera trigger length reg.regIn.data = cam_pulse.q; reg.regIn.drdy = 1; - } else if (reg.regOut.address == ADDR_CAM_PERIOD) { // Camera trigger period - reg.regIn.data = cam_period.q; + } else if (reg.regOut.address == ADDR_CAM_READOUT) { // Camera inter frame period + reg.regIn.data = cam_readout.q; reg.regIn.drdy = 1; } else if (reg.regOut.address == ADDR_CAM_EXPO) { // Camera exposure length reg.regIn.data = cam_exposure.q; reg.regIn.drdy = 1; } else if (reg.regOut.address == ADDR_LASER_DELAY) { // Laser trigger delay - reg.regIn.data = laser_delay.q; - reg.regIn.drdy = 1; + reg.regIn.data = cam_delay.q; + reg.regIn.drdy = 1; } else if (reg.regOut.address < ADDR_AI+NUM_ANALOG) { // Analog input reg.regIn.data = adc.value[reg.regOut.address-ADDR_AI]; reg.regIn.drdy = 1; @@ -271,34 +271,33 @@ module mojo_top ( if(active_trigger.q){ // active trigger: the FPGA triggers both camera and lasers // parameters from serial communication - trigger.start = start_trigger.q; - trigger.trigger_pulse = cam_pulse.q; - trigger.trigger_period = cam_period.q; - trigger.trigger_exposure = cam_exposure.q; - trigger.trigger_delay = laser_delay.q; + camera.start = start_trigger.q; + camera.pulse = cam_pulse.q; + camera.readout = cam_readout.q; + camera.exposure = cam_exposure.q; + camera.delay = cam_delay.q; // feed the exposure signal to the lasers - framesync.camera = trigger.trigger_lasers; // inter-laser sync module - l.cam_sig = NUM_LASERSx{trigger.trigger_lasers}; - + framesync.camera = camera.exposure_trigger; // inter-laser sync module + l.cam_sig = NUM_LASERSx{camera.exposure_trigger}; // trigger camera - camera_out = trigger.trigger_camera; + camera_out = camera.fire_trigger; led[0] = start_trigger.q; - led[1] = trigger.trigger_camera; - led[2] = trigger.trigger_lasers; + led[1] = camera.fire_trigger; + led[2] = camera.exposure_trigger; led[3] = l.lasersignal[0]; led[4] = l.lasersignal[1]; led[5] = l.lasersignal[2]; - led[6] = l.lasersignal[2]; + led[6] = l.lasersignal[3]; } else { // passive trigger: external camera triggers the FPGA/lasers - trigger.start = 0; - trigger.trigger_pulse = 16x{0}; - trigger.trigger_period = 16x{0}; - trigger.trigger_exposure = 16x{0}; - trigger.trigger_delay = 16x{0}; + camera.start = 0; + camera.pulse = 20x{0}; + camera.readout = 16x{0}; + camera.exposure = 20x{0}; + camera.delay = 16x{0}; camera_out = 0;