Skip to content

Commit

Permalink
v3.1-beta
Browse files Browse the repository at this point in the history
  • Loading branch information
jdeschamps committed Mar 22, 2022
1 parent 105074e commit c407046
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 76 deletions.
64 changes: 32 additions & 32 deletions Alchitry_projects/Mojo_v3/source/camera_trigger.luc
Original file line number Diff line number Diff line change
@@ -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
| | | |
Expand All @@ -38,39 +38,39 @@ 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;
var delay_cycle;

.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){
Expand All @@ -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;
}
}
9 changes: 7 additions & 2 deletions Alchitry_projects/Mojo_v3/source/laser_trigger.luc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
83 changes: 41 additions & 42 deletions Alchitry_projects/Mojo_v3/source/mojo_top.luc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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];
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit c407046

Please sign in to comment.