In this repository there are some image processing algorithms implemented using C and Verilog, and then use Python3 to compare the result whether there is any difference.
- Table of Contents
- Contents
- Load Image
- RAW to BGR
- RAW to Gray
- Image Downscaling
- Planar BGR buffer
- Planar gray buffer
- BGR to Gray
- Binarization
- Image Vertical Flip
- Image Horizontal Flip
- Image Dilation
- Image Erosion
- Connected Components
- Image Histogram
- Histogram Equalization
- Mean Filter
- Median Filter
- Gaussian Blur Filter
- Sobel Filter
- Laplacian Filter
- Quick Test
- Batch synthesis (Design Compiler)
- Image Processing Flow
- Tools
Read image from BMP (bitmap) file, and then write it into another.
Convert 8-bit-per-channel RGB interleaved RAW (256×256×3 bytes) to 24-bit BGR BMP. After packing pixels, applies the same vertical flip (row swap) as Image Vertical Flip so the result matches BMP scan order (avoids upside-down output).
Read 8-bit grayscale RAW (256×256 bytes) and write 24-bit BMP with B=G=R per pixel (same visual style as BGR→Gray output). Uses the same vertical flip as Image Vertical Flip for correct BMP orientation.
Downscale 256×256 → 128×128 by 2×2 box averaging each BGR channel (same rounding as RTL). BMP header fields are rewritten for the smaller image.
BMP_ROM → planar B/G/R SRAMs → PLANAR_ALGO_BGR_IDENTITY (or custom) → BGR merge → output RAM → BMP file. 24 bpp file order is B,G,R. TB mux priority: LOAD > ALGO > MERGE read.
Same planar pipeline as planar_bgr: load → PLANAR_GRAY_ALGO_IDENTITY → merge. One gray plane (Y=(30B+150G+76R)\gg 8), then B=G=R=Y to 24 bpp output. RTL: make vs_rtl (VCS).
Read image from BMP (bitmap) file, and then convert it (BGR image) to grayscale.
Read image from BMP (bitmap) file, and then convert it (BGR image) to grayscale. Finally, set pixels to white or black determined by threshold.
Vertical flip (swap top and bottom rows of the raster). This is not left–right mirroring; it matches the row reordering needed when RAW is scanned top-down but BMP stores the first row as the bottom of the image.
Horizontal flip (left–right mirror): each row’s BGR pixels are reversed. Unlike vertical flip, row order is unchanged.
Apply 3x3 dilation on a binarized grayscale image.
Apply 3x3 erosion on a binarized grayscale image.
Label connected components (4-connectivity) on a binarized image.
Compute grayscale histogram from a grayscale 24-bit BMP (lena256.bmp, B=G=R) and render it as a BMP.
Equalize grayscale histogram on a grayscale 24-bit BMP (lena256.bmp, B=G=R) to enhance contrast.
Read image from BMP (bitmap) file, and then use mean filter to blur image.
Read image with salt and pepper noise from BMP (bitmap) file, and then use median filter to remove noise.
Apply a 3×3 Gaussian blur separately on B, G, and R; output is a color 24-bit BMP.
Detect edges with Sobel operator on a grayscale image.
Detect edges with 3x3 Laplacian operator on a grayscale image.
planar_bgr/planar_gray: each planarBMP_LWORD_RAMport is muxed with priority LOAD (byte write) → algorithm (byte write) → merge (address only,wen=0) so only one writer drives the plane per cycle.- Other Verilog demos (e.g. mean filter, Sobel): a single input buffer uses
load_done ? algo_ram_addr : load_ram_addr(and disables load word-enables after load). That is the same sequential load then algorithm idea without planar merge.
run_all_content_rtl.sh runs, for each module in order: C build and run, RTL simulation (make vs_rtl with VCS by default, or make ivl_rtl / make irun_rtl), and compare.py when present. --rtl-tool accepts vcs (default, runs vs_rtl), vs (alias for vcs), ivl (Icarus), or irun. The name iverilog is accepted as an alias for ivl (including RTL_TOOL=iverilog in the environment).
run_all_content_gate.sh does the same flow with gate-level simulation only: make vcs_gate or make irun_gate. --rtl-tool must be vcs (default) or irun (no Icarus gate target).
Place test assets under each module (e.g. lena256.bmp, raw_to_bgr/lena256_rgb.raw). If median_filter/lena256_noise.bmp is missing, the scripts try to generate it with add_noise.py from lena256.bmp. On failure, they print how many steps failed and a list of them.
cd Image_Processing_in_C_and_Verilog
# RTL (default: vcs → make vs_rtl)
./run_all_content_rtl.sh
./run_all_content_rtl.sh --rtl-tool vs
./run_all_content_rtl.sh --rtl-tool ivl
./run_all_content_rtl.sh --rtl-tool irun
RTL_TOOL=ivl ./run_all_content_rtl.sh
RTL_TOOL=irun ./run_all_content_rtl.sh
# Gate (default: vcs → make vcs_gate)
./run_all_content_gate.sh
./run_all_content_gate.sh --rtl-tool irun
RTL_TOOL=irun ./run_all_content_gate.sh
# C only: skip simulation and compare.py
./run_all_content_rtl.sh --skip-rtl
./run_all_content_gate.sh --skip-rtl
RUN_RTL=0 ./run_all_content_rtl.sh
# Single module only (directory name, e.g. median_filter)
./run_all_content_rtl.sh --only median_filter
./run_all_content_gate.sh --only median_filter
# Usage
./run_all_content_rtl.sh --help
./run_all_content_gate.sh --helprun_all_content_syn.sh runs make syn in each module’s RTL/ directory, in the same order as Contents. This invokes Synopsys Design Compiler (dc_shell + syn.tcl per module). It does not run C, simulation, or compare.py. On failure, the script prints the failure count and a list (same style as run_all_content_rtl.sh).
cd Image_Processing_in_C_and_Verilog
./run_all_content_syn.sh
./run_all_content_syn.sh --only binarization
./run_all_content_syn.sh --help%%{
init: {
'theme': 'neutral',
'themeVariables': {
'textColor': '#000000',
'noteTextColor' : '#000000',
'fontSize': '20px'
}
}
}%%
flowchart LR
b0[ ] --- b2[ ] --- b4[ ] --- ProcessingFlow --- b1[ ] --- b3[ ] --- b5[ ]
style b0 stroke-width:0px, fill: #FFFFFF00, color:#FFFFFF00
style b1 stroke-width:0px, fill: #FFFFFF00
style b2 stroke-width:0px, fill: #FFFFFF00
style b3 stroke-width:0px, fill: #FFFFFF00
style b4 stroke-width:0px, fill: #FFFFFF00
style b5 stroke-width:0px, fill: #FFFFFF00, color:#FFFFFF00
linkStyle 0 stroke-width:0px
linkStyle 1 stroke-width:0px
linkStyle 2 stroke-width:0px
linkStyle 3 stroke-width:0px
linkStyle 4 stroke-width:0px
linkStyle 5 stroke-width:0px
subgraph ProcessingFlow
direction TB
style ProcessingFlow fill:#ffffff00, stroke-width:0px
direction TB
A[Put BMP image to ROM]
A --> B[Read BMP Header from ROM]
B --> C[Write BMP Header to RAM]
C --> D[Read BMP Pixel Data from ROM]
D --> E[Computer Vision Algorihtm]
E --> F[Write BMP Pixel Data to RAM]
style A fill:#74c2b5,stroke:#000000,stroke-width:4px
style B fill:#f8cecc,stroke:#000000,stroke-width:4px
style C fill:#fff2cc,stroke:#000000,stroke-width:4px
style D fill:#cce5ff,stroke:#000000,stroke-width:4px
style E fill:#fa6800,stroke:#000000,stroke-width:4px
style F fill:#ff6666,stroke:#000000,stroke-width:4px
end
- GNU Compiler Collection
- Python3
- Synopsys VCS (
make vs_rtlin each module’sRTL/) - Icarus Verilog (
make ivl_rtl) - Cadence irun (
make irun_rtl) - Synopsys Verdi
- GTKWave
- Synopsys Design Compile
- TSMC 0.13µm (Not provide in this repository)





































