feat(architecture): add CAM hardware block design diagram

- Add docs/architecture/cam_hardware_block_design.drawio
- Diagram illustrates CAM top-level architecture including:
  - Host write path with write-priority half-duplex arbiter
  - Write noise injector with Bernoulli flip mask
  - Banked CAM storage (8 BRAM banks × 512 depth)
  - 8-lane match engine pipeline with popcount
  - Top-K tracker and result serializer
- Supports documentation for 4096-row × 512-bit hash CAM design
This commit is contained in:
2026-05-28 12:08:10 +08:00
parent acf0c75132
commit 715a2c2ed6

View File

@@ -0,0 +1,95 @@
<mxfile host="Electron" agent="opencode">
<diagram id="cam-hardware-block-design" name="CAM Hardware Block Design">
<mxGraphModel dx="1405" dy="906" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1280" pageHeight="720" background="none" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="title" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=28;fontStyle=1;fontColor=#1B4332;" value="CAM Hardware Architecture" vertex="1">
<mxGeometry height="40" width="480" x="400" y="180" as="geometry" />
</mxCell>
<mxCell id="subtitle" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;fontColor=#52796F;" value="4096 rows · 512-bit hashes · 8 lanes · Top-K serial result · optional 1% write noise" vertex="1">
<mxGeometry height="28" width="650" x="315" y="220" as="geometry" />
</mxCell>
<mxCell id="cam_top" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#D8F3DC;strokeColor=#2D6A4F;fontColor=#1B4332;fontStyle=1;" value="cam_top&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;write-priority half-duplex arbiter&lt;/font&gt;" vertex="1">
<mxGeometry height="270" width="200" x="50" y="260" as="geometry" />
</mxCell>
<mxCell id="host_write" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#E9F5DB;strokeColor=#74A57F;fontColor=#1B4332;" value="Host Write&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;wr_valid / wr_ready&lt;/font&gt;" vertex="1">
<mxGeometry height="62" width="180" x="60" y="285" as="geometry" />
</mxCell>
<mxCell id="query_in" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#E0FBFC;strokeColor=#3D8C95;fontColor=#1B4965;" value="Query Input&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;query_hash&lt;/font&gt;" vertex="1">
<mxGeometry height="62" width="180" x="60" y="445" as="geometry" />
</mxCell>
<mxCell id="write_noise" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#F7E7C6;strokeColor=#B08968;fontColor=#5C4033;" value="Write Noise Injector&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;cam_write_noise&lt;br&gt;Bernoulli flip mask&lt;/font&gt;" vertex="1">
<mxGeometry height="76" width="190" x="310" y="278" as="geometry" />
</mxCell>
<mxCell id="storage" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#B7E4C7;strokeColor=#2D6A4F;fontColor=#1B4332;fontStyle=1;" value="Banked CAM Storage&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;cam_core_banked&lt;br&gt;8 BRAM banks × 512 depth&lt;/font&gt;" vertex="1">
<mxGeometry height="76" width="210" x="570" y="278" as="geometry" />
</mxCell>
<mxCell id="read_noise" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#D8F3DC;strokeColor=#40916C;fontColor=#1B4332;" value="Read Path / Noise Stage&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;cam_read_noise&lt;br&gt;registered lane response&lt;/font&gt;" vertex="1">
<mxGeometry height="76" width="200" x="850" y="278" as="geometry" />
</mxCell>
<mxCell id="match_engine" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#A9D6E5;strokeColor=#2A6F97;fontColor=#123047;fontStyle=1;" value="Match Engine Pipeline&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;batch scan control&lt;br&gt;rd_req base rows&lt;/font&gt;" vertex="1">
<mxGeometry height="82" width="190" x="310" y="435" as="geometry" />
</mxCell>
<mxCell id="popcount" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#CAE9FF;strokeColor=#468FAF;fontColor=#123047;" value="8× XNOR + Popcount&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;512-bit similarity score&lt;/font&gt;" vertex="1">
<mxGeometry height="70" width="210" x="570" y="441" as="geometry" />
</mxCell>
<mxCell id="fifo_topk" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#D9ED92;strokeColor=#76A21E;fontColor=#344E1F;" value="Candidate FIFO + Top-K Tracker&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;rank candidates, keep best K&lt;/font&gt;" vertex="1">
<mxGeometry height="70" width="220" x="840" y="441" as="geometry" />
</mxCell>
<mxCell id="serializer" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#E9F5DB;strokeColor=#74A57F;fontColor=#1B4332;" value="Result Serializer&lt;br&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;rank / row / score / last&lt;/font&gt;" vertex="1">
<mxGeometry height="62" width="220" x="840" y="555" as="geometry" />
</mxCell>
<mxCell id="result_out" parent="1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=14;strokeWidth=2;fillColor=#FFFFFF;strokeColor=#52796F;fontColor=#1B4332;fontStyle=1;" value="Top-K Results" vertex="1">
<mxGeometry height="62" width="130" x="1100" y="555" as="geometry" />
</mxCell>
<mxCell id="note_write" parent="1" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;size=18;strokeWidth=1;fillColor=#FFF7E6;strokeColor=#B08968;fontColor=#5C4033;fontSize=12;" value="Write-time noise is baked into stored rows.&lt;br&gt;Non-zero rate runs full mask generation per write." vertex="1">
<mxGeometry height="74" width="250" x="280" y="549" as="geometry" />
</mxCell>
<mxCell id="note_query" parent="1" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;size=18;strokeWidth=1;fillColor=#EFFAF6;strokeColor=#40916C;fontColor=#1B4332;fontSize=12;" value="Query scans banked rows in 8-lane batches,&lt;br&gt;then serializes the Top-K stream." vertex="1">
<mxGeometry height="62" width="250" x="550" y="555" as="geometry" />
</mxCell>
<mxCell id="e_write_noise" edge="1" parent="1" source="host_write" style="endArrow=block;html=1;rounded=0;strokeWidth=2;strokeColor=#74A57F;fontColor=#52796F;" target="write_noise" value="write hash">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_noise_storage" edge="1" parent="1" source="write_noise" style="endArrow=block;html=1;rounded=0;strokeWidth=2;strokeColor=#74A57F;fontColor=#52796F;" target="storage" value="noisy hash">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_query_match" edge="1" parent="1" source="query_in" style="endArrow=block;html=1;rounded=0;strokeWidth=2;strokeColor=#2A6F97;fontColor=#2A6F97;" target="match_engine" value="query">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_match_storage_req" edge="1" parent="1" source="match_engine" style="endArrow=block;html=1;rounded=1;strokeWidth=2;strokeColor=#2A6F97;fontColor=#2A6F97;dashed=1;edgeStyle=orthogonalEdgeStyle;curved=0;" target="storage" value="rd_req">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="405" y="380" />
<mxPoint x="675" y="380" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_storage_read" edge="1" parent="1" source="storage" style="endArrow=block;html=1;rounded=0;strokeWidth=2;strokeColor=#40916C;fontColor=#40916C;" target="read_noise" value="8 lane rows">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_read_pop" edge="1" parent="1" source="read_noise" style="endArrow=block;html=1;rounded=1;strokeWidth=2;strokeColor=#40916C;fontColor=#40916C;edgeStyle=orthogonalEdgeStyle;curved=0;" target="popcount" value="hashes + row ids">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="950" y="400" />
<mxPoint x="675" y="400" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_match_pop" edge="1" parent="1" source="match_engine" style="endArrow=block;html=1;rounded=0;strokeWidth=2;strokeColor=#2A6F97;fontColor=#2A6F97;" target="popcount" value="query hash">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_pop_fifo" edge="1" parent="1" source="popcount" style="endArrow=block;html=1;rounded=0;strokeWidth=2;strokeColor=#468FAF;fontColor=#2A6F97;" target="fifo_topk" value="scores">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_fifo_serializer" edge="1" parent="1" source="fifo_topk" style="endArrow=block;html=1;rounded=0;strokeWidth=2;strokeColor=#76A21E;fontColor=#344E1F;" target="serializer" value="top K">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_serializer_out" edge="1" parent="1" source="serializer" style="endArrow=block;html=1;rounded=0;strokeWidth=2;strokeColor=#52796F;" target="result_out" value="">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>