CamJ
At its core, CamJ simulates the noise and energy consumption of an CMOS Image Sensor (CIS) in seconds under a Frame Per Second (FPS) target. CamJ allow users to describe the CIS hardware, both the analog and digital components, and the (imaging, image processing, and computer vision) algorithm to be executed on the CIS using a declarative interface in Python. Under the surface, CamJ models the interplay across main structures of a computational CIS pipeline: pixel sensing → analog processing → digital processing. Thus, CamJ enables end-to-end modeling and optimization of the CIS architecture from photon ingestion to semantic results.
This project is under active development.
Cite Us
To know more about CamJ, please check out our paper and cite us:
@inproceedings{ma2023camj,
title={CamJ: Enabling System-Level Energy Modeling and Architectural Exploration for In-Sensor Visual Computing},
author={Ma, Tianrui and Feng, Yu and Zhang, Xuan and Zhu, Yuhao},
booktitle={Proceedings of the 50th Annual International Symposium on Computer Architecture},
year={2023}
}
What is CamJ Useful For?
CamJ is meant to be used for system-level exploration after each component design is sketched out; an analogy would be Systems-on-a-Chip (SoC) vs. accelerator design. Before system-level exploration, a team usually has at hand a range of component-level designs, which could be licensed Intellectual Property (IP) blocks, reference designs from the literature, or earlier designs from other teams in the organization; in all cases the component-level energy behavior is known or can be modeled using external tools.
CamJ helps designers make design decisions when assembling the individual (digital and analog) components into an optimal system. Ideally, a designer uses CamJ to estimate the system energy given initial designs of individual components; using the estimation, a designer can iteratively refine the components/system design. For instance, CamJ can identify energy bottlenecks and guide the re-design of corresponding components. Orthogonally, a designer can use CamJ to explore optimal mapping and partitioning of the algorithms between analog vs. digital domains or in vs. off CIS to minimize overall system energy under performance targets.
CamJ is not a synthesis tool; it does not generate a digital accelerator (or analog circuits for that matter), which is the goal of a High-Level Synthesis (HLS) tool. Rather, CamJ can be used in conjunction with HLS: one could use HLS to first generate an accelerator and then use CamJ to explore, in the bigger system, how/whether that accelerator would fit in a computational CIS to maximize end-to-end application gains.
Tutorial
The best way to learn how to use CamJ is to go through this tutorual. We host the tutorial on a Google Colab notebook, which provides a step-by-step walk-through of how to use CamJ APIs to describe a simple computational CIS, both its software and hardware, and then perform functional (noise) and energy simulations.
Want More Examples?
In CamJ repository, we have more examples of existing image sensor designs from recent literature.
What Are Supported by CamJ?
CamJ provides a high-level interface that describes some commonly-used analog and digital structures. Users can directly plug-in CamJ APIs in their image sensor designs. Here we summarize these hareware structures.
Analog Domain
The figure shown below presents all the analog components that are supported by CamJ.

In this figure, the top level shows the algorithmic operations that are currently supported in CamJ. The second level shows the analog components that support the algorithmic operations at the top level. The bottom level shows the major basic analog components that compose the analog components at the second level. Both the energy and noise modeling in CamJ are performed in the analog components at the bottom level. The energy and noise modeling at the second level are composed by the bottom level analog component.
CamJ Analog Interface
To make CamJ easy to use, we expose the second-level as our standard interface. Expert users can also extend our standard interface to implement more complex analog compoenent in their design. In later Sections, we also introduce how to extend our standard interface.
The table below shows the overview of analog components at the second level:
Component Name |
Functionality | Building Blocks |
Schematic | |
---|---|---|---|---|
Algorithmic Ops |
Mathematic Expression |
|||
3T Active Pixel Sensor (3T-APS) |
Sensing | - | Photodiode (PD), Floating Diffusion (FD), Source Follower (SF) |
![]() |
4T Active Pixel Sensor (4T-APS) |
Sensing | - | Photodiode (PD), Floating Diffusion (FD), Source Follower (SF) |
![]() |
Digital Pixel Sensor (DPS) |
Sensing | - | Photodiode (PD), Floating Diffusion (FD), Source Follower (SF), ADC |
![]() |
Pulse Width Modulation Pixel (PWM Pixel) |
Sensing | - | Photodiode (PD), Ramp, Comparator (CMP) |
![]() |
Analog-to-Digital Convertor (ADC) |
Conversion, Quanization |
- | ADC | ![]() |
Digital-to-Current Convertor (DAC) |
Conversion | - | DAC | ![]() |
Comparator | Compare | (In1 > In2) ? In1 : 0 | Comparator (CMP) | ![]() |
AnalogReLU | ReLU | (In > 0) ? In : 0 | Comparator (CMP) | ![]() |
Passive Average |
Average | ![]() |
Passive Switched Capacitor Array (PSCA), Source Follower (SF) |
![]() |
Active Average |
Average | ![]() |
Amplifier (AMP) | - |
Passive Binning |
Binning | ![]() |
Passive Switched Capacitor Array (PSCA), Source Follower (SF) |
![]() |
Active Binning |
Binning | ![]() |
Amplifier (AMP) | - |
Voltage-to-Voltage Convolution |
Convolution | ![]() |
Passive Switched Capacitor Array (PSCA), Source Follower (SF) |
![]() |
Time-to-Voltage Convolution |
Convolution | ![]() |
Current Mirror (CM), Passive Analog Memory (PAM) |
![]() |
Binary Weight Convolution |
Convolution | ![]() |
Amplifier (AMP) | ![]() |
Passive Analog Memory |
Store | - | Passive Analog Memory (PAM) | ![]() |
Acitve Analog Memory |
Store | - | Active Analog Memory (AAM) | ![]() |
Max Pool | Max Pooling | ![]() |
Amplifier (AMP) | ![]() |
Max Voltage | Max | ![]() |
Amplifier (AMP) | ![]() |
Adder | Add | ![]() |
Amplifier (AMP) | ![]() |
Subtractor | Subtraction | ![]() |
Amplifier (AMP) | ![]() |
Absolute Difference | Absolute Difference | ![]() |
Amplifier (AMP) Comparator (CMP) |
![]() |