commit fd323b44e1e03913c4e3ef2112b1dbbbc061c7f7 Author: Dennis Brentjes Date: Fri Jan 7 23:15:38 2022 +0100 Initial commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..722d5e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode diff --git a/SP1-breakout/.gitignore b/SP1-breakout/.gitignore new file mode 100644 index 0000000..2d753e9 --- /dev/null +++ b/SP1-breakout/.gitignore @@ -0,0 +1,5 @@ +*.gbr +*.drl +*.zip +*.gbrjob +fp-info-cache diff --git a/SP1-breakout/SP1-breakout.kicad_pcb b/SP1-breakout/SP1-breakout.kicad_pcb new file mode 100644 index 0000000..35e14c8 --- /dev/null +++ b/SP1-breakout/SP1-breakout.kicad_pcb @@ -0,0 +1,299 @@ +(kicad_pcb (version 20211014) (generator pcbnew) + + (general + (thickness 1.6) + ) + + (paper "A4") + (layers + (0 "F.Cu" signal) + (31 "B.Cu" signal) + (32 "B.Adhes" user "B.Adhesive") + (33 "F.Adhes" user "F.Adhesive") + (34 "B.Paste" user) + (35 "F.Paste" user) + (36 "B.SilkS" user "B.Silkscreen") + (37 "F.SilkS" user "F.Silkscreen") + (38 "B.Mask" user) + (39 "F.Mask" user) + (40 "Dwgs.User" user "User.Drawings") + (41 "Cmts.User" user "User.Comments") + (42 "Eco1.User" user "User.Eco1") + (43 "Eco2.User" user "User.Eco2") + (44 "Edge.Cuts" user) + (45 "Margin" user) + (46 "B.CrtYd" user "B.Courtyard") + (47 "F.CrtYd" user "F.Courtyard") + (48 "B.Fab" user) + (49 "F.Fab" user) + (50 "User.1" user) + (51 "User.2" user) + (52 "User.3" user) + (53 "User.4" user) + (54 "User.5" user) + (55 "User.6" user) + (56 "User.7" user) + (57 "User.8" user) + (58 "User.9" user) + ) + + (setup + (pad_to_mask_clearance 0) + (pcbplotparams + (layerselection 0x00010fc_ffffffff) + (disableapertmacros false) + (usegerberextensions false) + (usegerberattributes true) + (usegerberadvancedattributes true) + (creategerberjobfile true) + (svguseinch false) + (svgprecision 6) + (excludeedgelayer true) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (dxfpolygonmode true) + (dxfimperialunits true) + (dxfusepcbnewfont true) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (sketchpadsonfab false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 0) + (scaleselection 1) + (outputdirectory "") + ) + ) + + (net 0 "") + (net 1 "Net-(J1-Pad1)") + (net 2 "Net-(J1-Pad2)") + (net 3 "Net-(J1-Pad3)") + (net 4 "Net-(J1-Pad4)") + (net 5 "Net-(J1-Pad5)") + (net 6 "Net-(J1-Pad6)") + (net 7 "Net-(J1-Pad7)") + (net 8 "Net-(J1-Pad8)") + (net 9 "Net-(J1-Pad9)") + (net 10 "Net-(J1-Pad10)") + (net 11 "Net-(J1-Pad11)") + (net 12 "Net-(J1-Pad12)") + + (footprint "GameCube:Conn_SP1" (layer "F.Cu") + (tedit 61CDEE58) (tstamp 3036986f-780f-4e5b-8e4b-4e66acc1e072) + (at 152 62) + (property "Sheetfile" "SP1-breakout.kicad_sch") + (property "Sheetname" "") + (path "/30d78a8a-040f-4f3e-aaa0-dac019e1b733") + (attr smd) + (fp_text reference "J1" (at -1 -1 unlocked) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp bde7a4d8-63ca-4270-b66f-826c8a03c717) + ) + (fp_text value "Conn_SP1" (at -4 1 unlocked) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp fcfcf9de-da88-4d1f-851c-bc4477644e6e) + ) + (fp_text user "CS" (at 3 -2 90 unlocked) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 37b995b2-20fa-47e3-83c3-f318a861f125) + ) + (fp_text user "DO" (at 7 -2 90 unlocked) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 3dcac506-eb97-4f6b-95ff-608f12f70ea1) + ) + (fp_text user "CLK" (at 9 -2 90 unlocked) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 6940450b-7815-4ba5-8e90-396dacf6b9f3) + ) + (fp_text user "GND" (at 1 -2 90 unlocked) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 860f245f-211c-4e13-9bbc-ca4b223eb73e) + ) + (fp_text user "GND" (at 11 -2 90 unlocked) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 97235839-87e9-4e23-bf69-7f63b0dc5010) + ) + (fp_text user "3.3V" (at 5 -2 90 unlocked) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp d78ffba0-128a-4068-a1fd-69c9f25d7568) + ) + (fp_text user "12V" (at 8 -2 90 unlocked) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 2af950fa-cfd1-451a-baa2-54e4a9c1c4e5) + ) + (fp_text user "GND" (at 2 -2 90 unlocked) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 40b23672-a50c-45b8-80c1-fb678f1db4f7) + ) + (fp_text user "3.3V" (at 6 -2 90 unlocked) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 626d40b4-8682-4a64-8532-bad6c09249cd) + ) + (fp_text user "EXTIN" (at 12 -2 90 unlocked) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 90a61a06-2407-465b-b8cd-d3b6a338627c) + ) + (fp_text user "DI" (at 4 -2 90 unlocked) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 984f25ce-3db5-4e4e-87db-a99637e9fee5) + ) + (fp_text user "INT" (at 10 -2 90 unlocked) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp e16b5cd1-71f9-4abf-96b3-9f1ba90e244f) + ) + (fp_rect (start 0 0) (end 13 7) (layer "F.SilkS") (width 0.12) (fill none) (tstamp 83866f8b-566a-4559-bc8e-7637985bbf18)) + (pad "1" smd rect (at 12 3.683 90) (size 6.6 1) (layers "F.Cu" "F.Paste" "F.Mask") + (net 1 "Net-(J1-Pad1)") (pinfunction "EXTIN") (pintype "input") (tstamp 1482877d-3e64-47ea-b1fe-2305a912ab67)) + (pad "2" smd rect (at 11 3.683 90) (size 6.6 1) (layers "B.Cu" "B.Paste" "B.Mask") + (net 2 "Net-(J1-Pad2)") (pinfunction "GND") (pintype "passive") (tstamp 9058b67d-f074-4f5f-96f2-240ee34236e2)) + (pad "3" smd rect (at 10 3.683 90) (size 6.6 1) (layers "F.Cu" "F.Paste" "F.Mask") + (net 3 "Net-(J1-Pad3)") (pinfunction "INT") (pintype "output") (tstamp 30b18f77-37fc-45f9-9c83-9844d7628b80)) + (pad "4" smd rect (at 9 3.683 90) (size 6.6 1) (layers "B.Cu" "B.Paste" "B.Mask") + (net 4 "Net-(J1-Pad4)") (pinfunction "CLK") (pintype "output") (tstamp 77ee6f3d-ab56-45dd-8012-c40936920e41)) + (pad "5" smd rect (at 8 3.683 90) (size 6.6 1) (layers "F.Cu" "F.Paste" "F.Mask") + (net 5 "Net-(J1-Pad5)") (pinfunction "12V") (pintype "passive") (tstamp 29823d02-53df-4780-a2f2-b575d50d547a)) + (pad "6" smd rect (at 7 3.683 90) (size 6.6 1) (layers "B.Cu" "B.Paste" "B.Mask") + (net 6 "Net-(J1-Pad6)") (pinfunction "DO") (pintype "input") (tstamp a330dbe2-7d63-48cf-8d2c-c99b67aa386a)) + (pad "7" smd rect (at 6 3.683 90) (size 6.6 1) (layers "F.Cu" "F.Paste" "F.Mask") + (net 7 "Net-(J1-Pad7)") (pinfunction "3.3v") (pintype "passive") (tstamp 8a159839-71df-4b5d-a760-d8138c34435b)) + (pad "8" smd rect (at 5 3.683 90) (size 6.6 1) (layers "B.Cu" "B.Paste" "B.Mask") + (net 8 "Net-(J1-Pad8)") (pinfunction "3.3v") (pintype "passive") (tstamp 5bd6e026-7480-4044-bb63-e1487f65d29e)) + (pad "9" smd rect (at 4 3.683 90) (size 6.6 1) (layers "F.Cu" "F.Paste" "F.Mask") + (net 9 "Net-(J1-Pad9)") (pinfunction "DI") (pintype "input") (tstamp 2e8407c2-3509-46d1-a1cf-b0dfe806b775)) + (pad "10" smd rect (at 3 3.683 90) (size 6.6 1) (layers "B.Cu" "B.Paste" "B.Mask") + (net 10 "Net-(J1-Pad10)") (pinfunction "CS") (pintype "output") (tstamp bc13ae13-3d12-4cf8-a665-c3793b5a6cb4)) + (pad "11" smd rect (at 2 3.683 90) (size 6.6 1) (layers "F.Cu" "F.Paste" "F.Mask") + (net 11 "Net-(J1-Pad11)") (pinfunction "GND") (pintype "passive") (tstamp c0c5f17d-3aac-474d-bb3f-2ca22c2fb264)) + (pad "12" smd rect (at 1 3.683 90) (size 6.6 1) (layers "B.Cu" "B.Paste" "B.Mask") + (net 12 "Net-(J1-Pad12)") (pinfunction "GND") (pintype "passive") (tstamp f8b43c68-b236-4157-bae6-4b9115080deb)) + ) + + (footprint "Connector_PinHeader_2.54mm:PinHeader_2x06_P2.54mm_Vertical" (layer "F.Cu") + (tedit 59FED5CC) (tstamp 5f30f18a-2eb5-4274-9d3d-af9601238118) + (at 164.85 37.225 -90) + (descr "Through hole straight pin header, 2x06, 2.54mm pitch, double rows") + (tags "Through hole pin header THT 2x06 2.54mm double row") + (property "Sheetfile" "SP1-breakout.kicad_sch") + (property "Sheetname" "") + (path "/ea1328d2-29be-4d36-bbe3-052d59ff791f") + (attr through_hole) + (fp_text reference "J2" (at 5.775 -0.15 180) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 996c5414-4d36-42a5-a5a3-5c685d76f56d) + ) + (fp_text value "Conn_01x12" (at -3.225 -0.15 180) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 4110e71c-ac60-4e49-a67d-42ff60f3a0ba) + ) + (fp_text user "${REFERENCE}" (at 1.27 6.35) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 18648368-8315-41f6-b287-55706b48f79e) + ) + (fp_line (start -1.33 1.27) (end 1.27 1.27) (layer "F.SilkS") (width 0.12) (tstamp 5880b9b0-aa32-4505-8669-deb95429be37)) + (fp_line (start 3.87 -1.33) (end 3.87 14.03) (layer "F.SilkS") (width 0.12) (tstamp 5b17d47a-a4a2-4ddf-966a-e6b5821094ec)) + (fp_line (start 1.27 1.27) (end 1.27 -1.33) (layer "F.SilkS") (width 0.12) (tstamp 8eb5e770-d904-422f-814b-21543d34976a)) + (fp_line (start -1.33 14.03) (end 3.87 14.03) (layer "F.SilkS") (width 0.12) (tstamp a4016004-dc80-4dea-8e6b-d39f67a11e91)) + (fp_line (start -1.33 -1.33) (end 0 -1.33) (layer "F.SilkS") (width 0.12) (tstamp c7f16784-da95-4ab7-905d-9889694975ee)) + (fp_line (start 1.27 -1.33) (end 3.87 -1.33) (layer "F.SilkS") (width 0.12) (tstamp c8fb0e8c-a702-4abf-8afe-bedb64abe0e1)) + (fp_line (start -1.33 0) (end -1.33 -1.33) (layer "F.SilkS") (width 0.12) (tstamp de9814ea-c668-40c7-a581-41a00d5ad413)) + (fp_line (start -1.33 1.27) (end -1.33 14.03) (layer "F.SilkS") (width 0.12) (tstamp facfc131-66c7-4b5b-b59f-7d81e0c94438)) + (fp_line (start -1.8 14.5) (end 4.35 14.5) (layer "F.CrtYd") (width 0.05) (tstamp 13ca6f98-495b-4848-a1b9-619bdbf2e008)) + (fp_line (start -1.8 -1.8) (end -1.8 14.5) (layer "F.CrtYd") (width 0.05) (tstamp 207f3729-b16f-4bed-8e25-6323ca6af59d)) + (fp_line (start 4.35 -1.8) (end -1.8 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 2d5b3e10-9b65-4abf-803e-969a546fc8e3)) + (fp_line (start 4.35 14.5) (end 4.35 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 3969f1a4-cee5-45d1-af73-48102fab1b79)) + (fp_line (start 0 -1.27) (end 3.81 -1.27) (layer "F.Fab") (width 0.1) (tstamp 148d4173-b063-4b10-8a8d-efdde1f30322)) + (fp_line (start -1.27 0) (end 0 -1.27) (layer "F.Fab") (width 0.1) (tstamp 3bb6370c-713d-4d7f-8232-809c9ec621ba)) + (fp_line (start 3.81 13.97) (end -1.27 13.97) (layer "F.Fab") (width 0.1) (tstamp 69814d9b-0367-4de8-9718-43b37031d240)) + (fp_line (start -1.27 13.97) (end -1.27 0) (layer "F.Fab") (width 0.1) (tstamp 69b9c43b-f07d-440f-a8c0-3e74d8fe8255)) + (fp_line (start 3.81 -1.27) (end 3.81 13.97) (layer "F.Fab") (width 0.1) (tstamp abdf1fc0-a5f4-4a26-adc8-ba7216defb10)) + (pad "1" thru_hole rect locked (at 0 0 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 1 "Net-(J1-Pad1)") (pinfunction "Pin_1") (pintype "passive") (tstamp 2e74c5cf-df21-4ecb-90c2-e2781152c95b)) + (pad "2" thru_hole oval locked (at 2.54 0 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 2 "Net-(J1-Pad2)") (pinfunction "Pin_2") (pintype "passive") (tstamp 91d720eb-a86c-46fd-9f6a-0dddf20bde1e)) + (pad "3" thru_hole oval locked (at 0 2.54 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 3 "Net-(J1-Pad3)") (pinfunction "Pin_3") (pintype "passive") (tstamp 291d9785-819b-4ab3-8871-6887bb427f84)) + (pad "4" thru_hole oval locked (at 2.54 2.54 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 4 "Net-(J1-Pad4)") (pinfunction "Pin_4") (pintype "passive") (tstamp 744bf9ad-3201-4631-b4df-82ae02271ec9)) + (pad "5" thru_hole oval locked (at 0 5.08 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 5 "Net-(J1-Pad5)") (pinfunction "Pin_5") (pintype "passive") (tstamp 72596630-6f62-446b-a788-e57836f8a3c1)) + (pad "6" thru_hole oval locked (at 2.54 5.08 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 6 "Net-(J1-Pad6)") (pinfunction "Pin_6") (pintype "passive") (tstamp dfcdf09d-9f20-4402-b580-09edd237e4fb)) + (pad "7" thru_hole oval locked (at 0 7.62 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 7 "Net-(J1-Pad7)") (pinfunction "Pin_7") (pintype "passive") (tstamp bac0882a-cd95-40e5-bcae-36dd00c1e400)) + (pad "8" thru_hole oval locked (at 2.54 7.62 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 8 "Net-(J1-Pad8)") (pinfunction "Pin_8") (pintype "passive") (tstamp 34123646-538f-4d29-99e3-ef929983a259)) + (pad "9" thru_hole oval locked (at 0 10.16 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 9 "Net-(J1-Pad9)") (pinfunction "Pin_9") (pintype "passive") (tstamp 792df31f-d7c8-4ab7-9004-848451dfcc4f)) + (pad "10" thru_hole oval locked (at 2.54 10.16 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 10 "Net-(J1-Pad10)") (pinfunction "Pin_10") (pintype "passive") (tstamp a423b214-b454-4185-84f8-c95ee23e5bb6)) + (pad "11" thru_hole oval locked (at 0 12.7 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 11 "Net-(J1-Pad11)") (pinfunction "Pin_11") (pintype "passive") (tstamp b57691ac-45e2-4fef-b67e-be0698b53c0a)) + (pad "12" thru_hole oval locked (at 2.54 12.7 270) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) + (net 12 "Net-(J1-Pad12)") (pinfunction "Pin_12") (pintype "passive") (tstamp 46a7dba6-e84c-4e04-a72e-86e4c6e4e198)) + (model "${KICAD6_3DMODEL_DIR}/Connector_PinHeader_2.54mm.3dshapes/PinHeader_2x06_P2.54mm_Vertical.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (gr_poly + (pts + (xy 167 62) + (xy 165 62) + (xy 165 69) + (xy 152 69) + (xy 152 62) + (xy 150 62) + (xy 150 35) + (xy 167 35) + ) (layer "Edge.Cuts") (width 0.1) (fill none) (tstamp e0b09194-c95a-4fcd-af7c-326f7d8dc882)) + + (segment (start 164 65.683) (end 164 42.27601) (width 0.25) (layer "F.Cu") (net 1) (tstamp 782a3fea-6e84-4579-b9dd-e6072609511f)) + (segment (start 166.024511 40.251499) (end 166.024511 38.399511) (width 0.25) (layer "F.Cu") (net 1) (tstamp 8f95c6b4-5bd8-4782-8637-3307b0e23406)) + (segment (start 166.024511 38.399511) (end 164.85 37.225) (width 0.25) (layer "F.Cu") (net 1) (tstamp cd26d311-0ade-4d32-9c31-b518e26d3fae)) + (segment (start 164 42.27601) (end 166.024511 40.251499) (width 0.25) (layer "F.Cu") (net 1) (tstamp dd2bc80d-88d9-46d0-89cd-ce7d1f386fe4)) + (segment (start 163 41.615) (end 164.85 39.765) (width 0.25) (layer "B.Cu") (net 2) (tstamp 18a9e924-345c-4a2d-ba08-595ffc779d26)) + (segment (start 163 65.683) (end 163 41.615) (width 0.25) (layer "B.Cu") (net 2) (tstamp ba9b7f62-7186-4d32-971c-b77acb76b990)) + (segment (start 163.484511 38.399511) (end 162.31 37.225) (width 0.25) (layer "F.Cu") (net 3) (tstamp 6d99f6a0-d21d-40d5-8367-2d1511f779bf)) + (segment (start 163.484511 40.251499) (end 163.484511 38.399511) (width 0.25) (layer "F.Cu") (net 3) (tstamp 814bda4c-9b81-4fbc-bb92-810d42f7db00)) + (segment (start 162 41.73601) (end 163.484511 40.251499) (width 0.25) (layer "F.Cu") (net 3) (tstamp b005f436-b8fb-4674-a1f2-4a304343dad1)) + (segment (start 162 65.683) (end 162 41.73601) (width 0.25) (layer "F.Cu") (net 3) (tstamp e9e3c10a-4088-4608-b491-bf5afdb05419)) + (segment (start 161 41.075) (end 162.31 39.765) (width 0.25) (layer "B.Cu") (net 4) (tstamp 5efbc865-ed06-4b19-a6ab-6210245003f0)) + (segment (start 161 65.683) (end 161 41.075) (width 0.25) (layer "B.Cu") (net 4) (tstamp 7bea3523-6a2e-412c-b48b-d85cf6b79368)) + (segment (start 160 42.05) (end 161 41.05) (width 0.25) (layer "F.Cu") (net 5) (tstamp 0c093abb-9f9c-4557-9227-9b2c70beb271)) + (segment (start 161 41.05) (end 161 38.455) (width 0.25) (layer "F.Cu") (net 5) (tstamp 5c1d991d-202a-4e7e-ac3b-b45b999cc209)) + (segment (start 160 65.683) (end 160 42.05) (width 0.25) (layer "F.Cu") (net 5) (tstamp 6608fc21-068d-4d1d-822c-c0d1f6fe9c82)) + (segment (start 161 38.455) (end 159.77 37.225) (width 0.25) (layer "F.Cu") (net 5) (tstamp 6775c9be-f31e-47ff-9453-7d11c4e67cc0)) + (segment (start 159 40.535) (end 159.77 39.765) (width 0.25) (layer "B.Cu") (net 6) (tstamp 6bfa25a9-9d93-4675-9fb2-7d2dd0fc09de)) + (segment (start 159 65.683) (end 159 40.535) (width 0.25) (layer "B.Cu") (net 6) (tstamp df6c40da-834f-42fa-b570-545c924c8f61)) + (segment (start 158.404511 41.095489) (end 158.404511 38.399511) (width 0.25) (layer "F.Cu") (net 7) (tstamp 012ef9fd-b92e-444d-ae39-c70dc97a5253)) + (segment (start 158 65.683) (end 158.404511 65.278489) (width 0.25) (layer "F.Cu") (net 7) (tstamp 31c564e2-54c1-46dc-8fa7-c346347f3185)) + (segment (start 158.404511 38.399511) (end 157.23 37.225) (width 0.25) (layer "F.Cu") (net 7) (tstamp 3ad28c60-3710-4182-ab19-6a740a287323)) + (segment (start 158 65.683) (end 158 41.5) (width 0.25) (layer "F.Cu") (net 7) (tstamp 50dc91db-ad4e-4510-90fc-fd2ef6cd0cc0)) + (segment (start 158 41.5) (end 158.404511 41.095489) (width 0.25) (layer "F.Cu") (net 7) (tstamp 9dbe33fd-c0b4-417c-84f2-a8c664f3c385)) + (segment (start 157 39.995) (end 157.23 39.765) (width 0.25) (layer "B.Cu") (net 8) (tstamp 49eab125-efd3-4080-b2c7-709e2e3c6640)) + (segment (start 157 65.683) (end 157 39.995) (width 0.25) (layer "B.Cu") (net 8) (tstamp 5c768b44-cfc2-4b66-a946-df5f950fd7ac)) + (segment (start 156 65.683) (end 156 38.535) (width 0.25) (layer "F.Cu") (net 9) (tstamp 2aff57ff-d257-4a10-aad9-d08661f08ca0)) + (segment (start 156 38.535) (end 154.69 37.225) (width 0.25) (layer "F.Cu") (net 9) (tstamp c976a384-4574-48a8-95b3-389f100b0740)) + (segment (start 155 40.075) (end 154.69 39.765) (width 0.25) (layer "B.Cu") (net 10) (tstamp 211dafae-49cb-4e21-8b4b-ab2810e6e7a1)) + (segment (start 155 65.683) (end 155 40.075) (width 0.25) (layer "B.Cu") (net 10) (tstamp 7995e523-012f-4e1e-8697-85e9be4682cc)) + (segment (start 154 42.15) (end 153.324511 41.474511) (width 0.25) (layer "F.Cu") (net 11) (tstamp 39b0a25f-8d98-4e5b-bfd6-0e0721c204db)) + (segment (start 154 65.683) (end 154 42.15) (width 0.25) (layer "F.Cu") (net 11) (tstamp 4790bcb2-7790-46b9-9080-9ca48e01b7a3)) + (segment (start 153.324511 41.474511) (end 153.324511 38.399511) (width 0.25) (layer "F.Cu") (net 11) (tstamp 743430b2-e0ca-4715-bfb5-790a2a92ccd5)) + (segment (start 153.324511 38.399511) (end 152.15 37.225) (width 0.25) (layer "F.Cu") (net 11) (tstamp a8dc336e-9055-40c8-8451-89f61df62da1)) + (segment (start 153 42.55) (end 152.15 41.7) (width 0.25) (layer "B.Cu") (net 12) (tstamp 04534876-aa04-43ca-8864-ca2c9549748e)) + (segment (start 152.15 39.765) (end 152.15 41.7) (width 0.25) (layer "B.Cu") (net 12) (tstamp 2f53529a-e1cb-4eeb-b31c-582451417cf7)) + (segment (start 153 65.683) (end 153 42.55) (width 0.25) (layer "B.Cu") (net 12) (tstamp 50aef0ec-7b35-463a-af3c-867422f8abf1)) + +) diff --git a/SP1-breakout/SP1-breakout.kicad_prl b/SP1-breakout/SP1-breakout.kicad_prl new file mode 100644 index 0000000..5f45ac4 --- /dev/null +++ b/SP1-breakout/SP1-breakout.kicad_prl @@ -0,0 +1,75 @@ +{ + "board": { + "active_layer": 0, + "active_layer_preset": "All Layers", + "auto_track_width": true, + "hidden_nets": [], + "high_contrast_mode": 0, + "net_color_mode": 1, + "opacity": { + "pads": 1.0, + "tracks": 1.0, + "vias": 1.0, + "zones": 0.6 + }, + "ratsnest_display_mode": 0, + "selection_filter": { + "dimensions": true, + "footprints": true, + "graphics": true, + "keepouts": true, + "lockedItems": true, + "otherItems": true, + "pads": true, + "text": true, + "tracks": true, + "vias": true, + "zones": true + }, + "visible_items": [ + 0, + 1, + 2, + 3, + 4, + 5, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 32, + 33, + 34, + 35, + 36 + ], + "visible_layers": "fffffff_ffffffff", + "zone_display_mode": 0 + }, + "meta": { + "filename": "SP1-breakout.kicad_prl", + "version": 3 + }, + "project": { + "files": [] + } +} diff --git a/SP1-breakout/SP1-breakout.kicad_pro b/SP1-breakout/SP1-breakout.kicad_pro new file mode 100644 index 0000000..ddb7956 --- /dev/null +++ b/SP1-breakout/SP1-breakout.kicad_pro @@ -0,0 +1,326 @@ +{ + "board": { + "design_settings": { + "defaults": { + "board_outline_line_width": 0.1, + "copper_line_width": 0.2, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "other_line_width": 0.15, + "silk_line_width": 0.15, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.15 + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "rules": { + "min_copper_edge_clearance": 0.0, + "solder_mask_clearance": 0.0, + "solder_mask_min_width": 0.0 + }, + "track_widths": [], + "via_dimensions": [] + }, + "layer_presets": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_label_syntax": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "extra_units": "error", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "lib_symbol_issues": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "warning", + "power_pin_not_driven": "error", + "similar_labels": "warning", + "unannotated": "error", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "SP1-breakout.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12.0, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.25, + "via_diameter": 0.8, + "via_drill": 0.4, + "wire_width": 6.0 + } + ], + "meta": { + "version": 2 + }, + "net_colors": null + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "specctra_dsn": "", + "step": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "drawing": { + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "field_names": [], + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.375, + "pin_symbol_size": 25.0, + "text_offset_ratio": 0.15 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "ngspice": { + "fix_include_paths": true, + "fix_passive_vals": false, + "meta": { + "version": 0 + }, + "model_mode": 0, + "workbook_filename": "" + }, + "page_layout_descr_file": "", + "plot_directory": "", + "spice_adjust_passive_values": false, + "spice_external_command": "spice \"%I\"", + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "92563de1-61c4-4e3f-8603-96474790934f", + "" + ] + ], + "text_variables": {} +} diff --git a/SP1-breakout/SP1-breakout.kicad_sch b/SP1-breakout/SP1-breakout.kicad_sch new file mode 100644 index 0000000..9e85037 --- /dev/null +++ b/SP1-breakout/SP1-breakout.kicad_sch @@ -0,0 +1,325 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid 92563de1-61c4-4e3f-8603-96474790934f) + + (paper "A4") + + (lib_symbols + (symbol "Connector_Generic:Conn_01x12" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes) + (property "Reference" "J" (id 0) (at 0 15.24 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "Conn_01x12" (id 1) (at 0 -17.78 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "connector" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Generic connector, single row, 01x12, script generated (kicad-library-utils/schlib/autogen/connector/)" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "Connector*:*_1x??_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "Conn_01x12_1_1" + (rectangle (start -1.27 -15.113) (end 0 -15.367) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 -12.573) (end 0 -12.827) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 -10.033) (end 0 -10.287) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 -7.493) (end 0 -7.747) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 -4.953) (end 0 -5.207) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 -2.413) (end 0 -2.667) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 0.127) (end 0 -0.127) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 2.667) (end 0 2.413) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 5.207) (end 0 4.953) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 7.747) (end 0 7.493) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 10.287) (end 0 10.033) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 12.827) (end 0 12.573) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start -1.27 13.97) (end 1.27 -16.51) + (stroke (width 0.254) (type default) (color 0 0 0 0)) + (fill (type background)) + ) + (pin passive line (at -5.08 12.7 0) (length 3.81) + (name "Pin_1" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 -10.16 0) (length 3.81) + (name "Pin_10" (effects (font (size 1.27 1.27)))) + (number "10" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 -12.7 0) (length 3.81) + (name "Pin_11" (effects (font (size 1.27 1.27)))) + (number "11" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 -15.24 0) (length 3.81) + (name "Pin_12" (effects (font (size 1.27 1.27)))) + (number "12" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 10.16 0) (length 3.81) + (name "Pin_2" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 7.62 0) (length 3.81) + (name "Pin_3" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 5.08 0) (length 3.81) + (name "Pin_4" (effects (font (size 1.27 1.27)))) + (number "4" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 2.54 0) (length 3.81) + (name "Pin_5" (effects (font (size 1.27 1.27)))) + (number "5" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 0 0) (length 3.81) + (name "Pin_6" (effects (font (size 1.27 1.27)))) + (number "6" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 -2.54 0) (length 3.81) + (name "Pin_7" (effects (font (size 1.27 1.27)))) + (number "7" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 -5.08 0) (length 3.81) + (name "Pin_8" (effects (font (size 1.27 1.27)))) + (number "8" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at -5.08 -7.62 0) (length 3.81) + (name "Pin_9" (effects (font (size 1.27 1.27)))) + (number "9" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Gamecube:Conn_SP1" (in_bom yes) (on_board yes) + (property "Reference" "J" (id 0) (at 3.81 3.81 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "Conn_SP1" (id 1) (at 3.81 1.27 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "Conn_SP1_0_1" + (rectangle (start 0 0) (end 7.62 -33.02) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "Conn_SP1_1_1" + (pin input line (at 10.16 -2.54 180) (length 2.54) + (name "EXTIN" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin output line (at 10.16 -25.4 180) (length 2.54) + (name "CS" (effects (font (size 1.27 1.27)))) + (number "10" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 10.16 -27.94 180) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "11" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 10.16 -30.48 180) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "12" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 10.16 -5.08 180) (length 2.54) + (name "GND" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin output line (at 10.16 -7.62 180) (length 2.54) + (name "INT" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + (pin output line (at 10.16 -10.16 180) (length 2.54) + (name "CLK" (effects (font (size 1.27 1.27)))) + (number "4" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 10.16 -12.7 180) (length 2.54) + (name "12V" (effects (font (size 1.27 1.27)))) + (number "5" (effects (font (size 1.27 1.27)))) + ) + (pin input line (at 10.16 -15.24 180) (length 2.54) + (name "DO" (effects (font (size 1.27 1.27)))) + (number "6" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 10.16 -17.78 180) (length 2.54) + (name "3.3v" (effects (font (size 1.27 1.27)))) + (number "7" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 10.16 -20.32 180) (length 2.54) + (name "3.3v" (effects (font (size 1.27 1.27)))) + (number "8" (effects (font (size 1.27 1.27)))) + ) + (pin input line (at 10.16 -22.86 180) (length 2.54) + (name "DI" (effects (font (size 1.27 1.27)))) + (number "9" (effects (font (size 1.27 1.27)))) + ) + ) + ) + ) + + + (wire (pts (xy 58.42 58.42) (xy 73.66 58.42)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 087b9502-45b7-421c-a796-aebf67b14e5b) + ) + (wire (pts (xy 58.42 53.34) (xy 73.66 53.34)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 1a260284-2f66-4f8f-ab41-090129e221c6) + ) + (wire (pts (xy 58.42 66.04) (xy 73.66 66.04)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 3febab91-6e45-4b46-8d52-11ad91611c85) + ) + (wire (pts (xy 58.42 50.8) (xy 73.66 50.8)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 418b5591-5987-40e1-9098-0264559658eb) + ) + (wire (pts (xy 58.42 55.88) (xy 73.66 55.88)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 4c955a8d-fcbe-4be8-91c7-1f9269f12510) + ) + (wire (pts (xy 58.42 60.96) (xy 73.66 60.96)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 67a6d458-005c-4ef0-9198-1a9f8f807f77) + ) + (wire (pts (xy 58.42 43.18) (xy 73.66 43.18)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 83c868cc-41b1-4e10-ac08-4d4dfbe64a47) + ) + (wire (pts (xy 58.42 45.72) (xy 73.66 45.72)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 8e5d9526-6253-4e85-ad42-c13731f6ff9c) + ) + (wire (pts (xy 58.42 63.5) (xy 73.66 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 94cf2e9a-3326-4ca4-ae03-814bc0c2e327) + ) + (wire (pts (xy 58.42 40.64) (xy 73.66 40.64)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 9b3c501b-dad9-4982-8d5b-c9a69e461fde) + ) + (wire (pts (xy 58.42 68.58) (xy 73.66 68.58)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid e51a42fb-6a26-4d20-a9a8-552850a32440) + ) + (wire (pts (xy 58.42 48.26) (xy 73.66 48.26)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid f20c7c3c-b320-4f89-bc6d-3e4e91a52d10) + ) + + (symbol (lib_id "Gamecube:Conn_SP1") (at 48.26 38.1 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid 30d78a8a-040f-4f3e-aaa0-dac019e1b733) + (property "Reference" "J1" (id 0) (at 48.26 34.29 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "Conn_SP1" (id 1) (at 48.26 36.83 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "GameCube:Conn_SP1" (id 2) (at 48.26 38.1 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 48.26 38.1 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 42a0dd2f-213e-4ba5-9282-5f1a2486f4da)) + (pin "10" (uuid c23a006f-46af-4d13-b89e-ff6253c4c7c4)) + (pin "11" (uuid b9b067ce-38ac-4b8a-b54c-132dbd63e06a)) + (pin "12" (uuid bf057173-9741-4001-b5ef-8295ad203027)) + (pin "2" (uuid 7f61998d-e04d-4388-b7dc-a68602295164)) + (pin "3" (uuid 66ae9f71-6157-4c5d-a73c-098667f4227b)) + (pin "4" (uuid d1ae81b4-e945-4c98-aae2-7c5c5aca713c)) + (pin "5" (uuid 0ce7f80a-c33c-41da-b4ad-c94fec0bd914)) + (pin "6" (uuid 8cc76379-50b0-4db6-920b-fcae05b66004)) + (pin "7" (uuid b8c81b2d-2762-45f6-87a5-bf7fe91502ea)) + (pin "8" (uuid 7b5fc003-35db-420f-b25d-63168474a732)) + (pin "9" (uuid 29143fa6-84f5-4bee-926c-e22b901ceb10)) + ) + + (symbol (lib_id "Connector_Generic:Conn_01x12") (at 78.74 53.34 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid ea1328d2-29be-4d36-bbe3-052d59ff791f) + (property "Reference" "J2" (id 0) (at 76.2 34.29 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "Conn_01x12" (id 1) (at 73.66 36.83 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Connector_PinHeader_2.54mm:PinHeader_2x06_P2.54mm_Vertical" (id 2) (at 78.74 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 78.74 53.34 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 878237d8-a43e-4f0d-9a4b-f2a072d49b84)) + (pin "10" (uuid f24549d0-5224-4dbb-9140-b3420dcd67bf)) + (pin "11" (uuid e437b015-aa81-4709-9d5d-dc530b3c2bd5)) + (pin "12" (uuid 981293ff-7819-4546-95ea-deb94a5458b8)) + (pin "2" (uuid 0df390b8-f1d1-44d3-b74f-3a673a277ad9)) + (pin "3" (uuid bb6a9045-78c8-4a57-8c32-6e92004836eb)) + (pin "4" (uuid 4edde7cc-c0b0-417b-9685-ab1523b07d5d)) + (pin "5" (uuid 62d0b570-956b-425e-b1e4-82169842ac74)) + (pin "6" (uuid f17bb2ec-6cb0-4d42-b0d5-6bf7fbec1243)) + (pin "7" (uuid 146e7698-6d8d-4afb-a180-cbb61241ac13)) + (pin "8" (uuid 2ae1f89c-927f-4eef-b991-e4b8f105284d)) + (pin "9" (uuid 08e1a7aa-f4db-46c4-b87f-0adfbd2ce959)) + ) + + (sheet_instances + (path "/" (page "1")) + ) + + (symbol_instances + (path "/30d78a8a-040f-4f3e-aaa0-dac019e1b733" + (reference "J1") (unit 1) (value "Conn_SP1") (footprint "GameCube:Conn_SP1") + ) + (path "/ea1328d2-29be-4d36-bbe3-052d59ff791f" + (reference "J2") (unit 1) (value "Conn_01x12") (footprint "Connector_PinHeader_2.54mm:PinHeader_2x06_P2.54mm_Vertical") + ) + ) +) diff --git a/bba/.gitignore b/bba/.gitignore new file mode 100644 index 0000000..2d753e9 --- /dev/null +++ b/bba/.gitignore @@ -0,0 +1,5 @@ +*.gbr +*.drl +*.zip +*.gbrjob +fp-info-cache diff --git a/bba/re-bba-rb.kicad_pcb b/bba/re-bba-rb.kicad_pcb new file mode 100644 index 0000000..28b47a1 --- /dev/null +++ b/bba/re-bba-rb.kicad_pcb @@ -0,0 +1,2 @@ +(kicad_pcb (version 20211014) (generator pcbnew) +) \ No newline at end of file diff --git a/bba/re-bba-rb.kicad_prl b/bba/re-bba-rb.kicad_prl new file mode 100644 index 0000000..13529f1 --- /dev/null +++ b/bba/re-bba-rb.kicad_prl @@ -0,0 +1,75 @@ +{ + "board": { + "active_layer": 0, + "active_layer_preset": "All Layers", + "auto_track_width": true, + "hidden_nets": [], + "high_contrast_mode": 0, + "net_color_mode": 1, + "opacity": { + "pads": 1.0, + "tracks": 1.0, + "vias": 1.0, + "zones": 0.6 + }, + "ratsnest_display_mode": 0, + "selection_filter": { + "dimensions": true, + "footprints": true, + "graphics": true, + "keepouts": true, + "lockedItems": true, + "otherItems": true, + "pads": true, + "text": true, + "tracks": true, + "vias": true, + "zones": true + }, + "visible_items": [ + 0, + 1, + 2, + 3, + 4, + 5, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 32, + 33, + 34, + 35, + 36 + ], + "visible_layers": "fffffff_ffffffff", + "zone_display_mode": 0 + }, + "meta": { + "filename": "re-bba-rb.kicad_prl", + "version": 3 + }, + "project": { + "files": [] + } +} diff --git a/bba/re-bba-rb.kicad_pro b/bba/re-bba-rb.kicad_pro new file mode 100644 index 0000000..f8f202c --- /dev/null +++ b/bba/re-bba-rb.kicad_pro @@ -0,0 +1,420 @@ +{ + "board": { + "design_settings": { + "defaults": { + "board_outline_line_width": 0.09999999999999999, + "copper_line_width": 0.19999999999999998, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": false, + "text_position": 0, + "units_format": 1 + }, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.15, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.762, + "height": 1.524, + "width": 1.524 + }, + "silk_line_width": 0.15, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.15, + "silk_text_upright": false, + "zones": { + "45_degree_only": false, + "min_clearance": 0.508 + } + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "meta": { + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "copper_edge_clearance": "error", + "courtyards_overlap": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "footprint_type_mismatch": "error", + "hole_clearance": "error", + "hole_near_hole": "error", + "invalid_outline": "error", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "error", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "through_hole_pad_without_hole": "error", + "too_many_vias": "error", + "track_dangling": "warning", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zone_has_empty_net": "error", + "zones_intersect": "error" + }, + "rules": { + "allow_blind_buried_vias": false, + "allow_microvias": false, + "max_error": 0.005, + "min_clearance": 0.0, + "min_copper_edge_clearance": 0.0, + "min_hole_clearance": 0.25, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.19999999999999998, + "min_microvia_drill": 0.09999999999999999, + "min_silk_clearance": 0.0, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.19999999999999998, + "min_via_annular_width": 0.049999999999999996, + "min_via_diameter": 0.39999999999999997, + "solder_mask_clearance": 0.0, + "solder_mask_min_width": 0.0, + "use_height_for_length_calcs": true + }, + "track_widths": [], + "via_dimensions": [], + "zones_allow_external_fillets": false, + "zones_use_no_outline": true + }, + "layer_presets": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_label_syntax": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "extra_units": "error", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "lib_symbol_issues": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "warning", + "power_pin_not_driven": "error", + "similar_labels": "warning", + "unannotated": "error", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "re-bba-rb.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12.0, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.25, + "via_diameter": 0.8, + "via_drill": 0.4, + "wire_width": 6.0 + } + ], + "meta": { + "version": 2 + }, + "net_colors": null + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "specctra_dsn": "", + "step": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "drawing": { + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "field_names": [], + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.375, + "pin_symbol_size": 25.0, + "text_offset_ratio": 0.15 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "ngspice": { + "fix_include_paths": true, + "fix_passive_vals": false, + "meta": { + "version": 0 + }, + "model_mode": 0, + "workbook_filename": "" + }, + "page_layout_descr_file": "", + "plot_directory": "", + "spice_adjust_passive_values": false, + "spice_external_command": "spice \"%I\"", + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "e63e39d7-6ac0-4ffd-8aa3-1841a4541b55", + "" + ] + ], + "text_variables": {} +} diff --git a/bba/re-bba-rb.kicad_sch b/bba/re-bba-rb.kicad_sch new file mode 100644 index 0000000..1fea440 --- /dev/null +++ b/bba/re-bba-rb.kicad_sch @@ -0,0 +1,262 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid e63e39d7-6ac0-4ffd-8aa3-1841a4541b55) + + (paper "A4") + + (lib_symbols + (symbol "Connector:Conn_01x12_Male" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes) + (property "Reference" "J" (id 0) (at 0 15.24 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "Conn_01x12_Male" (id 1) (at 0 -17.78 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "connector" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Generic connector, single row, 01x12, script generated (kicad-library-utils/schlib/autogen/connector/)" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "Connector*:*_1x??_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "Conn_01x12_Male_1_1" + (polyline + (pts + (xy 1.27 -15.24) + (xy 0.8636 -15.24) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 -12.7) + (xy 0.8636 -12.7) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 -10.16) + (xy 0.8636 -10.16) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 -7.62) + (xy 0.8636 -7.62) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 -5.08) + (xy 0.8636 -5.08) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 -2.54) + (xy 0.8636 -2.54) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 0) + (xy 0.8636 0) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 2.54) + (xy 0.8636 2.54) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 5.08) + (xy 0.8636 5.08) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 7.62) + (xy 0.8636 7.62) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 10.16) + (xy 0.8636 10.16) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 12.7) + (xy 0.8636 12.7) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start 0.8636 -15.113) (end 0 -15.367) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 -12.573) (end 0 -12.827) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 -10.033) (end 0 -10.287) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 -7.493) (end 0 -7.747) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 -4.953) (end 0 -5.207) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 -2.413) (end 0 -2.667) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 0.127) (end 0 -0.127) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 2.667) (end 0 2.413) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 5.207) (end 0 4.953) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 7.747) (end 0 7.493) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 10.287) (end 0 10.033) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 12.827) (end 0 12.573) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (pin passive line (at 5.08 12.7 180) (length 3.81) + (name "Pin_1" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -10.16 180) (length 3.81) + (name "Pin_10" (effects (font (size 1.27 1.27)))) + (number "10" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -12.7 180) (length 3.81) + (name "Pin_11" (effects (font (size 1.27 1.27)))) + (number "11" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -15.24 180) (length 3.81) + (name "Pin_12" (effects (font (size 1.27 1.27)))) + (number "12" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 10.16 180) (length 3.81) + (name "Pin_2" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 7.62 180) (length 3.81) + (name "Pin_3" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 5.08 180) (length 3.81) + (name "Pin_4" (effects (font (size 1.27 1.27)))) + (number "4" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 2.54 180) (length 3.81) + (name "Pin_5" (effects (font (size 1.27 1.27)))) + (number "5" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 0 180) (length 3.81) + (name "Pin_6" (effects (font (size 1.27 1.27)))) + (number "6" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -2.54 180) (length 3.81) + (name "Pin_7" (effects (font (size 1.27 1.27)))) + (number "7" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -5.08 180) (length 3.81) + (name "Pin_8" (effects (font (size 1.27 1.27)))) + (number "8" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -7.62 180) (length 3.81) + (name "Pin_9" (effects (font (size 1.27 1.27)))) + (number "9" (effects (font (size 1.27 1.27)))) + ) + ) + ) + ) + + + (symbol (lib_id "Connector:Conn_01x12_Male") (at 26.67 34.29 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid fa113599-7f96-408a-8974-e29046fc38ba) + (property "Reference" "J1" (id 0) (at 27.305 17.5473 0)) + (property "Value" "Conn_01x12_Male" (id 1) (at 27.305 20.3224 0)) + (property "Footprint" "" (id 2) (at 26.67 34.29 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 26.67 34.29 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 5d7ba739-ec09-4eb2-88de-f93b63931246)) + (pin "10" (uuid f8b0dcee-6bce-4fc3-b08f-85a62ef6ed48)) + (pin "11" (uuid 7ed6c747-b2e1-4fcd-a83a-251e00b9c400)) + (pin "12" (uuid 64d362b5-8df7-456f-a9ec-8c9312ae7ead)) + (pin "2" (uuid 4acead20-afd3-40c9-9779-362a2fa8e3db)) + (pin "3" (uuid 7302d1b8-5eb7-435f-8a27-1e073843e0b6)) + (pin "4" (uuid 7e321d44-b31c-441e-a648-29f6a530a65c)) + (pin "5" (uuid 2d4b4a06-1fbc-412f-a73f-b6cb8a54c8ff)) + (pin "6" (uuid e550c2c8-2970-49c1-af5a-e118415b14be)) + (pin "7" (uuid f10fe1b6-f645-44d8-a779-e60b8654088d)) + (pin "8" (uuid 67ffeb0f-301e-465b-88a4-09ca3188f9fc)) + (pin "9" (uuid ff9989c6-7a02-4da9-9a30-c5fc15f960c5)) + ) + + (sheet_instances + (path "/" (page "1")) + ) + + (symbol_instances + (path "/fa113599-7f96-408a-8974-e29046fc38ba" + (reference "J1") (unit 1) (value "Conn_01x12_Male") (footprint "") + ) + ) +) diff --git a/re-bba-test/.gitignore b/re-bba-test/.gitignore new file mode 100644 index 0000000..eb2b850 --- /dev/null +++ b/re-bba-test/.gitignore @@ -0,0 +1,4 @@ +build +*.dol +*.elf +.cache diff --git a/re-bba-test/Makefile b/re-bba-test/Makefile new file mode 100644 index 0000000..1ac09ac --- /dev/null +++ b/re-bba-test/Makefile @@ -0,0 +1,133 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/gamecube_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := src +DATA := data +INCLUDES := + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -logc -lm + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) + +export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := -L$(LIBOGC_LIB) $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +$(OFILES_SOURCES) : $(HFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.jpg.o %_jpg.h : %.jpg +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/re-bba-test/cmake/gc-toolchain.cmake b/re-bba-test/cmake/gc-toolchain.cmake new file mode 100644 index 0000000..f348b8d --- /dev/null +++ b/re-bba-test/cmake/gc-toolchain.cmake @@ -0,0 +1,48 @@ +set(CMAKE_SYSTEM_NAME Generic) # Must be "Generic" - otherwise CMake expects it in its distribution. +set(CMAKE_SYSTEM_PROCESSOR powerpc) +set(CMAKE_SYSTEM_VERSION 1.0) +set(CMAKE_SYSTEM ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION}) + +set(DevKitPro_Platform "GameCube") + +set(DevKitPro_ABI "eabi") +set(DevKitPro_Target "${CMAKE_SYSTEM_PROCESSOR}-${DevKitPro_ABI}") + +if(NOT DEFINED ENV{DEVKITPRO}) + message(FATAL_ERROR "The DEVKITPRO environment variable must be defined in order to use this toolchain!") +endif() + +set(DevKitPro "$ENV{DEVKITPRO}") + +set(DevKitProPPC "${DevKitPro}/devkitPPC") +set(DevKitPro_Bin "${DevKitProPPC}/bin") +set(DevKitPro_Tools "${DevKitProPPC}/${DevKitPro_Target}") + +if(WIN32) + set(BINARY_EXT ".exe") +else() + set(BINARY_EXT "") +endif() + +set(CMAKE_C_COMPILER "${DevKitPro_Bin}/${DevKitPro_Target}-gcc${BINARY_EXT}") +set(CMAKE_CXX_COMPILER "${DevKitPro_Bin}/${DevKitPro_Target}-g++${BINARY_EXT}") + + +foreach(LANG C CXX) + set(CMAKE_${LANG}_FLAGS_INIT "-DGEKKO -mcpu=750 -meabi -mhard-float -mogc") + set(CMAKE_${LANG}_STANDARD_INCLUDE_DIRECTORIES + "${DevKitProPPC}/lib/gcc/${DevKitPro_Target}/8.3.0/include" + "${DevKitPro_Tools}/include/c++/8.3.0" + "${DevKitPro_Tools}/include" + "${DevKitPro}/libogc/include" + ) + set(CMAKE_${LANG}_STANDARD_LIBRARIES "-logc -lm") + set(CMAKE_EXECUTABLE_SUFFIX_${LANG} ".elf") +endforeach() + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +set(CMAKE_EXE_LINKER_FLAGS "-L${DevKitPro_Tools}/lib -L${DevKitPro}/libogc/lib/cube") \ No newline at end of file diff --git a/re-bba-test/compile_commands.json b/re-bba-test/compile_commands.json new file mode 100644 index 0000000..cf500f4 --- /dev/null +++ b/re-bba-test/compile_commands.json @@ -0,0 +1,7 @@ +[ +{ + "directory": "F:/projects/re-bba-rb/re-bba-test", + "command": "F:/devkitpro/devkitPPC/bin/powerpc-eabi-gcc.exe -isystem F:/devkitpro/devkitPPC/lib/gcc/powerpc-eabi/8.3.0/include -isystem F:/devkitpro/devkitPPC/powerpc-eabi/include/c++/8.3.0 -isystem F:/devkitpro/devkitPPC/powerpc-eabi/include -isystem F:/devkitpro/libogc/include -DGEKKO -mcpu=750 -meabi -mhard-float -mogc -o CMakeFiles/re-bba-test.dir/src/main.c.obj -c F:/projects/re-bba-rb/re-bba-test/src/main.c", + "file": "F:/projects/re-bba-rb/re-bba-test/src/main.c" +} +] \ No newline at end of file diff --git a/re-bba-test/src/main.c b/re-bba-test/src/main.c new file mode 100644 index 0000000..ca0a71b --- /dev/null +++ b/re-bba-test/src/main.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include + +static void *xfb = NULL; +static GXRModeObj *rmode = NULL; + +void* initialise(); +int test_bba_get_id(); + +#define EXI_BBA_ID 0x04020200 + +#define OK 0 +#define NOK -1 + +typedef int(*test_f)(void); + +typedef enum { + Ok = OK, + ExiGetIdFailed, + Nok = NOK, +} error_code_t; + +typedef struct { + test_f test; + char test_name[32]; +} test_entry_t; + +#define TEST_ENTRY(name) { (name), #name } + +test_entry_t tests[1] = { + TEST_ENTRY(test_bba_get_id) +}; + +int main(int argc, char **argv) { + xfb = initialise(); + + printf("\nHello World!\n"); + + int current_test = 0; + int nr_tests = sizeof(tests) / sizeof(tests[0]); + + while(1) { + + VIDEO_WaitVSync(); + PAD_ScanPads(); + + int buttonsDown = PAD_ButtonsDown(0); + + if( buttonsDown & PAD_BUTTON_A ) { + printf("Button A pressed.\n"); + } + + if (buttonsDown & PAD_BUTTON_START) { + exit(0); + } + + if(current_test < nr_tests) { + test_entry_t t = tests[current_test++]; + int result = t.test(); + printf("Test: %s Result %s", t.test_name, result == OK ? "OK" : "NOK"); + current_test++; + } + } + + return 0; +} + +void * initialise() { + void *framebuffer; + + VIDEO_Init(); + PAD_Init(); + + rmode = VIDEO_GetPreferredMode(NULL); + + framebuffer = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + console_init(framebuffer,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ); + + VIDEO_Configure(rmode); + VIDEO_SetNextFramebuffer(framebuffer); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); + + return framebuffer; +} + +error_code_t test_bba_get_id() { + + u32 exi_id = 0; + EXI_GetID(EXI_CHANNEL_0, EXI_DEVICE_2, &exi_id); + return exi_id == EXI_BBA_ID ? Ok : ExiGetIdFailed; +} + diff --git a/re-bba/.gitignore b/re-bba/.gitignore new file mode 100644 index 0000000..f6a0f81 --- /dev/null +++ b/re-bba/.gitignore @@ -0,0 +1 @@ +*.vcd diff --git a/re-bba/LEDBlinker.py b/re-bba/LEDBlinker.py new file mode 100644 index 0000000..b5f44ed --- /dev/null +++ b/re-bba/LEDBlinker.py @@ -0,0 +1,22 @@ +from amaranth import * + +class LEDBlinker(Elaboratable): + def elaborate(self, platform): + m = Module() + + led = platform.request("led") + + half_freq = int(platform.default_clk_frequency // 2) + timer = Signal(range(half_freq + 1)) + + with m.If(timer == half_freq): + m.d.sync += led.eq(~led) + m.d.sync += timer.eq(0) + with m.Else(): + m.d.sync += timer.eq(timer + 1) + + return m + +from amaranth_boards.icebreaker import * + +ICEBreakerPlatform().build(LEDBlinker(), do_program=True) \ No newline at end of file diff --git a/re-bba/amaranth_boards/__init__.py b/re-bba/amaranth_boards/__init__.py new file mode 100644 index 0000000..6eb2e59 --- /dev/null +++ b/re-bba/amaranth_boards/__init__.py @@ -0,0 +1,11 @@ +try: + try: + from importlib import metadata as importlib_metadata # py3.8+ stdlib + except ImportError: + import importlib_metadata # py3.7- shim + __version__ = importlib_metadata.version(__package__) +except ImportError: + # No importlib_metadata. This shouldn't normally happen, but some people prefer not installing + # packages via pip at all, instead using PYTHONPATH directly or copying the package files into + # `lib/pythonX.Y/site-packages`. Although not a recommended way, we still try to support it. + __version__ = "unknown" # :nocov: diff --git a/re-bba/amaranth_boards/__pycache__/__init__.cpython-310.pyc b/re-bba/amaranth_boards/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..2c56ce6 Binary files /dev/null and b/re-bba/amaranth_boards/__pycache__/__init__.cpython-310.pyc differ diff --git a/re-bba/amaranth_boards/__pycache__/icebreaker.cpython-310.pyc b/re-bba/amaranth_boards/__pycache__/icebreaker.cpython-310.pyc new file mode 100644 index 0000000..8787bb5 Binary files /dev/null and b/re-bba/amaranth_boards/__pycache__/icebreaker.cpython-310.pyc differ diff --git a/re-bba/amaranth_boards/alchitry_au.py b/re-bba/amaranth_boards/alchitry_au.py new file mode 100644 index 0000000..49a7a51 --- /dev/null +++ b/re-bba/amaranth_boards/alchitry_au.py @@ -0,0 +1,76 @@ +import os +import subprocess +import shutil + +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["AlchitryAuPlatform"] + + +def find_loader(): + loader_prgm = os.environ.get("ALCHITRY_LOADER", shutil.which("loader")) + if loader_prgm is None: + raise EnvironmentError("Could not find Alchrity Loader. Place " + "it directly in PATH or specify path explicitly via the " + "ALCHITRY_LOADER environment variable") + bridge_bin = os.environ.get("ALCHITRY_BRIDGE_BIN", os.path.join(os.path.dirname(loader_prgm), "au_loader.bin")) + return (loader_prgm, bridge_bin) + + +class AlchitryAuPlatform(Xilinx7SeriesPlatform): + device = "XC7A35T" # Artix 7 33K LEs + package = "FTG256" + speed = "1" + default_clk = "clk100" + resources = [ + Resource("clk100", 0, Pins("N14", dir="i"), + Clock(10e7), Attrs(IOSTANDARD="LVCMOS33")), + + # On-Board LED Array + *LEDResources( + pins="K13 K12 L14 L13 M16 M14 M12 N16", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + Resource("usb", 0, + Subsignal("usb_tx", Pins("P16", dir="o")), + Subsignal("usb_rx", Pins("P15", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ), + + # TODO: This is untested + DDR3Resource(0, + rst_n="D13", clk_p="G14", clk_n="F14", clk_en="D15", cs_n="D16", we_n="E11", ras_n="D14", cas_n="D14", + a="F12 G16 G15 E16 H11 G12 H16 H12 H16 H13 E12 H14 F13 J15", + ba="E13 F15 E15", + dqs_p="B15 A15", dqs_n="B9 A10", + dq="A13 B16 B14 C11 C13 C16 C12 C14 D8 B11 C8 B10 A12 A8 B12 A9", + dm="A14 C9", odt="G11", + diff_attrs=Attrs(IOSTANDARD="LVDS"), + attrs=Attrs(IOSTANDARD="LVCMOS15")), + ] + + connectors = [ + Connector("bank", 0, "T8 T7 T5 R5 R8 P8 L2 L3 J1 K1 H1 H2 G1 G2 K5 E6 " + "T10 T9 R6 R7 P9 N9 K2 K3 J4 J5 H3 J3 H4 H5 N6 M6 "), + Connector("bank", 1, "D1 E2 A2 B2 E1 F2 F3 F4 A3 B4 A4 A5 B5 B6 A7 B7 " + "B1 C1 C2 C3 D3 E3 C4 D4 G4 G5 E5 F5 D5 D6 C6 C7 "), + Connector("bank", 2, "T13 R13 T12 R12 R11 R10 N2 N3 P3 P4 M4 L4 N4 M5 L5 P5 " + "P11 P10 N12 N11 P13 N13 M1 M2 P1 N1 R1 R2 T2 R3 T3 T4 "), + Connector("bank", 3, "L14 L13 M12 N16 R16 R15 P14 M15 P16 P15 - - - - - - " + "K13 K12 M16 M14 T16 T14 N14 - - - - - - - - - ") + ] + + def toolchain_program(self, products, name): + (loader, bridge_bin) = find_loader() + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([loader, "-e", "-f", bitstream_filename, + "-p", bridge_bin + ]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + AlchitryAuPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/arrow_deca.py b/re-bba/amaranth_boards/arrow_deca.py new file mode 100644 index 0000000..5fd4245 --- /dev/null +++ b/re-bba/amaranth_boards/arrow_deca.py @@ -0,0 +1,88 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["ArrowDECAPlatform"] + + +class ArrowDECAPlatform(IntelPlatform): + device = "10M50DA" # MAX 10 + package = "F484" + speed = "C6" + suffix = "GES" + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("M8", dir="i"), + Clock(50e6), Attrs(io_standard="2.5 V")), + Resource("clk50", 1, Pins("P11", dir="i"), + Clock(50e6), Attrs(io_standard="3.3 V")), + Resource("clk50", 2, Pins("N15", dir="i"), + Clock(50e6), Attrs(io_standard="1.5 V")), + Resource("clk10", 0, Pins("M9", dir="i"), + Clock(10e6), Attrs(io_standard="2.5 V")), + + *LEDResources( + pins="C7 C8 A6 B7 C4 A5 B4 C5", + invert=True, + attrs=Attrs(io_standard="1.2 V")), + *ButtonResources( + pins="H21 H22", + invert=True, + attrs=Attrs(io_standard="1.5 V")), + *SwitchResources( + pins="J21 J22", + attrs=Attrs(io_standard="1.5 V")), + ] + connectors = [ + Connector("gpio", 0, + "W18 Y18 Y19 AA17 AA20 AA19 AB21 AB20 AB19 Y16 V16 " + "AB18 V15 W17 AB17 AA16 AB16 W16 AB15 W15 Y14 AA15 " + "AB14 AA14 AB13 AA13 AB12 AA12 AB11 AA11 AB10 Y13 Y11 " + "W13 W12 W11 V12 V11 V13 V14 Y17 W14 U15 R13"), + Connector("gpio", 1, + "Y5 Y6 W6 W7 W8 V8 AB8 V7 R11 AB7 AB6 " + "AA7 AA6 Y7 V10 U7 W9 W5 R9 W4 P9 V17 " + "W3"), + ] + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename]) + + @property + def file_templates(self): + # Configure the voltages of the I/O banks by appending the global + # assignments to the template. However, we create our own copy of the + # file templates before modifying them to avoid modifying the original. + return { + **super().file_templates, + "{{name}}.qsf": + super().file_templates.get("{{name}}.qsf") + + r""" + set_global_assignment -name IOBANK_VCCIO 2.5V -section_id 1A + set_global_assignment -name IOBANK_VCCIO 2.5V -section_id 1B + set_global_assignment -name IOBANK_VCCIO 2.5V -section_id 2 + set_global_assignment -name IOBANK_VCCIO 3.3V -section_id 3 + set_global_assignment -name IOBANK_VCCIO 3.3V -section_id 4 + set_global_assignment -name IOBANK_VCCIO 1.5V -section_id 5 + set_global_assignment -name IOBANK_VCCIO 1.5V -section_id 6 + set_global_assignment -name IOBANK_VCCIO 1.8V -section_id 7 + set_global_assignment -name IOBANK_VCCIO 1.2V -section_id 8 + + set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON + set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF + set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF + set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF + """ + } + + +if __name__ == "__main__": + from .test.blinky import Blinky + ArrowDECAPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/arty_a7.py b/re-bba/amaranth_boards/arty_a7.py new file mode 100644 index 0000000..3032349 --- /dev/null +++ b/re-bba/amaranth_boards/arty_a7.py @@ -0,0 +1,230 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["ArtyA7_35Platform", "ArtyA7_100Platform"] + + +class _ArtyA7Platform(Xilinx7SeriesPlatform): + package = "csg324" + speed = "1L" + default_clk = "clk100" + default_rst = "rst" + resources = [ + Resource("clk100", 0, Pins("E3", dir="i"), + Clock(100e6), Attrs(IOSTANDARD="LVCMOS33")), + Resource("rst", 0, PinsN("C2", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + + *LEDResources(pins="H5 J5 T9 T10", attrs=Attrs(IOSTANDARD="LVCMOS33")), + + RGBLEDResource(0, r="G6", g="F6", b="E1", attrs=Attrs(IOSTANDARD="LVCMOS33")), + RGBLEDResource(1, r="G3", g="J4", b="G4", attrs=Attrs(IOSTANDARD="LVCMOS33")), + RGBLEDResource(2, r="J3", g="J2", b="H4", attrs=Attrs(IOSTANDARD="LVCMOS33")), + RGBLEDResource(3, r="K1", g="H6", b="K2", attrs=Attrs(IOSTANDARD="LVCMOS33")), + + *ButtonResources(pins="D9 C9 B9 B8 ", attrs=Attrs(IOSTANDARD="LVCMOS33")), + *SwitchResources(pins="A8 C11 C10 A10", attrs=Attrs(IOSTANDARD="LVCMOS33")), + + UARTResource(0, + rx="A9", tx="D10", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + + SPIResource(0, + cs_n="C1", clk="F1", copi="H1", cipo="G1", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + + Resource("i2c", 0, + Subsignal("scl", Pins("L18", dir="io")), + Subsignal("sda", Pins("M18", dir="io")), + Subsignal("scl_pullup", Pins("A14", dir="o")), + Subsignal("sda_pullup", Pins("A13", dir="o")), + Attrs(IOSTANDARD="LVCMOS33") + ), + + *SPIFlashResources(0, + cs_n="L13", clk="L16", copi="K17", cipo="K18", wp_n="L14", hold_n="M14", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + + Resource("ddr3", 0, + Subsignal("rst", PinsN("K6", dir="o")), + Subsignal("clk", DiffPairs("U9", "V9", dir="o"), Attrs(IOSTANDARD="DIFF_SSTL135")), + Subsignal("clk_en", Pins("N5", dir="o")), + Subsignal("cs", PinsN("U8", dir="o")), + Subsignal("we", PinsN("P5", dir="o")), + Subsignal("ras", PinsN("P3", dir="o")), + Subsignal("cas", PinsN("M4", dir="o")), + Subsignal("a", Pins("R2 M6 N4 T1 N6 R7 V6 U7 R8 V7 R6 U6 T6 T8", dir="o")), + Subsignal("ba", Pins("R1 P4 P2", dir="o")), + Subsignal("dqs", DiffPairs("N2 U2", "N1 V2", dir="io"), + Attrs(IOSTANDARD="DIFF_SSTL135")), + Subsignal("dq", Pins("K5 L3 K3 L6 M3 M1 L4 M2 V4 T5 U4 V5 V1 T3 U3 R3", dir="io"), + Attrs(IN_TERM="UNTUNED_SPLIT_40")), + Subsignal("dm", Pins("L1 U1", dir="o")), + Subsignal("odt", Pins("R5", dir="o")), + Attrs(IOSTANDARD="SSTL135", SLEW="FAST"), + ), + + Resource("eth_clk25", 0, Pins("G18", dir="o"), + Clock(25e6), Attrs(IOSTANDARD="LVCMOS33")), + Resource("eth_clk50", 0, Pins("G18", dir="o"), + Clock(50e6), Attrs(IOSTANDARD="LVCMOS33")), + Resource("eth_mii", 0, + Subsignal("rst", PinsN("C16", dir="o")), + Subsignal("mdio", Pins("K13", dir="io")), + Subsignal("mdc", Pins("F16", dir="o")), + Subsignal("tx_clk", Pins("H16", dir="i")), + Subsignal("tx_en", Pins("H15", dir="o")), + Subsignal("tx_data", Pins("H14 J14 J13 H17", dir="o")), + Subsignal("rx_clk", Pins("F15", dir="i")), + Subsignal("rx_dv", Pins("G16", dir="i"), Attrs(PULLDOWN="TRUE")), # strap to select MII + Subsignal("rx_er", Pins("C17", dir="i")), + Subsignal("rx_data", Pins("D18 E17 E18 G17", dir="i")), + Subsignal("col", Pins("D17", dir="i")), + Subsignal("crs", Pins("G14", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ), + Resource("eth_rmii", 0, + Subsignal("rst", PinsN("C16", dir="o")), + Subsignal("mdio", Pins("K13", dir="io")), + Subsignal("mdc", Pins("F16", dir="o")), + Subsignal("tx_en", Pins("H15", dir="o")), + Subsignal("tx_data", Pins("H14 J14", dir="o")), + Subsignal("rx_crs_dv", Pins("G14", dir="i")), + Subsignal("rx_dv", Pins("G16", dir="i"), Attrs(PULLUP="TRUE")), # strap to select RMII + Subsignal("rx_er", Pins("C17", dir="i")), + Subsignal("rx_data", Pins("D18 E17", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ) + ] + connectors = [ + Connector("pmod", 0, "G13 B11 A11 D12 - - D13 B18 A18 K16 - -"), # JA + Connector("pmod", 1, "E15 E16 D15 C15 - - J17 J18 K15 J15 - -"), # JB + Connector("pmod", 2, "U12 V12 V10 V11 - - U14 V14 T13 U13 - -"), # JC + Connector("pmod", 3, " D4 D3 F4 F3 - - E2 D2 H2 G2 - -"), # JD + + Connector("ck_io", 0, { + # Outer Digital Header + "io0": "V15", + "io1": "U16", + "io2": "P14", + "io3": "T11", + "io4": "R12", + "io5": "T14", + "io6": "T15", + "io7": "T16", + "io8": "N15", + "io9": "M16", + "io10": "V17", + "io11": "U18", + "io12": "R17", + "io13": "P17", + + # Inner Digital Header + "io26": "U11", + "io27": "V16", + "io28": "M13", + "io29": "R10", + "io30": "R11", + "io31": "R13", + "io32": "R15", + "io33": "P15", + "io34": "R16", + "io35": "N16", + "io36": "N14", + "io37": "U17", + "io38": "T18", + "io39": "R18", + "io40": "P18", + "io41": "N17", + + # Outer Analog Header as Digital IO + "a0": "F5", + "a1": "D8", + "a2": "C7", + "a3": "E7", + "a4": "D7", + "a5": "D5", + + # Inner Analog Header as Digital IO + "io20": "B7", + "io21": "B6", + "io22": "E6", + "io23": "E5", + "io24": "A4", + "io25": "A3" + }), + Connector("xadc", 0, { + # Outer Analog Header + "vaux4_n": "C5", + "vaux4_p": "C6", + "vaux5_n": "A5", + "vaux5_p": "A6", + "vaux6_n": "B4", + "vaux6_p": "C4", + "vaux7_n": "A1", + "vaux7_p": "B1", + "vaux15_n": "B2", + "vaux15_p": "B3", + "vaux0_n": "C14", + "vaux0_p": "D14", + + # Inner Analog Header + "vaux12_n": "B7", + "vaux12_p": "B6", + "vaux13_n": "E6", + "vaux13_p": "E5", + "vaux14_n": "A4", + "vaux14_p": "A3", + + # Power Measurements + "vsnsuv_n": "B17", + "vsnsuv_p": "B16", + "vsns5v0_n": "B12", + "vsns5v0_p": "C12", + "isns5v0_n": "F14", + "isns5v0_n": "F13", + "isns0v95_n": "A16", + "isns0v95_n": "A15", + }) + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = { + "script_before_bitstream": + "set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]", + "script_after_bitstream": + "write_cfgmem -force -format bin -interface spix4 -size 16 " + "-loadbit \"up 0x0 {name}.bit\" -file {name}.bin".format(name=name), + "add_constraints": + """ + set_property INTERNAL_VREF 0.675 [get_iobanks 34] + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + """ + } + return super().toolchain_prepare(fragment, name, **overrides, **kwargs) + + def toolchain_program(self, products, name): + xc3sprog = os.environ.get("XC3SPROG", "xc3sprog") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.run([xc3sprog, "-c", "nexys4", bitstream_filename], check=True) + + +class ArtyA7_35Platform(_ArtyA7Platform): + device = "xc7a35ti" + + +class ArtyA7_100Platform(_ArtyA7Platform): + device = "xc7a100ti" + + +if __name__ == "__main__": + from .test.blinky import * + ArtyA7_35Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/arty_s7.py b/re-bba/amaranth_boards/arty_s7.py new file mode 100644 index 0000000..5122617 --- /dev/null +++ b/re-bba/amaranth_boards/arty_s7.py @@ -0,0 +1,235 @@ +import os +import textwrap +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["ArtyS7_25Platform", "ArtyS7_50Platform"] + + +class _ArtyS7Platform(Xilinx7SeriesPlatform): + package = "csga324" + speed = "1" + default_clk = "clk100" + default_rst = "rst" + resources = [ + Resource("clk100", 0, Pins("R2", dir="i"), + Clock(100e6), Attrs(IOSTANDARD="SSTL135")), + Resource("rst", 0, PinsN("C18", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + + *LEDResources(pins="E18 F13 E13 H15", attrs=Attrs(IOSTANDARD="LVCMOS33")), + + RGBLEDResource(0, r="J15", g="G17", b="F15", attrs=Attrs(IOSTANDARD="LVCMOS33")), + RGBLEDResource(1, r="E15", g="F18", b="E14", attrs=Attrs(IOSTANDARD="LVCMOS33")), + + *ButtonResources(pins="G15 K16 J16 H13", attrs=Attrs(IOSTANDARD="LVCMOS33")), + *SwitchResources(pins="H14 H18 G18 M5", attrs=Attrs(IOSTANDARD="LVCMOS33")), + + UARTResource(0, + rx="V12", tx="R12", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + + SPIResource(0, + cs_n="H16", clk="G16", copi="H17", cipo="K14", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + + I2CResource(0, + scl="J14", sda="J13", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + + *SPIFlashResources(0, + cs_n="M13", clk="D11", copi="K17", cipo="K18", wp_n="L14", hold_n="M15", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + + Resource("ddr3", 0, + Subsignal("rst", PinsN("J6", dir="o")), + Subsignal("clk", DiffPairs("R5", "T4", dir="o"), Attrs(IOSTANDARD="DIFF_SSTL135")), + Subsignal("clk_en", Pins("T2", dir="o")), + Subsignal("cs", PinsN("R3", dir="o")), + Subsignal("we", PinsN("P7", dir="o")), + Subsignal("ras", PinsN("U1", dir="o")), + Subsignal("cas", PinsN("V3", dir="o")), + Subsignal("a", Pins("U2 R4 V2 V4 T3 R7 V6 T6 U7 V7 P6 T5 R6 U6", dir="o")), + Subsignal("ba", Pins("V5 T1 U3", dir="o")), + Subsignal("dqs", DiffPairs("K1 N3", "L1 N2", dir="io"), + Attrs(IOSTANDARD="DIFF_SSTL135")), + Subsignal("dq", Pins("K2 K3 L4 M6 K6 M4 L5 L6 N4 R1 N1 N5 M2 P1 M1 P2", dir="io"), + Attrs(IN_TERM="UNTUNED_SPLIT_40")), + Subsignal("dm", Pins("K4 M3", dir="o")), + Subsignal("odt", Pins("P5", dir="o")), + Attrs(IOSTANDARD="SSTL135", SLEW="FAST"), + ), + ] + connectors = [ + Connector("pmod", 0, "L17 L18 M14 N14 - - M16 M17 M18 N18 - -"), # JA + Connector("pmod", 1, "P17 P18 R18 T18 - - P14 P15 N15 P16 - -"), # JB + Connector("pmod", 2, "U15 V16 U17 U18 - - U16 P13 R13 V14 - -"), # JC + Connector("pmod", 3, "V15 U12 V13 T12 - - T13 R11 T11 U11 - -"), # JD + + Connector("ck_io", 0, { + # Outer Digital Header + "io0": "L13", + "io1": "N13", + "io2": "L16", + "io3": "R14", + "io4": "T14", + "io5": "R16", + "io6": "R17", + "io7": "V17", + "io8": "R15", + "io9": "T15", + "io10": "H16", + "io11": "H17", + "io12": "K14", + "io13": "G16", + + # Inner Digital Header + "io26": "U11", + "io27": "T11", + "io28": "R11", + "io29": "T13", + "io30": "T12", + "io31": "V13", + "io32": "U12", + "io33": "V15", + "io34": "V14", + "io35": "R13", + "io36": "P13", + "io37": "U16", + "io38": "U18", + "io39": "U17", + "io40": "V16", + "io41": "U15", + + # Outer Analog Header as Digital IO + "a0": "G13", + "a1": "B16", + "a2": "A16", + "a3": "C13", + "a4": "C14", + "a5": "D18", + + # Inner Analog Header as Digital IO + "io20": "B14", + "io21": "A14", + "io22": "D16", + "io23": "D17", + "io24": "D14", + "io25": "D15" + }), + Connector("xadc", 0, { + # Outer Analog Header + "vaux0_p": "B13", + "vaux0_n": "A13", + "vaux1_p": "B15", + "vaux1_n": "A15", + "vaux9_p": "E12", + "vaux9_n": "D12", + "vaux2_p": "B17", + "vaux2_n": "A17", + "vaux10_p": "C17", + "vaux10_n": "B18", + "vaux11_p": "E16", + "vaux11_n": "E17", + + # Inner Analog Header + "vaux8_p": "B14", + "vaux8_n": "A14", + "vaux3_p": "D16", + "vaux3_n": "D17", + }) + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = { + "script_before_bitstream": + "set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]", + "script_after_bitstream": + "write_cfgmem -force -format mcs -interface spix4 -size 16 " + "-loadbit \"up 0x0 {name}.bit\" -file {name}.mcs".format(name=name), + "add_constraints": + "set_property INTERNAL_VREF 0.675 [get_iobanks 34]" + } + return super().toolchain_prepare(fragment, name, **overrides, **kwargs) + + def toolchain_program(self, product, name, *, programmer="vivado", flash=True): + assert programmer in ("vivado", "openocd") + + if programmer == "vivado": + if flash: + # It does not appear possible to reset the FPGA via TCL after + # flash programming. + with product.extract("{}.bin".format(name)) as bitstream_filename: + cmd = textwrap.dedent(""" + open_hw_manager + connect_hw_server + open_hw_target + current_hw_device [lindex [get_hw_devices] 0] + create_hw_cfgmem -hw_device [current_hw_device] s25fl128sxxxxxx0-spi-x1_x2_x4 + set_property PROGRAM.FILES {{{}}} [current_hw_cfgmem] + set_property PROGRAM.ADDRESS_RANGE {{use_file}} [current_hw_cfgmem] + set_property PROGRAM.BLANK_CHECK 1 [current_hw_cfgmem] + set_property PROGRAM.ERASE 1 [current_hw_cfgmem] + set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem] + set_property PROGRAM.VERIFY 1 [current_hw_cfgmem] + create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]] + program_hw_devices + program_hw_cfgmem + close_hw_manager + puts "Vivado TCL cannot reset boards. Reset or power-cycle your board now." + """).format(bitstream_filename).encode("utf-8") + subprocess.run(["vivado", "-nolog", "-nojournal", "-mode", "tcl"], input=cmd, check=True) + else: + with product.extract("{}.bit".format(name)) as bitstream_filename: + cmd = textwrap.dedent(""" + open_hw_manager + connect_hw_server + open_hw_target + current_hw_device [lindex [get_hw_devices] 0] + set_property PROGRAM.FILE {{{}}} [current_hw_device] + program_hw_devices + close_hw_manager + """).format(bitstream_filename).encode("utf-8") + subprocess.run(["vivado", "-nolog", "-nojournal", "-mode", "tcl"], input=cmd, check=True) + else: + openocd = os.environ.get("OPENOCD", "openocd") + # In order, OpenOCD searches these directories for files: + # * $HOME/.openocd if $HOME exists (*nix) + # * Path pointed to by $OPENOCD_SCRIPTS if $OPENOCD_SCRIPTS exists + # * $APPDATA/OpenOCD on Windows + # Place the bscan_spi_xc7s50.bit proxy bitstream under a directory + # named "proxy" in one of the above directories so OpenOCD finds it. + if flash: + with product.extract("{}.bin".format(name)) as fn: + subprocess.check_call([openocd, "-f", "board/arty_s7.cfg", + "-c", """init; + jtagspi_init 0 [find proxy/bscan_spi_xc7s50.bit]; + jtagspi_program {} 0; + xc7_program xc7.tap; + shutdown""".format(fn)]) + else: + with product.extract("{}.bit".format(name)) as fn: + subprocess.check_call(["openocd", "-f", "board/arty_s7.cfg", + "-c", """init; + pld load 0 {}; + shutdown""".format(fn)]) + + +class ArtyS7_50Platform(_ArtyS7Platform): + device = "xc7s50" + + +class ArtyS7_25Platform(_ArtyS7Platform): + device = "xc7s25" + + +if __name__ == "__main__": + from .test.blinky import * + ArtyS7_25Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/arty_z7.py b/re-bba/amaranth_boards/arty_z7.py new file mode 100644 index 0000000..48b75e0 --- /dev/null +++ b/re-bba/amaranth_boards/arty_z7.py @@ -0,0 +1,175 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["ArtyZ720Platform"] + + +class ArtyZ720Platform(Xilinx7SeriesPlatform): + device = "xc7z020" + package = "clg400" + speed = "1" + default_clk = "clk125" + resources = [ + Resource("clk125", 0, + Pins("H16", dir="i"), Clock(125e6), Attrs(IOSTANDARD="LVCMOS33")), + + *SwitchResources( + pins="M20 M19", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + RGBLEDResource(0, + r="N15", g="G17", b="L15", # LD4 + attrs=Attrs(IOSTANDARD="LVCMOS33")), + RGBLEDResource(1, # LD5 + r="M15", g="L14", b="G14", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + *LEDResources( + pins="R14 P14 N16 M14", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + *ButtonResources( + pins="D19 D20 L20 L19", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + Resource("audio", 0, + Subsignal("pwm", Pins("R18", dir="o")), + Subsignal("sd", PinsN("T17", dir="o")), + Attrs(IOSTANDARD="LVCMOS33")), + + Resource("crypto_sda", 0, # ATSHA204A + Pins("J15", dir="io"), + Attrs(IOSTANDARD="LVCMOS33")), + + Resource("hdmi_rx", 0, # J10 + Subsignal("cec", Pins("H17", dir="io")), + Subsignal("clk", DiffPairs("N18", "P19", dir="i"), + Attrs(IOSTANDARD="TMDS_33")), + Subsignal("d", DiffPairs("V20 T20 N20", "W20 U20 P20", dir="i"), + Attrs(IOSTANDARD="TMDS_33")), + Subsignal("hpd", Pins("T19", dir="o")), + Subsignal("scl", Pins("U14", dir="io")), + Subsignal("sda", Pins("U15", dir="io")), + Attrs(IOSTANDARD="LVCMOS33")), + + Resource("hdmi_tx", 0, # J11 + Subsignal("cec", Pins("G15", dir="io")), + Subsignal("clk", DiffPairs("L16", "L17", dir="o"), + Attrs(IOSTANDARD="TMDS_33")), + Subsignal("d", DiffPairs("K17 K19 J18", "K18 J19 H18", dir="o"), + Attrs(IOSTANDARD="TMDS_33")), + Subsignal("hpd", PinsN("R19", dir="i")), + Subsignal("scl", Pins("M17", dir="io")), + Subsignal("sda", Pins("M18", dir="io")), + Attrs(IOSTANDARD="LVCMOS33")) + ] + connectors = [ + Connector("pmod", 0, "Y18 Y19 Y16 Y17 - - U18 U19 W18 W19 - -"), # JA + Connector("pmod", 1, "W14 Y14 T11 T10 - - V16 W16 V12 W13 - -"), # JB + + Connector("ck_io", 0, { + # Outer Digital Header + "io0": "T14", + "io1": "U12", + "io2": "U13", + "io3": "V13", + "io4": "V15", + "io5": "T15", + "io6": "R16", + "io7": "U17", + "io8": "V17", + "io9": "V18", + "io10": "T16", + "io11": "R17", + "io12": "P18", + "io13": "N17", + + # Inner Digital Header + "io26": "U5", + "io27": "V5", + "io28": "V6", + "io29": "U7", + "io30": "V7", + "io31": "U8", + "io32": "V8", + "io33": "V10", + "io34": "W10", + "io35": "W6", + "io36": "Y6", + "io37": "Y7", + "io38": "W8", + "io39": "Y8", + "io40": "W9", + "io41": "Y9", + + # Outer Analog Header as Digital IO + "a0": "Y11", + "a1": "Y12", + "a2": "W11", + "a3": "V11", + "a4": "T5", + "a5": "U10", + + # Inner Analog Header as Digital IO + "a6": "F19", + "a7": "F20", + "a8": "C20", + "a9": "B20", + "a10": "B19", + "a11": "A20", + + # Misc. + "a": "Y13" + }), + + Connector("ck_spi", 0, { + "cipo": "W15", + "copi": "T12", + "sck": "H15", + "ss": "F16" + }), + + Connector("ck_i2c", 0, { + "scl": "P16", + "sda": "P15" + }), + + Connector("xadc", 0, { + # Outer Analog Header + "vaux1_n": "D18", + "vaux1_p": "E17", + "vaux9_n": "E19", + "vaux9_p": "E18", + "vaux6_n": "J14", + "vaux6_p": "K14", + "vaux15_n": "J16", + "vaux15_p": "K16", + "vaux5_n": "H20", + "vaux5_p": "J20", + "vaux13_n": "G20", + "vaux13_p": "G19", + + # Inner Analog Header + "vaux12_n": "F20", + "vaux12_p": "F19", + "vaux0_n": "B20", + "vaux0_p": "C20", + "vaux8_n": "A20", + "vaux8_p": "B19" + }) + ] + + def toolchain_program(self, products, name, **kwargs): + xc3sprog = os.environ.get("XC3SPROG", "xc3sprog") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.run([xc3sprog, "-c", "jtaghs1_fast", "-p", "1", bitstream_filename], check=True) + + +if __name__ == "__main__": + from .test.blinky import * + ArtyZ720Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/atlys.py b/re-bba/amaranth_boards/atlys.py new file mode 100644 index 0000000..96b5a26 --- /dev/null +++ b/re-bba/amaranth_boards/atlys.py @@ -0,0 +1,224 @@ +import subprocess +import textwrap + +from amaranth.build import * +from amaranth.vendor.xilinx_spartan_3_6 import * +from .resources import * + + +__all__ = ["AtlysPlatform"] + + +class AtlysPlatform(XilinxSpartan6Platform): + """Platform file for Digilent Atlys Spartan 6 board. + https://reference.digilentinc.com/reference/programmable-logic/atlys/start""" + + device = "xc6slx45" + package = "csg324" + speed = "3" + + def __init__(self, *, JP12="2V5", **kwargs): + super().__init__(**kwargs) + + assert JP12 in ["2V5", "3V3"] + self._JP12 = JP12 + + def bank2_iostandard(self): + return "LVCMOS25" if self._JP12 == "2V5" else "LVCMOS33" + + default_clk = "clk100" + default_rst = "rst" + resources = [ + Resource("rst", 0, PinsN("T15", dir="i"), Attrs(IOSTANDARD=bank2_iostandard)), # RESET + Resource("clk100", 0, Pins("L15", dir="i"), + Clock(100e6), Attrs(IOSTANDARD="LVCMOS33")), # GCLK + + Resource("led", 0, Pins("U18", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD0 + Resource("led", 1, Pins("M14", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD1 + Resource("led", 2, Pins("N14", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD2 + Resource("led", 3, Pins("L14", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD3 + Resource("led", 4, Pins("M13", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD4 + Resource("led", 5, Pins("D4", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD5 + Resource("led", 6, Pins("P16", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), # LD6 + Resource("led", 7, Pins("N12", dir="o"), Attrs(IOSTANDARD=bank2_iostandard)), # LD7 + + Resource("button", 0, Pins("N4", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTNU + Resource("button", 1, Pins("P4", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTNL + Resource("button", 2, Pins("P3", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTND + Resource("button", 3, Pins("F6", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTNR + Resource("button", 4, Pins("F5", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # BTNC + + Resource("switch", 0, Pins("A10", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), # SW0 + Resource("switch", 1, Pins("D14", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), # SW1 + Resource("switch", 2, Pins("C14", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), # SW2 + Resource("switch", 3, Pins("P15", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), # SW3 + Resource("switch", 4, Pins("P12", dir="i"), Attrs(IOSTANDARD=bank2_iostandard)), # SW4 + Resource("switch", 5, Pins("R5", dir="i"), Attrs(IOSTANDARD=bank2_iostandard)), # SW5 + Resource("switch", 6, Pins("T5", dir="i"), Attrs(IOSTANDARD=bank2_iostandard)), # SW6 + Resource("switch", 7, Pins("E4", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), # SW7 + + UARTResource(0, rx="A16", tx="B16", attrs=Attrs(IOSTANDARD="LVCMOS33")), # J17/UART + + PS2Resource(0, # PS/2 keyboard interface converted from J13 "HOST" USB connector + clk="P17", dat="N15", attrs=Attrs(IOSTANDARD="LVCMOS33")), + PS2Resource(1, # PS/2 mouse interface converted from J13 "HOST" USB connector + clk="N18", dat="P18", attrs=Attrs(IOSTANDARD="LVCMOS33")), + + *SPIFlashResources(0, + cs_n="AE14", clk="AH18", copi="AF14", cipo="AF20", wp_n="AG21", hold_n="AG17", + attrs=Attrs(IOSTANDARD="LVCMOS25", SLEW="FAST"), + ), + + Resource("ddr2", 0, + Subsignal("clk", DiffPairs("G3", "G1", dir="o"), + Attrs(IOSTANDARD="DIFF_SSTL18_II", IN_TERM="NONE")), + Subsignal("clk_en", Pins("H7", dir="o")), + Subsignal("we", PinsN("E3", dir="o")), + Subsignal("ras", PinsN("L5", dir="o")), + Subsignal("cas", PinsN("K5", dir="o")), + Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6", dir="o")), + Subsignal("ba", Pins("F2 F1 E1", dir="o")), + Subsignal("dqs", DiffPairs("P2 L4", "P1 L3", dir="o"), + Attrs(IOSTANDARD="DIFF_SSTL18_II")), + Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1", dir="io")), + Subsignal("dm", Pins("K4 K3", dir="o")), + Subsignal("odt", Pins("K6", dir="o")), + Attrs(IOSTANDARD="SSTL18_II", SLEW="FAST"), + ), + + Resource("eth_gmii", 0, + Subsignal("rst", PinsN("G13", dir="o")), + Subsignal("int", PinsN("L16", dir="o")), + Subsignal("mdio", Pins("N17", dir="io")), + Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz + Subsignal("gtx_clk", Pins("L12", dir="o")), + Subsignal("tx_clk", Pins("K16", dir="i")), + Subsignal("tx_en", Pins("H15", dir="o")), + Subsignal("tx_er", Pins("G18", dir="o")), + Subsignal("tx_data", Pins("H16 H13 K14 K13 J13 G14 H12 K12", dir="o")), + Subsignal("rx_clk", Pins("K15", dir="i")), + Subsignal("rx_dv", Pins("F17", dir="i"), Attrs(PULLDOWN="TRUE")), + Subsignal("rx_er", Pins("F18", dir="i")), + Subsignal("rx_data", Pins("G16 H14 E16 F15 F14 E18 D16 D17", dir="i")), + Subsignal("col", Pins("C17", dir="i")), + Subsignal("crs", Pins("C18", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ), + Resource("eth_rgmii", 0, + Subsignal("rst", PinsN("G13", dir="o")), + Subsignal("int", PinsN("L16", dir="o")), + Subsignal("mdio", Pins("N17", dir="io")), + Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz + Subsignal("tx_clk", Pins("L12", dir="o")), + Subsignal("tx_ctl", Pins("H15", dir="o")), + Subsignal("tx_data", Pins("H16 H13 K14 K13", dir="o")), + Subsignal("rx_clk", Pins("K15", dir="i")), + Subsignal("rx_ctl", Pins("F17", dir="i"), Attrs(PULLDOWN="TRUE")), + Subsignal("rx_data", Pins("G16 H14 E16 F15", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ), + Resource("eth_mii", 0, + Subsignal("rst", PinsN("G13", dir="o")), + Subsignal("int", PinsN("L16", dir="o")), + Subsignal("mdio", Pins("N17", dir="io")), + Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz + Subsignal("tx_clk", Pins("K16", dir="i")), + Subsignal("tx_en", Pins("H15", dir="o")), + Subsignal("tx_er", Pins("G18", dir="o")), + Subsignal("tx_data", Pins("H16 H13 K14 K13", dir="o")), + Subsignal("rx_clk", Pins("K15", dir="i")), + Subsignal("rx_dv", Pins("F17", dir="i"), Attrs(PULLDOWN="TRUE")), + Subsignal("rx_er", Pins("F18", dir="i")), + Subsignal("rx_data", Pins("G16 H14 E16 F15", dir="i")), + Subsignal("col", Pins("C17", dir="i")), + Subsignal("crs", Pins("C18", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ), + # Device does not support RMII + Resource("eth_tbi", 0, + Subsignal("rst", PinsN("G13", dir="o")), + Subsignal("int", PinsN("L16", dir="o")), + Subsignal("mdio", Pins("N17", dir="io")), + Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz + Subsignal("tx_clk", Pins("L12", dir="o")), + Subsignal("tx_data", Pins("H16 H13 K14 K13 J13 G14 H12 K12 H15 G18", dir="o")), + Subsignal("rx_clk", Pins("K15 L12", dir="i")), + Subsignal("rx_data", Pins("G16 H14 E16 F15 F14 E18 D16 D17 F17 F18", dir="i")), + Subsignal("lpbk", Pins("C17", dir="o"), Attrs(PULLDOWN="TRUE")), + Subsignal("comma", Pins("C18", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ), + Resource("eth_rtbi", 0, + Subsignal("rst", PinsN("G13", dir="o")), + Subsignal("int", PinsN("L16", dir="o")), + Subsignal("mdio", Pins("N17", dir="io")), + Subsignal("mdc", Pins("F16", dir="o")), # Max 8.3MHz + Subsignal("tx_clk", Pins("L12", dir="o")), + Subsignal("tx_data", Pins("H16 H13 K14 K13 H15", dir="o")), + Subsignal("rx_clk", Pins("K15", dir="i")), + Subsignal("rx_data", Pins("G16 H14 E16 F15 F17", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ), + + Resource("hdmi", 0, # J1, input only due to on board buffer, HDMI A connector + Subsignal("scl", Pins("C13"), Attrs(IOSTANDARD="I2C")), + Subsignal("sda", Pins("A13"), Attrs(IOSTANDARD="I2C")), + Subsignal("clk", DiffPairs("D11", "C11", dir="i")), + Subsignal("d", DiffPairs("G9 B11 B12", "F9 A11 A12", dir="i")), + Attrs(IOSTANDARD="TMDS_33"), + ), + Resource("hdmi", 1, # J2, output only due to on board buffer, HDMI A connector + Subsignal("scl", Pins("D9"), Attrs(IOSTANDARD="I2C")), + Subsignal("sda", Pins("C9"), Attrs(IOSTANDARD="I2C")), + Subsignal("clk", DiffPairs("B6", "A6", dir="o")), + Subsignal("d", DiffPairs("D8 C7 B8", "C8 A7 A8", dir="o")), + Attrs(IOSTANDARD="TMDS_33"), + ), + Resource("hdmi", 2, # J3, input only due to on board buffer, HDMI A connector + Subsignal("scl", Pins("M16"), Attrs(IOSTANDARD="I2C")), + Subsignal("sda", Pins("M18"), Attrs(IOSTANDARD="I2C")), + Subsignal("clk", DiffPairs("H17", "H18", dir="i")), + Subsignal("d", DiffPairs("K17 L17 J16", "K18 L18 J18", dir="i")), + Attrs(IOSTANDARD="TMDS_33"), + ), + Resource("hdmi", 3, # JA, input/output as it is unbuffered, HDMI D connector + Subsignal("scl", Pins("C13"), Attrs(IOSTANDARD="I2C")), + Subsignal("sda", Pins("A13"), Attrs(IOSTANDARD="I2C")), + Subsignal("clk", DiffPairs("T9", "V9")), + Subsignal("d", DiffPairs("R3 T4 N5", "T3 V4 P6")), + Attrs(IOSTANDARD="TMDS_33"), + ), + + Resource("ac97", 0, + Subsignal("clk", Pins("L13", dir="o")), + Subsignal("sync", Pins("U17", dir="o")), + Subsignal("reset", Pins("T17", dir="o")), + Subsignal("sdo", Pins("N18", dir="o")), + Subsignal("sdi", Pins("T18", dir="i")), + Attrs(IOSTANDARD="LVCMOS33") + ), + ] + connectors = [ + Connector("pmod", 0, "T3 R3 P6 N5 - - V9 T9 V4 T4 - -"), # JB + + Connector("vhdci", 0, # JC + "U16 - U15 U13 - M11 R11 - T12 N10 - M10 U11 - R10 - - - - U10 - R8 M8 - U8 U7 - N7 T6 - R7 N6 - U5 " + "V16 - V15 V13 - N11 T11 - V12 P11 - N9 V11 - T10 - - - - V10 - T8 N8 - V8 V7 - P8 V6 - T7 P7 - V5 " + ), + ] + + def toolchain_program(self, products, name): + with products.extract("{}.bit".format(name)) as bitfile: + cmd = textwrap.dedent(""" + setMode -bscan + setCable -port auto + addDevice -p 1 -file "{}" + program -p 1 + exit + """).format(bitfile).encode('utf-8') + subprocess.run(["impact", "-batch"], input=cmd, check=True) + + +if __name__ == "__main__": + from .test.blinky import * + AtlysPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/blackice.py b/re-bba/amaranth_boards/blackice.py new file mode 100644 index 0000000..1e2db73 --- /dev/null +++ b/re-bba/amaranth_boards/blackice.py @@ -0,0 +1,61 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["BlackIcePlatform"] + + +class BlackIcePlatform(LatticeICE40Platform): + device = "iCE40HX4K" + package = "TQ144" + default_clk = "clk100" + resources = [ + Resource("clk100", 0, Pins("129", dir="i"), + Clock(100e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + *LEDResources(pins="71 67 68 70", attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + # Semantic aliases + Resource("led_b", 0, Pins("71", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 0, Pins("67", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_o", 0, Pins("68", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_r", 0, Pins("70", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + + *ButtonResources(pins="63 64", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + *SwitchResources(pins="37 38 39 41", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + + UARTResource(0, + rx="88", tx="85", + attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1), + role="dce" + ), + + SRAMResource(0, + cs_n="136", oe_n="45", we_n="120", + a="137 138 139 141 142 42 43 44 73 74 75 76 115 116 117 118 119 78", + d="135 134 130 128 125 124 122 121 61 60 56 55 52 49 48 47", + attrs=Attrs(IO_STANDARD="SB_LVCMOS"), + ), + ] + connectors = [ + Connector("pmod", 0, " 94 91 88 85 - - 95 93 90 87 - -"), # PMOD1/2 + Connector("pmod", 1, "105 102 99 97 - - 104 101 98 96 - -"), # PMOD3/4 + Connector("pmod", 2, "143 114 112 107 - - 144 113 110 106 - -"), # PMOD5/6 + Connector("pmod", 3, " 10 9 2 1 - - 8 7 4 3 - -"), # PMOD7/8 + Connector("pmod", 4, " 20 19 16 15 - - 18 17 12 11 - -"), # PMOD9/10 + Connector("pmod", 5, " 34 33 22 21 - - 32 31 26 25 - -"), # PMOD11/12 + Connector("pmod", 6, " 29 28 24 23 - -"), # PMOD13 + Connector("pmod", 7, " 71 67 68 70 - -"), # PMOD14 + ] + + def toolchain_program(self, products, name): + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call(["cp", bitstream_filename, "/dev/ttyACM0"]) + + +if __name__ == "__main__": + from .test.blinky import * + BlackIcePlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/blackice_ii.py b/re-bba/amaranth_boards/blackice_ii.py new file mode 100644 index 0000000..99fd1e7 --- /dev/null +++ b/re-bba/amaranth_boards/blackice_ii.py @@ -0,0 +1,63 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["BlackIceIIPlatform"] + + +class BlackIceIIPlatform(LatticeICE40Platform): + device = "iCE40HX4K" + package = "TQ144" + default_clk = "clk100" + resources = [ + Resource("clk100", 0, Pins("129", dir="i"), + Clock(100e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS") + ), + + *LEDResources(pins="71 67 68 70", attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + # Color aliases + Resource("led_b", 0, Pins("71", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 0, Pins("67", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_o", 0, Pins("68", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_r", 0, Pins("70", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + + *ButtonResources(pins="63 64", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + *SwitchResources(pins="37 38 39 41", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + + UARTResource(0, + rx="88", tx="85", rts="91", cts="94", + attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1), + role="dce" + ), + + SRAMResource(0, + cs_n="136", oe_n="29", we_n="120", + a="137 138 139 141 142 42 43 44 73 74 75 76 115 116 117 118 119 78", + d="136 135 134 130 125 124 122 121 62 61 60 56 55 48 47 45", + dm_n="24 28", + attrs=Attrs(IO_STANDARD="SB_LVCMOS"), + ), + ] + connectors = [ + Connector("pmod", 0, " 94 91 88 85 - - 95 93 90 87 - -"), # PMOD1/2 + Connector("pmod", 1, "105 102 99 97 - - 104 101 98 96 - -"), # PMOD3/4 + Connector("pmod", 2, "143 114 112 107 - - 144 113 110 106 - -"), # PMOD5/6 + Connector("pmod", 3, " 10 9 2 1 - - 8 7 4 3 - -"), # PMOD7/8 + Connector("pmod", 4, " 20 19 16 15 - - 18 17 12 11 - -"), # PMOD9/10 + Connector("pmod", 5, " 34 33 22 21 - - 32 31 26 25 - -"), # PMOD11/12 + Connector("pmod", 6, " 37 38 39 41 - -"), # PMOD13 + Connector("pmod", 7, " 71 67 68 70 - -"), # PMOD14 + ] + + def toolchain_program(self, products, name): + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call(["cp", bitstream_filename, "/dev/ttyACM0"]) + + +if __name__ == "__main__": + from .test.blinky import * + BlackIceIIPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/chameleon96.py b/re-bba/amaranth_boards/chameleon96.py new file mode 100644 index 0000000..412e7ed --- /dev/null +++ b/re-bba/amaranth_boards/chameleon96.py @@ -0,0 +1,105 @@ +import os +import subprocess + +from amaranth import * +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["Chameleon96Platform"] + + +class Chameleon96Platform(IntelPlatform): + device = "5CSEBA6" # Cyclone V SE 110K LEs + package = "U19" # UBGA-484 + speed = "I7" + default_clk = "cyclonev_oscillator" + resources = [ + # WIFI and BT LEDs + *LEDResources( + pins="Y19 Y20", + attrs=Attrs(io_standard="2.5 V")), + + # TDA19988 HDMI transmitter + Resource("tda19988", 0, + Subsignal("vpa", Pins(" W8 W7 V6 V5 U6 ", dir="o")), # bits 3 to 7 + Subsignal("vpb", Pins("AB5 AA5 AA8 AB8 AB9 Y11", dir="o")), # bits 2 to 7 + Subsignal("vpc", Pins(" W6 Y5 AB7 AA7 AA6", dir="o")), # bits 3 to 7 + Subsignal("pclk", Pins("AB10", dir="o")), + Subsignal("hsync", Pins("V10 ", dir="o")), + Subsignal("vsync", Pins("V7 ", dir="o")), + Subsignal("de", Pins("Y8 ", dir="o")), + Attrs(io_standard="1.8 V") + ), + + I2CResource("tda19988_i2c", 0, + scl="U7", sda="U10", + attrs=Attrs(io_standard="1.8 V"), + ), + + Resource("tda19988_i2s", 0, + Subsignal("mclk", Pins("V11 ", dir="o")), # OSC_IN/AP3 + Subsignal("txd", Pins("AA11", dir="o")), # AP1 + Subsignal("txc", Pins("W11 ", dir="o")), # ACLK + Subsignal("txfs", Pins("V9 ", dir="o")), # AP0 + Attrs(io_standard="1.8 V") + ), + + # Wifi and BT module + *SDCardResources("wifi", 0, + clk="AB20", cmd="AB18", dat0="Y14", dat1="AB19", dat2="AA18", dat3="AB15", + attrs=Attrs(io_standard="1.8 V"), + ), + + Resource("bt", 0, + Subsignal("host_wake", Pins("AB12", dir="o")), + Attrs(io_standard="1.8 V"), + ), + + Resource("bt_i2s", 0, + Subsignal("txd", Pins("Y15 ", dir="o")), # BT_PCM_IN + Subsignal("rxd", Pins("Y16 ", dir="i")), # BT_PCM_OUT + Subsignal("txc", Pins("AA13", dir="i")), # BT_PCM_CLK + Subsignal("txfs", Pins("AB13", dir="i")), # BT_PCM_SYNC + Attrs(io_standard="1.8 V"), + ), + + UARTResource("bt_uart", 0, + rx="AB14", cts="AB17", tx="AA15", rts="AA16", role="dte", + attrs=Attrs(io_standard="1.8 V"), + ), + ] + + connectors = [ + # J3, 2x20 expansion port + Connector("J", 3, + "- - Y13 - W14 - C5 - C6 -" + "- - - - - E5 - F5 - A6" + "- A5 - - - - - - - -" + "- - - - - - - - - -" + ), + + # J8, 2x30 high speed expansion port (MIPI CSI) + Connector("J", 8, + "- V16 - U17 - - - V17 - W18" + "- - - U18 W12 V19 - - - -" + "- - - - - - - - - -" + "- - - - - - - - - -" + "- - - - - - - - - -" + "- - - - - - - - - -" + ), + ] + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + # The @2 selects the second device in the JTAG chain, because this chip + # puts the ARM cores first. + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename + "@2"]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + Chameleon96Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/colorlight_5a75b_r7_0.py b/re-bba/amaranth_boards/colorlight_5a75b_r7_0.py new file mode 100644 index 0000000..5ade245 --- /dev/null +++ b/re-bba/amaranth_boards/colorlight_5a75b_r7_0.py @@ -0,0 +1,114 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ecp5 import * +from .resources import * + + +__all__ = ["Colorlight_5A75B_R70Platform"] + + +class Colorlight_5A75B_R70Platform(LatticeECP5Platform): + device = "LFE5U-25F" + package = "BG256" + speed = "6" + default_clk = "clk25" + + resources = [ + Resource("clk25", 0, Pins("P6", dir="i"), Clock(25e6), Attrs(IO_TYPE="LVCMOS33")), + + *LEDResources(pins="P11", invert = True, + attrs=Attrs(IO_TYPE="LVCMOS33", DRIVE="4")), + + *ButtonResources(pins="M13", invert = True, + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP")), + + UARTResource(0, + tx="P11", # led (J19 DATA_LED-) + rx="M13", # btn (J19 KEY+) + attrs=Attrs(IO_TYPE="LVCMOS33") + ), + + # SPIFlash (W25Q32JV) 1x/2x/4x speed + Resource("spi_flash", 0, + Subsignal("cs", PinsN("N8", dir="o")), + # Subsignal("clk", Pins("", dir="i")), # driven through USRMCLK + Subsignal("cipo", Pins("T8", dir="i")), # Chip: DI/IO0 + Subsignal("copi", Pins("T7", dir="o")), # DO/IO1 + # Subsignal("wp", PinsN("unknown", dir="o")), # IO2 Todo + # Subsignal("hold", PinsN("unknown", dir="o")), # IO3 Todo + Attrs(IO_TYPE="LVCMOS33") + ), + + # 2x ESMT M12L16161A-5T 1M x 16bit 200MHz SDRAMs (organized as 1M x 32bit) + # 2x WinBond W9816G6JH-6 1M x 16bit 166MHz SDRAMs (organized as 1M x 32bit) are lso reported + SDRAMResource(0, + clk="C6", we_n="C7", cas_n="E7", ras_n="D7", + ba="A7", a="A9 E10 B12 D13 C12 D11 D10 E9 D9 B7 C8", + dq="B13 C11 C10 A11 C9 E8 B6 B9 A6 B5 A5 B4 B3 C3 A2 B2 " + "E2 D3 A4 E4 D4 C4 E5 D5 E6 D6 D8 A8 B8 B10 B11 E11", + attrs=Attrs(PULLMODE="NONE", DRIVE="4", SLEWRATE="FAST", IO_TYPE="LVCMOS33") + ), + + # Broadcom B50612D Gigabit Ethernet Transceiver + Resource("eth_rgmii", 0, + Subsignal("rst", PinsN("P5", dir="o")), + Subsignal("mdc", Pins("P3", dir="o")), + Subsignal("mdio", Pins("T2", dir="io")), + Subsignal("tx_clk", Pins("M2", dir="o")), + Subsignal("tx_ctl", Pins("M3", dir="o")), + Subsignal("tx_data", Pins("L1 L3 P2 L4", dir="o")), + Subsignal("rx_clk", Pins("M1", dir="i")), + Subsignal("rx_ctl", Pins("N6", dir="i")), + Subsignal("rx_data", Pins("N1 M5 N5 M6", dir="i")), + Attrs(IO_TYPE="LVCMOS33") + ), + + # Broadcom B50612D Gigabit Ethernet Transceiver + Resource("eth_rgmii", 1, + Subsignal("rst", PinsN("P5", dir="o")), + Subsignal("mdc", Pins("P3", dir="o")), + Subsignal("mdio", Pins("T2", dir="io")), + Subsignal("tx_clk", Pins("M12", dir="o")), + Subsignal("tx_ctl", Pins("R15", dir="o")), + Subsignal("tx_data", Pins("T14 R12 R13 R14", dir="o")), + Subsignal("rx_clk", Pins("M16", dir="i")), + Subsignal("rx_ctl", Pins("L15", dir="i")), + Subsignal("rx_data", Pins("P13 N13 P14 M15", dir="i")), + Attrs(IO_TYPE="LVCMOS33") + ), + + ] + connectors = [ + Connector("j", 1, "F3 F1 G3 - G2 H3 H5 F15 L2 K1 J5 K2 B16 J14 F12 -"), + Connector("j", 2, "J4 K3 G1 - K4 C2 E3 F15 L2 K1 J5 K2 B16 J14 F12 -"), + Connector("j", 3, "H4 K5 P1 - R1 L5 F2 F15 L2 K1 J5 K2 B16 J14 F12 -"), + Connector("j", 4, "P4 R2 M8 - M9 T6 R6 F15 L2 K1 J5 K2 B16 J14 F12 -"), + Connector("j", 5, "M11 N11 P12 - K15 N12 L16 F15 L2 K1 J5 K2 B16 J14 F12 -"), + Connector("j", 6, "K16 J15 J16 - J12 H15 G16 F15 L2 K1 J5 K2 B16 J14 F12 -"), + Connector("j", 7, "H13 J13 H12 - G14 H14 G15 F15 L2 K1 J5 K2 B16 J14 F12 -"), + Connector("j", 8, "A15 F16 A14 - E13 B14 A13 F15 L2 K1 J5 K2 B16 J14 F12 -"), + Connector("j", 19, " - M13 - - P11"), + ] + + @property + def required_tools(self): + return super().required_tools + [ + "openFPGALoader" + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = dict(ecppack_opts="--compress") + overrides.update(kwargs) + return super().toolchain_prepare(fragment, name, **overrides) + + def toolchain_program(self, products, name): + tool = os.environ.get("OPENFPGALOADER", "openFPGALoader") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.check_call([tool, "-c", "ft232", "-m", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + Colorlight_5A75B_R70Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/de0.py b/re-bba/amaranth_boards/de0.py new file mode 100644 index 0000000..c10cce3 --- /dev/null +++ b/re-bba/amaranth_boards/de0.py @@ -0,0 +1,111 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["DE0Platform"] + + +class DE0Platform(IntelPlatform): + device = "EP3C16" # Cyclone III 15K LEs + package = "F484" # FBGA-484 + speed = "C6" + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("G21", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 1, Pins("B12", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + + *LEDResources( + pins="J1 J2 J3 H1 F2 E1 C1 C2 B2 B1", + attrs=Attrs(io_standard="3.3-V LVTTL")), + *ButtonResources( + pins="H2 G3 F1", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + *SwitchResources( + pins="J6 H5 H6 G4 G5 J7 H7 E3 E4 D2", + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(0, + a="E11", b="F11", c="H12", d="H13", e="G12", f="F12", g="F13", dp="D13", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(1, + a="A13", b="B13", c="C13", d="A14", e="B14", f="E14", g="A15", dp="B15", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(2, + a="D15", b="A16", c="B16", d="E15", e="A17", f="B17", g="F14", dp="A18", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(3, + a="B18", b="F15", c="A19", d="B19", e="C19", f="D19", g="G15", dp="G16", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + + UARTResource(0, + rx="U22", tx="U21", rts="V22", cts="V21", + attrs=Attrs(io_standard="3.3-V LVTTL"), + role="dce"), + + Resource("display_hd44780", 0, + Subsignal("e", Pins("E21", dir="o")), + Subsignal("d", Pins("D22 D21 C22 C21 B22 B21 D20 C20", dir="io")), + Subsignal("rw", Pins("E22", dir="o")), + Subsignal("rs", Pins("F22", dir="o")), + # Backlight + Subsignal("bl", Pins("F21", dir="o")), + Attrs(io_standard="3.3-V LVTTL") + ), + + VGAResource(0, + r="H19 H17 H20 H21", + g="H22 J17 K17 J21", + b="K22 K21 J22 K18", + hs="L21", vs="L22", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + PS2Resource(0, # Keyboard + clk="P22", dat="P21", attrs=Attrs(io_standard="3.3-V LVTTL")), + PS2Resource(1, # Mouse + clk="R21", dat="R22", attrs=Attrs(io_standard="3.3-V LVTTL")), + + *SDCardResources(0, + clk="Y21", cmd="Y22", dat0="AA22", dat3="W21", wp_n="W20", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + SDRAMResource(0, + clk="E5", cke="E6", cs_n="G7", we_n="D6", ras_n="F7", cas_n="G8", + ba="B5 A4", a="C4 A3 B3 C3 A5 C6 B6 A6 C7 B7 B4 A7 C8", + dq="D10 G10 H10 E9 F9 G9 H9 F8 A8 B9 A9 C10 B10 A10 E10 F10", dqm="E7 B8", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + *NORFlashResources(0, + rst="R1", byte_n="AA1", + cs_n="N8", oe_n="R6", we_n="P4", wp_n="T3", by="M7", + a="P7 P5 P6 N7 N5 N6 M8 M4 P2 N2 N1 M3 M2 M1 L7 L6 AA2 M5 M6 P1 P3 R2", + dq="R7 P8 R8 U1 V2 V3 W1 Y1 T5 T7 T4 U2 V1 V4 W2 Y2", + attrs=Attrs(io_standard="3.3-V LVTTL")), + ] + connectors = [ + Connector("j", 4, + "AB12 AB16 AA12 AA16 AA15 AB15 AA14 AB14 AB13 AA13 - - " + "AB10 AA10 AB8 AA8 AB5 AA5 AB3 AB4 AA3 AA4 V14 U14 " + "Y13 W13 U13 V12 - - R10 V11 Y10 W10 T8 V8 " + "W7 W6 V5 U7 "), + Connector("j", 5, + "AB11 AA20 AA11 AB20 AA19 AB19 AB18 AA18 AA17 AB17 - - " + "Y17 W17 U15 T15 W15 V15 R16 AB9 T16 AA9 AA7 AB7 " + "T14 R14 U12 T12 - - R11 R12 U10 T10 U9 T9 " + "Y7 U8 V6 V7 "), + ] + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + DE0Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/de0_cv.py b/re-bba/amaranth_boards/de0_cv.py new file mode 100644 index 0000000..adc607f --- /dev/null +++ b/re-bba/amaranth_boards/de0_cv.py @@ -0,0 +1,99 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["DE0CVPlatform"] + + +class DE0CVPlatform(IntelPlatform): + device = "5CEBA4" # Cyclone V 49K LEs + package = "F23" # FBGA-484 + speed = "C7" + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("M9", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 1, Pins("H13", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 2, Pins("E10", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 3, Pins("V15", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + + *LEDResources( + pins="AA2 AA1 W2 Y3 N2 N1 U2 U1 L2 L1", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + *ButtonResources( + pins="U7 W9 M7 M6", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + *SwitchResources( + pins="U13 V13 T13 T12 AA15 AB15 AA14 AA13 AB13 AB12", + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(0, + a="U21", b="V21", c="W22", d="W21", e="Y22", f="Y21", g="AA22", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(1, + a="AA20", b="AB20", c="AA19", d="AA18", e="AB18", f="AA17", g="U22", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(2, + a="Y19", b="AB17", c="AA10", d="Y14", e="V14", f="AB22", g="AB21", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(3, + a="Y16", b="W16", c="Y17", d="V16", e="U17", f="V18", g="V19", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(4, + a="U20", b="Y20", c="V20", d="U16", e="U15", f="Y15", g="P9", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(5, + a="N9", b="M8", c="T14", d="P14", e="C1", f="C2", g="W19", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + + VGAResource(0, + r="A9 B10 C9 A5", + g="L7 K7 J7 J8", + b="B6 B7 A8 A7", + hs="H8", vs="G8", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + PS2Resource(0, # Keyboard + clk="D3", dat="G2", attrs=Attrs(io_standard="3.3-V LVTTL")), + PS2Resource(1, # Mouse + clk="E2", dat="G1", attrs=Attrs(io_standard="3.3-V LVTTL")), + + *SDCardResources(0, + clk="H11", cmd="B11", dat0="K9", dat1="D12", dat2="E12", dat3="C11", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + SDRAMResource(0, + clk="AB11", cke="R6", cs_n="U6", we_n="AB5", ras_n="AB6", cas_n="V6", + ba="T7 AB7", a="W8 T8 U11 Y10 N6 AB10 P12 P7 P8 R5 U8 P6 R7", + dq="Y9 T10 R9 Y11 R10 R11 R12 AA12 AA9 AB8 AA8 AA7 V10 V9 U10 T9", dqm="U12 N8", + attrs=Attrs(io_standard="3.3-V LVCMOS")), + ] + connectors = [ + Connector("j", 1, + "N16 B16 M16 C16 D17 K20 K21 K22 M20 M21 " + "- - N21 R22 R21 T22 N20 N19 M22 P19 " + "L22 P17 P16 M18 L18 L17 L19 K17 - - " + "K19 P18 R15 R17 R16 T20 T19 T18 T17 T15 "), + Connector("j", 2, + "H16 A12 H15 B12 A13 B13 C13 D13 G18 G17 " + "- - H18 J18 J19 G11 H10 J11 H14 A15 " + "J13 L8 A14 B15 C15 E14 E15 E16 - - " + "F14 F15 F13 F12 G16 G15 G13 G12 J17 K16 "), + ] + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + DE0CVPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/de10_lite.py b/re-bba/amaranth_boards/de10_lite.py new file mode 100644 index 0000000..de9ea84 --- /dev/null +++ b/re-bba/amaranth_boards/de10_lite.py @@ -0,0 +1,89 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["DE10LitePlatform"] + + +class DE10LitePlatform(IntelPlatform): + device = "10M50DA" # MAX10 + package = "F484" # FBGA-484 + speed = "C7" + suffix = "G" + default_clk = "clk50" + resources = [ + Resource("clk10", 0, Pins("N5", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 0, Pins("P11", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 1, Pins("N14", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + + *LEDResources( + pins="A8 A9 A10 B10 D13 C13 E14 D14 A11 B11", + attrs=Attrs(io_standard="3.3-V LVTTL")), + *ButtonResources( + pins="B8 A7", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + *SwitchResources( + pins="C10 C11 D12 C12 A12 B12 A13 A14 B14 F15", + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(0, + a="C14", b="E15", c="C15", d="C16", e="E16", f="D17", g="C17", dp="D15", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(1, + a="C18", b="D18", c="E18", d="B16", e="A17", f="A18", g="B17", dp="A16", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(2, + a="B20", b="A20", c="B19", d="A21", e="B21", f="C22", g="B22", dp="A19", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(3, + a="F21", b="E22", c="E21", d="C19", e="C20", f="D19", g="E17", dp="D22", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(4, + a="F18", b="E20", c="E19", d="J18", e="H19", f="F19", g="F20", dp="F17", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(5, + a="J20", b="K20", c="L18", d="N18", e="M20", f="N19", g="N20", dp="L19", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # Arduino header + UARTResource(0, + rx="V10", tx="W10", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + SDRAMResource(0, + clk="L14", cs_n="U20", we_n="V20", ras_n="U22", cas_n="U21", + ba="T21 T22", a="U17 W19 V18 U18 U19 T18 T19 R18 P18 P19 T20 P20 R20", + dq="Y21 Y20 AA22 AA21 Y22 W22 W20 V21 P21 J22 H21 H22 G22 G20 G19 F22", + dqm="V22 J21", attrs=Attrs(io_standard="3.3-V LVCMOS")), + + VGAResource(0, + r="AA1 V1 Y2 Y1", + g="W1 T2 R2 R1", + b="P1 T1 P4 N2", + hs="N3", vs="N1", + attrs=Attrs(io_standard="3.3-V LVTTL")) + ] + connectors = [ + Connector("gpio", 0, + "V10 W10 V9 W9 V8 W8 V7 W7 W6 V5 W5 AA15 AA14 W13 W12 AB13 AB12 Y11 AB11 W11 AB10 " + "AA10 AA9 Y8 AA8 Y7 AA7 Y6 AA6 Y5 AA5 Y4 AB3 Y3 AB2 AA2"), + Connector("gpio", 5, + "AB5 AB6 AB7 AB8 AB9 Y10 AA11 AA12 AB17 AA17 AB19 AA19 Y19 AB20 AB21 AA20 F16"), + ] + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + DE10LitePlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/de10_nano.py b/re-bba/amaranth_boards/de10_nano.py new file mode 100644 index 0000000..1129813 --- /dev/null +++ b/re-bba/amaranth_boards/de10_nano.py @@ -0,0 +1,95 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["DE10NanoPlatform"] + + +# The MiSTer platform is built around the DE10-Nano; if you update one you should update the other. +class DE10NanoPlatform(IntelPlatform): + device = "5CSEBA6" # Cyclone V 110K LEs + package = "U23" # UBGA-484 + speed = "I7" + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("V11", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 1, Pins("Y13", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 2, Pins("E11", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + + *LEDResources( + pins="W15 AA24 V16 V15 AF26 AE26 Y16 AA23", + attrs=Attrs(io_standard="3.3-V LVTTL")), + *ButtonResources( + pins="AH17 AH16", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + *SwitchResources( + pins="Y24 W24 W21 W20", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # Arduino header + UARTResource(0, + rx="AG13", tx="AF13", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # LTC2308 analogue-to-digital converter + SPIResource(0, + cs_n="U9", clk="V10", copi="AC4", cipo="AD4", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # ADV7513 HDMI transmitter + # Note this has a lot of input formats for tx_d, but this defaults to RGB24 + Resource("adv7513", 0, + Subsignal("tx_d_r", Pins("AD12 AE12 W8 Y8 AD11 AD10 AE11 Y5", dir="o")), + Subsignal("tx_d_g", Pins("AF10 Y4 AE9 AB4 AE7 AF6 AF8 AF5", dir="o")), + Subsignal("tx_d_b", Pins("AE4 AH2 AH4 AH5 AH6 AG6 AF9 AE8", dir="o")), + Subsignal("tx_clk", Pins("AG5", dir="o")), + Subsignal("tx_de", Pins("AD19", dir="o")), + Subsignal("tx_hs", Pins("T8", dir="o")), + Subsignal("tx_vs", Pins("V13", dir="o")), + Subsignal("tx_int", Pins("AF11", dir="i")), + Subsignal("i2s0", Pins("T13", dir="o")), + Subsignal("mclk", Pins("U11", dir="o")), + Subsignal("lrclk", Pins("T11", dir="o")), + Subsignal("sclk", Pins("T12", dir="o")), + Subsignal("scl", Pins("U10", dir="o")), + Subsignal("sda", Pins("AA4", dir="io")), + Attrs(io_standard="3.3-V LVTTL")), + ] + connectors = [ + # Located on the top of the board, above the chip. + Connector("gpio", 0, + "V12 E8 W12 D11 D8 AH13 AF7 AH14 AF4 AH3 " + "- - AD5 AG14 AE23 AE6 AD23 AE24 D12 AD20 " + "C12 AD17 AC23 AC22 Y19 AB23 AA19 W11 - - " + "AA18 W14 Y18 Y17 AB25 AB26 Y11 AA26 AA13 AA11 "), + # Located on the bottom of the board. + Connector("gpio", 1, + "Y15 AC24 AA15 AD26 AG28 AF28 AE25 AF27 AG26 AH27 " + "- - AG25 AH26 AH24 AF25 AG23 AF23 AG24 AH22 " + "AH21 AG21 AH23 AA20 AF22 AE22 AG20 AF21 - - " + "AG19 AH19 AG18 AH18 AF18 AF20 AG15 AE20 AE19 AE17 "), + Connector("arduino", 0, + "AG13 AF13 AG10 AG9 U14 U13 AG8 AH8 " + "AF17 AE15 AF15 AG16 AH11 AH12 AH9 AG11 " + "AH7"), + ] + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + # The @2 selects the second device in the JTAG chain, because this chip + # puts the ARM cores first. + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename + "@2"]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + DE10NanoPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/de1_soc.py b/re-bba/amaranth_boards/de1_soc.py new file mode 100644 index 0000000..8df8c46 --- /dev/null +++ b/re-bba/amaranth_boards/de1_soc.py @@ -0,0 +1,87 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["DE1SoCPlatform"] + + +class DE1SoCPlatform(IntelPlatform): + device = "5CSEMA5" # Cyclone V 85K LEs + package = "F31" # FBGA-896 + speed = "C6" + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("AF14", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 1, Pins("AA16", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 2, Pins("Y26", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 3, Pins("K14", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + + *LEDResources( + pins="V16 W16 V17 V18 W17 W19 Y19 W20 W21 Y21", + attrs=Attrs(io_standard="3.3-V LVTTL")), + *ButtonResources( + pins="AA14 AA15 W15 Y16", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + *SwitchResources( + pins="AB12 AC12 AF9 AF10 AD11 AD12 AE11 AC9 AD10 AE12", + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(0, + a="AE26", b="AE27", c="AE28", d="AG27", e="AF28", + f="AG28", g="AH28", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(1, + a="AJ29", b="AH29", c="AH30", d="AG30", e="AF29", + f="AF30", g="AD27", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(2, + a="AB23", b="AE29", c="AD29", d="AC28", e="AD30", + f="AC29", g="AC30", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(3, + a="AD26", b="AC27", c="AD25", d="AC25", e="AB28", + f="AB25", g="AB22", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(4, + a="AA24", b="Y23", c="Y24", d="W22", e="W24", + f="V23", g="W25", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + Display7SegResource(5, + a="V25", b="AA28", c="Y27", d="AB27", e="AB26", + f="AA26", g="AA25", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + ] + connectors = [ + # Located on the right hand side of the board + Connector("gpio", 0, + "AC18 Y17 AD17 Y18 AK16 AK18 AK19 AJ19 AJ17 AJ16 " + " - - AH18 AH17 AG16 AE16 AF16 AG17 AA18 AA19 " + "AE17 AC20 AH19 AJ20 AH20 AK21 AD19 AD20 - - " + "AE18 AE19 AF20 AF21 AF19 AG21 AF18 AG20 AG18 AJ21 "), + + Connector("gpio", 1, + "AB17 AA21 AB21 AC23 AD24 AE23 AE24 AF25 AF26 AG25 " + "- - AG26 AH24 AH27 AJ27 AK29 AK28 AK27 AJ26 " + "AK26 AH25 AJ25 AJ24 AK24 AG23 AK23 AH23 - - " + "AK22 AJ22 AH22 AG22 AF24 AF23 AE22 AD21 AA20 AC22 "), + ] + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + # The @2 selects the second device in the JTAG chain, because this chip + # puts the ARM cores first. + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename + "@2"]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + DE1SoCPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/ebaz4205.py b/re-bba/amaranth_boards/ebaz4205.py new file mode 100644 index 0000000..eb4a692 --- /dev/null +++ b/re-bba/amaranth_boards/ebaz4205.py @@ -0,0 +1,40 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["EBAZ4205Platform"] + + +class EBAZ4205Platform(Xilinx7SeriesPlatform): + device = "xc7z010" + package = "clg400" + speed = "1" + default_clk = "clk33_333" + resources = [ + Resource("clk33_333", 0, + Pins("N18", dir="i"), Clock(33.333e6), Attrs(IOSTANDARD="LVCMOS33")), + + *LEDResources( + pins="W14 W13", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + UARTResource(0, + rx="B19", tx="B20", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + ] + connectors = [ + ] + + def toolchain_program(self, products, name, **kwargs): + xc3sprog = os.environ.get("XC3SPROG", "xc3sprog") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.run([xc3sprog, "-c", "jtaghs1_fast", "-p", "1", bitstream_filename], check=True) + + +if __name__ == "__main__": + from .test.blinky import * + EBAZ4205Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/ecp5_5g_evn.py b/re-bba/amaranth_boards/ecp5_5g_evn.py new file mode 100644 index 0000000..3eb6189 --- /dev/null +++ b/re-bba/amaranth_boards/ecp5_5g_evn.py @@ -0,0 +1,154 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ecp5 import * +from .resources import * + + +__all__ = ["ECP55GEVNPlatform"] + + +class ECP55GEVNPlatform(LatticeECP5Platform): + device = "LFE5UM5G-85F" + package = "BG381" + speed = "8" + default_clk = "clk12" + default_rst = "rst" + + def __init__(self, *, VCCIO1="2V5", VCCIO6="3V3", **kwargs): + """ + VCCIO1 is connected by default to 2.5 V via R100 (can be set to 3.3 V by disconnecting + R100 and connecting R105) + VCCIO6 is connected to 3.3 V by default via R99 (can be switched to 2.5 V with R104, + see page 51 in the ECP5-5G-EVN datasheet) + """ + super().__init__(**kwargs) + assert VCCIO1 in ("3V3", "2V5") + assert VCCIO6 in ("3V3", "2V5") + self._VCCIO1 = VCCIO1 + self._VCCIO6 = VCCIO6 + + def _vccio_to_iostandard(self, vccio): + if vccio == "2V5": + return "LVCMOS25" + if vccio == "3V3": + return "LVCMOS33" + assert False + + def bank1_iostandard(self): + return self._vccio_to_iostandard(self._VCCIO1) + + def bank6_iostandard(self): + return self._vccio_to_iostandard(self._VCCIO6) + + resources = [ + Resource("rst", 0, PinsN("G2", dir="i"), Attrs(IO_TYPE="LVCMOS33")), + Resource("clk12", 0, Pins("A10", dir="i"), + Clock(12e6), Attrs(IO_TYPE="LVCMOS33")), + + # By default this CLK is not populated, see User Manual Section 4. + Resource("extclk", 0, Pins("B11", dir="i"), + Attrs(IO_TYPE="LVCMOS33")), + + *LEDResources(pins="A13 A12 B19 A18 B18 C17 A17 B17", invert=True, + attrs=Attrs(IO_TYPE=bank1_iostandard)), + *ButtonResources(pins="P4", invert=True, + attrs=Attrs(IO_TYPE=bank6_iostandard)), + *SwitchResources(pins={1: "J1", 2: "H1", 3: "K1"}, invert=True, + attrs=Attrs(IO_TYPE=bank6_iostandard)), + *SwitchResources(pins={4: "E15", 5: "D16", 6: "B16", 7: "C16", 8: "A16"}, invert=True, + attrs=Attrs(IO_TYPE=bank1_iostandard)), + + # In order to use the UART as a UART you need to swap two resistor jumpers, + # and potentially reconfigure the onboard FTDI chip, see section 6.2 in the + # User Manual for hardware instructions, and + # https://github.com/trabucayre/fixFT2232_ecp5evn to reconfigure the FTDI. + UARTResource(0, + rx="P2", tx="P3", + attrs=Attrs(IO_TYPE=bank6_iostandard, PULLMODE="UP") + ), + + *SPIFlashResources(0, + cs_n="R2", clk="U3", cipo="V2", copi="W2", wp_n="Y2", hold_n="W1", + attrs=Attrs(IO_TYPE="LVCMOS33") + ), + + Resource("serdes", 0, + Subsignal("tx", DiffPairs("W4", "W5", dir="o")), + Subsignal("rx", DiffPairs("Y5", "Y6", dir="i")), + ), + Resource("serdes", 1, + Subsignal("tx", DiffPairs("W8", "W9", dir="o")), + Subsignal("rx", DiffPairs("Y7", "Y8", dir="i")), + ), + Resource("serdes", 2, + Subsignal("tx", DiffPairs("W13", "W14", dir="o")), + Subsignal("rx", DiffPairs("Y14", "Y15", dir="i")), + ), + Resource("serdes", 3, + Subsignal("tx", DiffPairs("W17", "W18", dir="o")), + Subsignal("rx", DiffPairs("Y16", "Y17", dir="i")), + ), + + Resource("serdes_clk", 0, DiffPairs("Y11", "Y12", dir="i")), + Resource("serdes_clk", 1, DiffPairs("Y19", "W20", dir="i")), # 200 MHz + + # TODO: add other resources + ] + connectors = [ + # Expansion connectors + Connector("J", 39, "- - - D15 B15 C15 B13 B20 D11 E11 B12 C12 D12 E12 C13 D13 E13 A14 A9 B10 - - - - - - - - E7 - A11 - A19 - - - - - - -"), + Connector("J", 40, "K2 - A15 F1 H2 G1 J4 J5 J3 K3 L4 L5 M4 N5 N4 P5 N3 M3 - - K5 - M5 - L3 - N2 M1 L2 - L1 N1 C14 - P1 E14 D14 - K4 -"), + # Arduino + Connector("J", 6, "K16 J16 H17 J17 H18 H16 - G18 G16 F17"), + Connector("J", 3, "F19 F20 E20 E19 D19 D20 C20 K17"), + Connector("J", 7, "C18 - D17 - - - - -"), + Connector("J", 4, "F18 E17 E18 D18 F16 E16"), + # Raspberry Pi + Connector("JP", 8, "- - T17 - U16 - U17 P18 - N20 N19 T16 M18 - N17 P17 - M17 U20 - T19 N18 R20 U19 - R18 L18 L17 U18 - T18 T20 P20 - R17 P19 N16 P16 - R16"), + # GPIO + Connector("J", 5, "- - H20 G19 - - K18 J18 - - K19 J19 - - K20 J20 - - G20 - - -"), # Contains 4 differential pairs + Connector("J", 8, "- - L19 M19 L20 M20 L16 -"), + Connector("J", 32, "- - - - A5 A4 - - C5 B5 - - B4 C4 - - B3 A3 - - D5 E4 - - D3 C3 - - E3 F4 - - F5 E5 - - B1 A2 - -"), # Contains 9 differential pairs + Connector("J", 33, "- - - - C2 B2 - - D1 C1 - - E1 D2 - - G5 H4 - - H3 H5 - - F3 G3 - - E2 F2 - -"), # Contains 7 differential pairs + # Mic + Connector("J", 30, "- B6 D9 C9 E9 D10 A6 E10 - -"), + # PMOD + Connector("J", 31, "C6 C7 E8 D8 - - C8 B8 A7 A8 - -"), + # JTAG + Connector("J", 1, "- V4 R5 - - U5 - T5"), + # Parallel configuration + Connector("J", 38, "W3 R2 T3 Y3 R1 V3 T1 V2 U1 W2 V1 T2 W1 U2 Y2 R2 U3 R3 - -"), # Connect pin 2 / R2 with jumper when needed + ] + + @property + def file_templates(self): + return { + **super().file_templates, + "{{name}}-openocd.cfg": r""" + interface ftdi + ftdi_device_desc "Lattice ECP5 Evaluation Board" + ftdi_vid_pid 0x0403 0x6010 + ftdi_channel 0 + ftdi_layout_init 0xfff8 0xfffb + reset_config none + adapter_khz 25000 + + jtag newtap ecp5 tap -irlen 8 -expected-id 0x81113043 + """ + } + + def toolchain_program(self, products, name): + openocd = os.environ.get("OPENOCD", "openocd") + with products.extract("{}-openocd.cfg".format(name), "{}.svf".format(name)) \ + as (config_filename, vector_filename): + subprocess.check_call([openocd, + "-f", config_filename, + "-c", "transport select jtag; init; svf -quiet {}; exit".format(vector_filename) + ]) + + +if __name__ == "__main__": + from .test.blinky import * + ECP55GEVNPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/ecpix5.py b/re-bba/amaranth_boards/ecpix5.py new file mode 100644 index 0000000..167e244 --- /dev/null +++ b/re-bba/amaranth_boards/ecpix5.py @@ -0,0 +1,232 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ecp5 import * +from .resources import * + + +__all__ = ["ECPIX585Platform", "ECPIX545Platform"] + + +class _ECPIX5Platform(LatticeECP5Platform): + package = "BG554" + speed = "8" + default_clk = "clk100" + default_rst = "rst" + + resources = [ + Resource("rst", 0, PinsN("AB1", dir="i"), Attrs(IO_TYPE="LVCMOS33")), + Resource("clk100", 0, Pins("K23", dir="i"), Clock(100e6), Attrs(IO_TYPE="LVCMOS33")), + + RGBLEDResource(0, + r="T23", g="R21", b="T22", invert=True, + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") + ), + RGBLEDResource(1, + r="U21", g="W21", b="T24", invert=True, + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") + ), + RGBLEDResource(2, + r="K21", g="K24", b="M21", invert=True, + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") + ), + RGBLEDResource(3, + r="P21", g="R23", b="P22", invert=True, + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") + ), + + UARTResource(0, + rx="R26", tx="R24", + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") + ), + + *SPIFlashResources(0, + cs_n="AA2", clk="AE3", cipo="AE2", copi="AD2", wp_n="AF2", hold_n="AE1", + attrs=Attrs(IO_TYPE="LVCMOS33") + ), + + Resource("eth_rgmii", 0, + Subsignal("rst", PinsN("C13", dir="o")), + Subsignal("mdio", Pins("A13", dir="io")), + Subsignal("mdc", Pins("C11", dir="o")), + Subsignal("tx_clk", Pins("A12", dir="o")), + Subsignal("tx_ctrl", Pins("C9", dir="o")), + Subsignal("tx_data", Pins("D8 C8 B8 A8", dir="o")), + Subsignal("rx_clk", Pins("E11", dir="i")), + Subsignal("rx_ctrl", Pins("A11", dir="i")), + Subsignal("rx_data", Pins("B11 A10 B10 A9", dir="i")), + Attrs(IO_TYPE="LVCMOS33") + ), + Resource("eth_int", 0, PinsN("B13", dir="i"), Attrs(IO_TYPE="LVCMOS33")), + + Resource("ddr3", 0, + Subsignal("clk", DiffPairs("H3", "J3", dir="o"), Attrs(IO_TYPE="SSTL15D_I")), + Subsignal("clk_en", Pins("P1", dir="o")), + Subsignal("we", PinsN("R3", dir="o")), + Subsignal("ras", PinsN("T3", dir="o")), + Subsignal("cas", PinsN("P2", dir="o")), + Subsignal("a", Pins("T5 M3 L3 V6 K2 W6 K3 L1 H2 L2 N1 J1 M1 K1 H1", dir="o")), + Subsignal("ba", Pins("U6 N3 N4", dir="o")), + Subsignal("dqs", DiffPairs("V4 V1", "U5 U2", dir="io"), + Attrs(IO_TYPE="SSTL15D_I", TERMINATION="OFF", DIFFRESISTOR="100")), + Subsignal("dq", Pins("T4 W4 R4 W5 R6 P6 P5 P4 R1 W3 T2 V3 U3 W1 T1 W2", dir="io"), + Attrs(TERMINATION="75")), + Subsignal("dm", Pins("U4 U1", dir="o")), + Subsignal("odt", Pins("P3", dir="o")), + Attrs(IO_TYPE="SSTL15_I", SLEWRATE="FAST") + ), + + Resource("sata", 0, + Subsignal("tx", DiffPairs("AD16", "AD17", dir="o")), + Subsignal("rx", DiffPairs("AF15", "AF16", dir="i")), + Attrs(IO_TYPE="LVDS") + ), + + Resource("ulpi", 0, + Subsignal("rst", Pins("E23", dir="o")), + Subsignal("clk", Pins("H24", dir="i")), + Subsignal("dir", Pins("F22", dir="i")), + Subsignal("nxt", Pins("F23", dir="i")), + Subsignal("stp", Pins("H23", dir="o")), + Subsignal("data", Pins("M26 L25 L26 K25 K26 J23 P25 H25", dir="io")), + Attrs(IO_TYPE="LVCMOS33") + ), + + Resource("usbc_cfg", 0, + Subsignal("scl", Pins("D24", dir="io")), + Subsignal("sda", Pins("C24", dir="io")), + Subsignal("dir", Pins("B23", dir="i")), + Subsignal("id", Pins("D23", dir="i")), + Subsignal("int", PinsN("B24", dir="i")), + Attrs(IO_TYPE="LVCMOS33") + ), + Resource("usbc_mux", 0, + Subsignal("en", Pins("C23", dir="oe")), + Subsignal("amsel", Pins("B26", dir="oe")), + Subsignal("pol", Pins("D26", dir="o")), + Subsignal("lna", DiffPairs( "AF9", "AF10", dir="i"), Attrs(IO_TYPE="LVCMOS18D")), + Subsignal("lnb", DiffPairs("AD10", "AD11", dir="o"), Attrs(IO_TYPE="LVCMOS18D")), + Subsignal("lnc", DiffPairs( "AD7", "AD8", dir="o"), Attrs(IO_TYPE="LVCMOS18D")), + Subsignal("lnd", DiffPairs( "AF6", "AF7", dir="i"), Attrs(IO_TYPE="LVCMOS18D")), + Attrs(IO_TYPE="LVCMOS33") + ), + ] + + connectors = [ + Connector("pmod", 0, "T25 U25 U24 V24 - - T26 U26 V26 W26 - -"), + Connector("pmod", 1, "U23 V23 U22 V21 - - W25 W24 W23 W22 - -"), + Connector("pmod", 2, "J24 H22 E21 D18 - - K22 J21 H21 D22 - -"), + Connector("pmod", 3, " E4 F4 E6 H4 - - F3 D4 D5 F5 - -"), + Connector("pmod", 4, "E26 D25 F26 F25 - - C26 C25 A25 A24 - -"), + Connector("pmod", 5, "D19 C21 B21 C22 - - D21 A21 A22 A23 - -"), + Connector("pmod", 6, "C16 B17 C18 B19 - - A17 A18 A19 C19 - -"), + Connector("pmod", 7, "D14 B14 E14 B16 - - C14 A14 A15 A16 - -"), + ] + + @property + def file_templates(self): + return { + **super().file_templates, + "{{name}}-openocd.cfg": r""" + interface ftdi + ftdi_vid_pid 0x0403 0x6010 + ftdi_channel 0 + ftdi_layout_init 0xfff8 0xfffb + reset_config none + adapter_khz 25000 + + {% if "85F" in platform.device -%} + jtag newtap ecp5 tap -irlen 8 -expected-id 0x81113043 ; # LF5UM5G-85F + {% else -%} + jtag newtap ecp5 tap -irlen 8 -expected-id 0x81112043 ; # LF5UM5G-45F + {% endif %} + """ + } + + def toolchain_program(self, products, name): + openocd = os.environ.get("OPENOCD", "openocd") + with products.extract("{}-openocd.cfg".format(name), "{}.svf".format(name)) \ + as (config_filename, vector_filename): + subprocess.check_call([openocd, + "-f", config_filename, + "-c", "transport select jtag; init; svf -quiet {}; exit".format(vector_filename) + ]) + + +class ECPIX545Platform(_ECPIX5Platform): + device = "LFE5UM5G-45F" + + resources = [ + *_ECPIX5Platform.resources, + + # The IT6613E HDMI transmitter has access to 8 bits per color channel. + Resource("it6613e", 0, + Subsignal("rst", PinsN("N6", dir="o")), + Subsignal("scl", Pins("C17", dir="io")), + Subsignal("sda", Pins("E17", dir="io")), + Subsignal("pclk", Pins("C1", dir="o")), + Subsignal("vsync", Pins("A4", dir="o")), + Subsignal("hsync", Pins("B4", dir="o")), + Subsignal("de", Pins("A3", dir="o")), + Subsignal("d", + Subsignal("b", Pins(" B3 C3 D3 B1 C2 D2 D1 E3", dir="o")), + Subsignal("g", Pins(" E1 F2 F1 D17 D16 E16 J6 H6", dir="o")), + Subsignal("r", Pins("E10 D11 D10 C10 D9 E8 H5 J4", dir="o")), + ), + Subsignal("mclk", Pins("E19", dir="o")), + Subsignal("sck", Pins("D6", dir="o")), + Subsignal("ws", Pins("C6", dir="o")), + Subsignal("i2s", Pins("A6 B6 A5 C5", dir="o")), + Subsignal("int", PinsN("C4", dir="i")), + Attrs(IO_TYPE="LVTTL33") + ), + ] + + +class ECPIX585Platform(_ECPIX5Platform): + device = "LFE5UM5G-85F" + + resources = [ + *_ECPIX5Platform.resources, + + # The IT6613E HDMI transmitter has access to 12 bits per color channel. The LFE5UM5G-85F + # has an additional I/O bank which is used to provide the lower 4 bits of each channel. + Resource("it6613e", 0, + Subsignal("rst", PinsN("N6", dir="o")), + Subsignal("scl", Pins("C17", dir="io")), + Subsignal("sda", Pins("E17", dir="io")), + Subsignal("pclk", Pins("C1", dir="o")), + Subsignal("vsync", Pins("A4", dir="o")), + Subsignal("hsync", Pins("B4", dir="o")), + Subsignal("de", Pins("A3", dir="o")), + Subsignal("d", + Subsignal("b", Pins("AD25 AC26 AB24 AB25 B3 C3 D3 B1 C2 D2 D1 E3", dir="o")), + Subsignal("g", Pins("AA23 AA22 AA24 AA25 E1 F2 F1 D17 D16 E16 J6 H6", dir="o")), + Subsignal("r", Pins("AD26 AE25 AF25 AE26 E10 D11 D10 C10 D9 E8 H5 J4", dir="o")), + ), + Subsignal("mclk", Pins("E19", dir="o")), + Subsignal("sck", Pins("D6", dir="o")), + Subsignal("ws", Pins("C6", dir="o")), + Subsignal("i2s", Pins("A6 B6 A5 C5", dir="o")), + Subsignal("int", PinsN("C4", dir="i")), + Attrs(IO_TYPE="LVTTL33") + ), + ] + + +if __name__ == "__main__": + import argparse + from .test.blinky import Blinky + + parser = argparse.ArgumentParser() + parser.add_argument("--variant", choices=("85", "45"), default="85", + help="platform variant (default: %(default)s)") + + args = parser.parse_args() + if args.variant == "85": + platform = ECPIX585Platform() + else: + platform = ECPIX545Platform() + + platform.build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/extensions/__init__.py b/re-bba/amaranth_boards/extensions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/re-bba/amaranth_boards/extensions/pmod.py b/re-bba/amaranth_boards/extensions/pmod.py new file mode 100644 index 0000000..5443966 --- /dev/null +++ b/re-bba/amaranth_boards/extensions/pmod.py @@ -0,0 +1,94 @@ +# Reference: https://www.digilentinc.com/Pmods/Digilent-Pmod_%20Interface_Specification.pdf + +from amaranth.build import * + + +__all__ = [ + "PmodGPIOType1Resource", + "PmodSPIType2Resource", + "PmodSPIType2AResource", + "PmodUARTType3Resource", + "PmodUARTType4Resource", + "PmodUARTType4AResource", + "PmodHBridgeType5Resource", + "PmodDualHBridgeType6Resource", +] + + +def PmodGPIOType1Resource(name, number, *args, pmod): + return Resource(name, number, + Pins("1 2 3 4", dir="io", conn=("pmod", pmod)), + *args + ) + + +def PmodSPIType2Resource(name, number, *args, pmod): + return Resource(name, number, + Subsignal("cs", PinsN("1", dir="o", conn=("pmod", pmod))), + Subsignal("clk", Pins("2", dir="o", conn=("pmod", pmod))), + Subsignal("copi", Pins("3", dir="o", conn=("pmod", pmod))), + Subsignal("cipo", Pins("4", dir="i", conn=("pmod", pmod))), + *args + ) + + +def PmodSPIType2AResource(name, number, *args, pmod): + return Resource(name, number, + Subsignal("cs", PinsN("1", dir="o", conn=("pmod", pmod))), + Subsignal("clk", Pins("2", dir="o", conn=("pmod", pmod))), + Subsignal("copi", Pins("3", dir="o", conn=("pmod", pmod))), + Subsignal("cipo", Pins("4", dir="i", conn=("pmod", pmod))), + Subsignal("int", Pins("7", dir="i", conn=("pmod", pmod))), + Subsignal("reset", Pins("8", dir="o", conn=("pmod", pmod))), + *args + ) + + +def PmodUARTType3Resource(name, number, *args, pmod): + return Resource(name, number, + Subsignal("cts", Pins("1", dir="o", conn=("pmod", pmod))), + Subsignal("rts", Pins("2", dir="i", conn=("pmod", pmod))), + Subsignal("rx", Pins("3", dir="i", conn=("pmod", pmod))), + Subsignal("tx", Pins("4", dir="o", conn=("pmod", pmod))), + *args + ) + + +def PmodUARTType4Resource(name, number, *args, pmod): + return Resource(name, number, + Subsignal("cts", Pins("1", dir="i", conn=("pmod", pmod))), + Subsignal("tx", Pins("2", dir="o", conn=("pmod", pmod))), + Subsignal("rx", Pins("3", dir="i", conn=("pmod", pmod))), + Subsignal("rts", Pins("4", dir="o", conn=("pmod", pmod))), + *args + ) + + +def PmodUARTType4AResource(name, number, *args, pmod): + return Resource(name, number, + Subsignal("cts", Pins("1", dir="i", conn=("pmod", pmod))), + Subsignal("tx", Pins("2", dir="o", conn=("pmod", pmod))), + Subsignal("rx", Pins("3", dir="i", conn=("pmod", pmod))), + Subsignal("rts", Pins("4", dir="o", conn=("pmod", pmod))), + Subsignal("int", Pins("7", dir="i", conn=("pmod", pmod))), + Subsignal("reset", Pins("8", dir="o", conn=("pmod", pmod))), + *args + ) + + +def PmodHBridgeType5Resource(name, number, *args, pmod): + return Resource(name, number, + Subsignal("dir", Pins("1", dir="o", conn=("pmod", pmod))), + Subsignal("en", Pins("2", dir="o", conn=("pmod", pmod))), + Subsignal("sa", Pins("3", dir="i", conn=("pmod", pmod))), + Subsignal("sb", Pins("4", dir="i", conn=("pmod", pmod))), + *args + ) + + +def PmodDualHBridgeType6Resource(name, number, *args, pmod): + return Resource(name, number, + Subsignal("dir", Pins("1 3", dir="o", conn=("pmod", pmod))), + Subsignal("en", Pins("2 4", dir="o", conn=("pmod", pmod))), + *args + ) diff --git a/re-bba/amaranth_boards/fomu_hacker.py b/re-bba/amaranth_boards/fomu_hacker.py new file mode 100644 index 0000000..14fa8fc --- /dev/null +++ b/re-bba/amaranth_boards/fomu_hacker.py @@ -0,0 +1,51 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["FomuHackerPlatform"] + + +class FomuHackerPlatform(LatticeICE40Platform): + device = "iCE40UP5K" + package = "UWG30" + default_clk = "clk48" + resources = [ + Resource("clk48", 0, Pins("F5", dir="i"), + Clock(48e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + *LEDResources(pins="A5", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + RGBLEDResource(0, + r="C5", g="B5", b="A5", invert=True, + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + + DirectUSBResource(0, d_p="A4", d_n="A2", pullup="D5", + attrs=Attrs(IO_STANDARD="SB_LVCMOS"), + ), + + *SPIFlashResources(0, + cs_n="C1", clk="D1", copi="F1", cipo="E1", + attrs=Attrs(IO_STANDARD="SB_LVCMOS"), + ), + ] + + connectors = [ + Connector("pin", 0, "F4"), + Connector("pin", 1, "E5"), + Connector("pin", 2, "E4"), + Connector("pin", 3, "F2"), + ] + + def toolchain_program(self, products, name): + dfu_util = os.environ.get("DFU_UTIL", "dfu-util") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([dfu_util, "-D", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + FomuHackerPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/fomu_pvt.py b/re-bba/amaranth_boards/fomu_pvt.py new file mode 100644 index 0000000..ef27dbd --- /dev/null +++ b/re-bba/amaranth_boards/fomu_pvt.py @@ -0,0 +1,51 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["FomuPVTPlatform"] + + +class FomuPVTPlatform(LatticeICE40Platform): + device = "iCE40UP5K" + package = "UWG30" + default_clk = "clk48" + resources = [ + Resource("clk48", 0, Pins("F4", dir="i"), + Clock(48e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + *LEDResources(pins="A5", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + RGBLEDResource(0, + r="B5", g="A5", b="C5", invert=True, + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + + + DirectUSBResource(0, d_p="A1", d_n="A2", pullup="A4", + attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + + *SPIFlashResources(0, + cs_n="C1", clk="D1", copi="F1", cipo="E1", + attrs=Attrs(IO_STANDARD="SB_LVCMOS"), + ), + + Resource("touch", 0, Pins("E4")), + Resource("touch", 1, Pins("D5")), + Resource("touch", 2, Pins("E5")), + Resource("touch", 3, Pins("F5")), + ] + + connectors = [] + + def toolchain_program(self, products, name): + dfu_util = os.environ.get("DFU_UTIL", "dfu-util") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([dfu_util, "-D", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + FomuPVTPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/genesys2.py b/re-bba/amaranth_boards/genesys2.py new file mode 100644 index 0000000..008dced --- /dev/null +++ b/re-bba/amaranth_boards/genesys2.py @@ -0,0 +1,363 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["Genesys2Platform"] + + +class Genesys2Platform(Xilinx7SeriesPlatform): + """Platform file for Diglient Genesys2 Kitex-7 board. + https://reference.digilentinc.com/reference/programmable-logic/genesys-2/start""" + + device = "xc7k325t" + package = "ffg900" + speed = "2" + + def __init__(self, JP6="2V5"): + super().__init__() + + assert JP6 in ["1V2", "1V8", "2V5", "3V3"] + self._JP6 = JP6 + + def bank15_16_17_iostandard(self): + return "LVCMOS" + self._JP6.replace('V', '') + + default_rst = "rst" + default_clk = "clk" + resources = [ + Resource("rst", 0, PinsN("R19", dir="i"), + Attrs(IOSTANDARD="LVCMOS33")), + Resource("clk", 0, DiffPairs(p="AD12 ", n="AD11", dir="i"), + Clock(200e6), Attrs(IOSTANDARD="LVDS")), + *ButtonResources(pins={ + "w": "M20", + "e": "C19", + "n": "B19", + "s": "M19", + "c": "E18"}, attrs=Attrs(IOSTANDARD=bank15_16_17_iostandard)), + *SwitchResources(pins="G19 G25 H24 K19 N19 P19", + attrs=Attrs(IOSTANDARD=bank15_16_17_iostandard)), + *SwitchResources(pins={ + 6: "P26", + 7: "P27"}, attrs=Attrs(IOSTANDARD="LVCMOS33")), + *LEDResources(pins="T28 V19 U30 U29 V20 V26 W24 W23", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + Resource("fan", 0, + Subsignal("pwm", Pins("W19", dir="o")), + Subsignal("tach", Pins("V21", dir="i")), + Attrs(IOSTANDARD="LVCMOS33")), + UARTResource(0, rx="Y20", tx="Y23", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + I2CResource(0, scl="AE30", sda="AF30", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + Resource("ddr3", 0, + Subsignal("rst", PinsN("AG5", dir="o"), + Attrs(IOSTANDARD="SSTL15")), + Subsignal("clk", + DiffPairs(p="AB9", n="AC9", dir="o"), + Attrs(IOSTANDARD="DIFF_SSTL15_DCI")), + Subsignal("clk_en", Pins("AJ9", dir="o")), + Subsignal("cs", PinsN("AH12", dir="o")), + Subsignal("we", PinsN("AG13", dir="o")), + Subsignal("ras", PinsN("AE11", dir="o")), + Subsignal("cas", PinsN("AF11", dir="o")), + Subsignal("a", Pins( + "AC12 AE8 AD8 AC10 AD9 AA13 AA10 AA11 " + "Y10 Y11 AB8 AA8 AB12 AA12 AH9 AG9", dir="o")), + Subsignal("ba", Pins("AE9 AB10 AC11", dir="o")), + Subsignal("dqs", + DiffPairs(p="AD2 AG4 AG2 AH7", + n="AD1 AG3 AH1 AJ7", dir="io"), + Attrs(IOSTANDARD="DIFF_SSTL15_DCI", ODT="RTT_40")), + Subsignal("dq", Pins( + "AD3 AC2 AC1 AC5 AC4 AD6 AE6 AC7 " + "AF2 AE1 AF1 AE4 AE3 AE5 AF5 AF6 " + "AJ4 AH6 AH5 AH2 AJ2 AJ1 AK1 AJ3 " + "AF7 AG7 AJ6 AK6 AJ8 AK8 AK5 AK4", dir="io"), + Attrs(ODT="RTT_40")), + Subsignal("dm", Pins("AD4 AF3 AH4 AF8", dir="o")), + Subsignal("odt", Pins("AK9", dir="o")), + Attrs(IOSTANDARD="SSTL15_DCI", SLEW="FAST", + OUTPUT_IMPEDANCE="RDRV_40_40")), + Resource("audio_i2c", 0, # ADAU1761 I2C + Subsignal("scl", Pins("AE19", dir="io")), + Subsignal("sda", Pins("AF18", dir="io")), + Subsignal("adr", Pins("AD19 AG19", dir="o")), + Attrs(IOSTANDARD="LVCMOS18")), + Resource("audio_i2s", 0, # ADAU1761 ADC, I2S + Subsignal("clk", Pins("AG18", dir="o")), # BCLK + Subsignal("sd_adc", Pins("AH19", dir="o")), # ADC_SDATA + Subsignal("sd_dac", Pins("AJ19", dir="i")), # DAC_SDATA + Subsignal("ws", Pins("AJ18", dir="o")), # LRCLK + Attrs(IOSTANDARD="LVCMOS18")), + Resource("audio_clk", 0, # ADAU1761 MCLK + Pins("AK19", dir="o"), Attrs(IOSTANDARD="LVCMOS18")), + SPIResource(0, # OLED, SSD1306, 128 x 32 + cs_n="dummy-cs0", clk="AF17", copi="Y15", + cipo="dummy-cipo0", reset="AB17", + attrs=Attrs(IOSTANDARD="LVCMOS18")), + Resource("oled", 0, # OLED, UG-2832HSWEG04 + Subsignal("dc", Pins("AC17", dir="o")), + Subsignal("vdd_en", PinsN("AG17", dir="o")), + Subsignal("vbat_en", PinsN("AB22", dir="o"), + Attrs(IOSTANDARD="LVCMOS33")), + Attrs(IOSTANDARD="LVCMOS18")), + Resource("hdmi", 0, # HDMI TX, connector J4 + Subsignal("scl", Pins("AF27", dir="io"), + Attrs(IOSTANDARD="LVCMOS33")), + Subsignal("sda", Pins("AF26", dir="io"), + Attrs(IOSTANDARD="LVCMOS33")), + Subsignal("clk", + DiffPairs(p="AA20", n="AB20", dir="o")), + Subsignal("d", + DiffPairs(p="AC20 AA22 AB24", + n="AC21 AA23 AC25", dir="o")), + Attrs(IOSTANDARD="TMDS_33")), + Resource("hdmi", 1, # HDMI RX, connector J5 + Subsignal("scl", Pins("AJ28", dir="io"), + Attrs(IOSTANDARD="LVCMOS33")), + Subsignal("sda", Pins("AJ29", dir="io"), + Attrs(IOSTANDARD="LVCMOS33")), + Subsignal("clk", DiffPairs(p="AE28", n="AF28", dir="i")), + Subsignal("rx", + DiffPairs(p="AJ26 AG27 AH26", + n="AK26 AG28 AH27", dir="i")), + Attrs(IOSTANDARD="TMDS_33")), + VGAResource(0, + r="AK25 AG25 AH25 AK24 AJ24", + g="AJ23 AJ22 AH22 AK21 AJ21 AK23", + b="AH20 AG20 AF21 AK20 AG22", + hs="AF20", vs="AG23", invert_sync=True, + attrs=Attrs(IOSTANDARD="LVCMOS33")), + *SDCardResources(0, clk="R28", cmd="R29", dat0="R26", dat1="R30", + dat2="P29", dat3="T30", cd="P28", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + Resource("sd_card_rst", 0, + Pins("AE24", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), + ULPIResource(0, data="AE14 AE15 AC15 AC16 AB15 AA15 AD14 AC14", + rst="AB14", clk="AD18", dir="Y16", stp="AA17", nxt="AA16", + clk_dir="i", rst_invert=True, attrs=Attrs(IOSTANDARD="LVCMOS18")), + Resource("vusb_oc", 0, + PinsN("AF16", dir="i"), Attrs(IOSTANDARD="LVCMOS18")), + Resource("eth_rgmii", 0, + Subsignal("rst", PinsN("AH24", dir="o"), + Attrs(IOSTANDARD="LVCMOS33")), + Subsignal("mdc", Pins("AF12", dir="o")), + Subsignal("mdio", Pins("AG12", dir="io")), + Subsignal("tx_clk", Pins("AE10", dir="o")), + Subsignal("tx_ctl", Pins("AK14", dir="o")), + Subsignal("tx_data", Pins("AJ12 AK11 AJ11 AK10", dir="o")), + Subsignal("rx_clk", Pins("AG10", dir="i")), + Subsignal("rx_ctl", Pins("AH11", dir="i")), + Subsignal("rx_data", Pins("AJ14 AH14 AK13 AJ13", dir="i")), + Attrs(IOSTANDARD="LVCMOS15"))] + + connectors = [ + Connector("pmod", 0, # JA + "U27 U28 T26 T27 - - " + "T22 T23 T20 T21 - -"), + Connector("pmod", 1, # JB + "V29 V30 V25 W26 - - " + "T25 U25 U22 U23 - -"), + Connector("pmod", 2, # JC + "AC26 AJ27 AH30 AK29 - - " + "AD26 AG30 AK30 AK28 - -"), + Connector("pmod", 3, # JD + "V27 Y30 V24 W22 - - " + "U24 Y26 V22 W21 - -"), + Connector("pmod", 4, # JXADC + "J23 K23 L22 L21 - - " + "J24 K24 L23 K21 - -"), + Connector("hpc", 0, + {"dp1_m2c_p": "Y6", + "dp1_m2c_n": "Y5", + "dp2_m2c_p": "W4", + "dp2_m2c_n": "W3", + "dp3_m2c_p": "V6", + "dp3_m2c_n": "V5", + "dp1_c2m_p": "V2", + "dp1_c2m_n": "V1", + "dp2_c2m_p": "U4", + "dp2_c2m_n": "U3", + "dp3_c2m_p": "T2", + "dp3_c2m_n": "T1", + "dp0_c2m_p": "Y2", + "dp0_c2m_n": "Y1", + "dp0_m2c_p": "AA4", + "dp0_m2c_n": "AA3", + "la06_p": "D29", + "la06_n": "C30", + "la10_p": "B27", + "la10_n": "A27", + "la14_p": "C24", + "la14_n": "B24", + "la18_cc_p": "D17", + "la18_cc_n": "D18", + "la27_p": "A20", + "la27_n": "A21", + "ha01_cc_p": "M28", + "ha01_cc_n": "L28", + "ha05_p": "J29", + "ha05_n": "H29", + "ha09_p": "L30", + "ha09_n": "K30", + "ha13_p": "K26", + "ha13_n": "J26", + "ha16_p": "M22", + "ha16_n": "M23", + "ha20_p": "G27", + "ha20_n": "F27", + "clk1_m2c_p": "E28", + "clk1_m2c_n": "D28", + "la00_cc_p": "D27", + "la00_cc_n": "C27", + "la03_p": "E29", + "la03_n": "E30", + "la08_p": "C29", + "la08_n": "B29", + "la12_p": "F26", + "la12_n": "E26", + "la16_p": "E23", + "la16_n": "D23", + "la20_p": "G22", + "la20_n": "F22", + "la22_p": "J17", + "la22_n": "H17", + "la25_p": "D22", + "la25_n": "C22", + "la29_p": "B18", + "la29_n": "A18", + "la31_p": "C17", + "la31_n": "B17", + "la33_p": "D16", + "la33_n": "C16", + "ha03_p": "N25", + "ha03_n": "N26", + "ha07_p": "M29", + "ha07_n": "M30", + "ha11_p": "P23", + "ha11_n": "N24", + "ha14_p": "N27", + "ha14_n": "M27", + "ha18_p": "E19", + "ha18_n": "D19", + "ha22_p": "D21", + "ha22_n": "C21", + "gbtclk1_m2c_p": "N8", + "gbtclk1_m2c_n": "N7", + "gbtclk0_m2c_p": "L8", + "gbtclk0_m2c_n": "L7", + "la01_cc_p": "D26", + "la01_cc_n": "C26", + "la05_p": "B30", + "la05_n": "A30", + "la09_p": "B28", + "la09_n": "A28", + "la13_p": "E24", + "la13_n": "D24", + "la17_cc_p": "F21", + "la17_cc_n": "E21", + "la23_p": "G17", + "la23_n": "F17", + "la26_p": "B22", + "la26_n": "A22", + "pg_m2c": "AH21", + "ha00_cc_p": "K28", + "ha00_cc_n": "K29", + "ha04_p": "M24", + "ha04_n": "M25", + "ha08_p": "J27", + "ha08_n": "J28", + "ha12_p": "L26", + "ha12_n": "L27", + "ha15_p": "J21", + "ha15_n": "J22", + "ha19_p": "G29", + "ha19_n": "F30", + "prsnt_m2c_b": "AA21", + "clk0_m2c_p": "F20", + "clk0_m2c_n": "E20", + "la02_p": "H30", + "la02_n": "G30", + "la04_p": "H26", + "la04_n": "H27", + "la07_p": "F25", + "la07_n": "E25", + "la11_p": "A25", + "la11_n": "A26", + "la15_p": "B23", + "la15_n": "A23", + "la19_p": "H21", + "la19_n": "H22", + "la21_p": "L17", + "la21_n": "L18", + "la24_p": "H20", + "la24_n": "G20", + "la28_p": "J19", + "la28_n": "H19", + "la30_p": "A16", + "la30_n": "A17", + "la32_p": "K18", + "la32_n": "J18", + "ha02_p": "P21", + "ha02_n": "P22", + "ha06_p": "N29", + "ha06_n": "N30", + "ha10_p": "N21", + "ha10_n": "N22", + "ha17_cc_p": "C25", + "ha17_cc_n": "B25", + "ha21_p": "G28", + "ha21_n": "F28", + "ha23_p": "G18", + "ha23_n": "F18"})] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = { + "script_after_read": "auto_detect_xpm", + "script_before_bitstream": + "set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]", + "add_constraints": """ + set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design] + set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] + set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] + set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + """} + return super().toolchain_prepare( + fragment, name, **overrides, **kwargs) + + @property + def file_templates(self): + return { + **super().file_templates, + "{{name}}-openocd.cfg": r""" + source [find interface/ftdi/digilent-hs1.cfg] + # fix channel + ftdi_channel 1 + adapter_khz 25000 + transport select jtag + source [find cpld/xilinx-xc7.cfg] + source [find cpld/jtagspi.cfg] + """ + } + + def toolchain_program(self, products, name): + openocd = os.environ.get("OPENOCD", "openocd") + with products.extract("{}-openocd.cfg".format(name), + "{}.bit".format(name)) as ( + config_filename, bitstream_filename): + subprocess.check_call([ + openocd, + "-f", config_filename, + "-c", "init; pld load 0 {}; exit".format(bitstream_filename)]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + Genesys2Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/ice40_hx1k_blink_evn.py b/re-bba/amaranth_boards/ice40_hx1k_blink_evn.py new file mode 100644 index 0000000..5b61fb6 --- /dev/null +++ b/re-bba/amaranth_boards/ice40_hx1k_blink_evn.py @@ -0,0 +1,48 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["ICE40HX1KBlinkEVNPlatform"] + + +class ICE40HX1KBlinkEVNPlatform(LatticeICE40Platform): + device = "iCE40HX1K" + package = "VQ100" + default_clk = "clk3p3" + resources = [ + Resource("clk3p3", 0, Pins("13", dir="i"), Clock(3.3e6), + Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + *LEDResources(pins="59 56 53 51", attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + + Resource("touch", 0, Pins("60"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("touch", 1, Pins("57"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("touch", 2, Pins("54"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("touch", 3, Pins("52"), Attrs(IO_STANDARD="SB_LVCMOS")), + + *SPIFlashResources(0, + cs_n="49", clk="48", copi="45", cipo="46", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + ] + connectors = [ + Connector("pmod", 1, "10 9 8 7 - - 4 3 2 1 - -"), # J1 + Connector("pmod", 5, "40 42 62 64 - - 37 41 63 45 - -"), # J5 + Connector("pmod", 6, "25 24 21 20 - - 26 27 28 33 - -"), # J6 + Connector("pmod", 11, "49 45 46 48 - -"), # J11 + Connector("pmod", 12, "59 56 53 51 - -"), # J12 + ] + + def toolchain_program(self, products, name): + iceburn = os.environ.get("ICEBURN", "iCEburn") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([iceburn, "-evw", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + ICE40HX1KBlinkEVNPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/ice40_hx8k_b_evn.py b/re-bba/amaranth_boards/ice40_hx8k_b_evn.py new file mode 100644 index 0000000..da24c29 --- /dev/null +++ b/re-bba/amaranth_boards/ice40_hx8k_b_evn.py @@ -0,0 +1,68 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["ICE40HX8KBEVNPlatform"] + + +class ICE40HX8KBEVNPlatform(LatticeICE40Platform): + device = "iCE40HX8K" + package = "CT256" + default_clk = "clk12" + resources = [ + Resource("clk12", 0, Pins("J3", dir="i"), + Clock(12e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + *LEDResources( + pins="C3 B3 C4 C5 A1 A2 B4 B5", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), # D2..D9 + + UARTResource(0, + rx="B10", tx="B12", rts="B13", cts="A15", dtr="A16", dsr="B14", dcd="B15", + attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1), + role="dce" + ), + + *SPIFlashResources(0, + cs_n="R12", clk="R11", copi="P12", cipo="P11", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + ] + connectors = [ + Connector("j", 1, # J1 + "A16 - A15 B15 B13 B14 - - B12 B11 " + "A11 B10 A10 C9 - - A9 B9 B8 A7 " + "B7 C7 - - A6 C6 B6 C5 A5 C4 " + "- - B5 C3 B4 B3 A2 A1 - - "), + Connector("j", 2, # J2 + "- - - R15 P16 P15 - - N16 M15 " + "M16 L16 K15 K16 - - K14 J14 G14 F14 " + "J15 H14 - - H16 G15 G16 F15 F16 E14 " + "- - E16 D15 D16 D14 C16 B16 - - "), + Connector("j", 3, # J3 + "R16 - T15 T16 T13 T14 - - N12 P13 " + "N10 M11 T11 P10 - - T10 R10 P8 P9 " + "T9 R9 - - T7 T8 T6 R6 T5 R5 " + "- - R3 R4 R2 T3 T1 T2 - - "), + Connector("j", 4, # J4 + "- - - R1 P1 P2 - - N3 N2 " + "M2 M1 L3 L1 - - K3 K1 J2 J1 " + "H2 J3 - - G2 H1 F2 G1 E2 F1 " + "- - D1 D2 C1 C2 B1 B2 - - "), + ] + + def toolchain_program(self, products, name): + iceprog = os.environ.get("ICEPROG", "iceprog") + with products.extract("{}.bin".format(name)) as bitstream_filename: + # TODO: this should be factored out and made customizable + subprocess.check_call([iceprog, "-S", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + ICE40HX8KBEVNPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/ice40_up5k_b_evn.py b/re-bba/amaranth_boards/ice40_up5k_b_evn.py new file mode 100644 index 0000000..10a100b --- /dev/null +++ b/re-bba/amaranth_boards/ice40_up5k_b_evn.py @@ -0,0 +1,66 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["ICE40UP5KBEVNPlatform"] + + +class ICE40UP5KBEVNPlatform(LatticeICE40Platform): + device = "iCE40UP5K" + package = "SG48" + default_clk = "clk12" + resources = [ + # J51 must be connected to use clk12 (it is by default) + Resource("clk12", 0, Pins("35", dir="i"), + Clock(12e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + # 3 LEDs are present in an RGB common-anode package. + *LEDResources( + pins="39 40 41", invert=True, + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + Resource("led_b", 0, PinsN("39", dir="o"), + Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 0, PinsN("40", dir="o"), + Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_r", 0, PinsN("41", dir="o"), + Attrs(IO_STANDARD="SB_LVCMOS")), + + # 4 DIP switches are available, requiring internal pull-ups. + # The switches' "ON" label points to the position which + # connects them to ground, so invert the inputs. + *SwitchResources(pins="23 25 34 43", invert=True, + attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1) + ), + + *SPIFlashResources(0, + cs_n="16", clk="15", copi="14", cipo="17", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + ] + connectors = [ + Connector("aardvark", 0, # J1 + "- - - - 14 - 15 17 16 -"), + Connector("pmod", 0, # U6 (board), U11 (schematic) + "16 14 17 15 - - 27 26 32 31 - -"), + Connector("j", 0, # 'Header A' (J52) + "- - 39 14 40 17 - 15 41 16 - -"), + Connector("j", 1, # 'Header B' (J2) + "- - 23 - 25 - 26 36 27 42 32 38 31 28 37 15 34 - 43 -"), + Connector("j", 2, # 'Header C' (J3) + "- 12 3 21 3 13 48 20 45 19 47 18 44 11 46 10 2 9 - 6"), + ] + + def toolchain_program(self, products, name): + iceprog = os.environ.get("ICEPROG", "iceprog") + with products.extract("{}.bin".format(name)) as bitstream_fn: + subprocess.check_call([iceprog, bitstream_fn]) + + +if __name__ == "__main__": + from .test.blinky import * + ICE40UP5KBEVNPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/icebreaker.py b/re-bba/amaranth_boards/icebreaker.py new file mode 100644 index 0000000..687ea16 --- /dev/null +++ b/re-bba/amaranth_boards/icebreaker.py @@ -0,0 +1,75 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["ICEBreakerPlatform"] + + +class ICEBreakerPlatform(LatticeICE40Platform): + device = "iCE40UP5K" + package = "SG48" + default_clk = "clk12" + resources = [ + Resource("clk12", 0, Pins("35", dir="i"), + Clock(12e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + *LEDResources(pins="11 37", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + # Semantic aliases + Resource("led_r", 0, PinsN("11", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 0, PinsN("37", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + + *ButtonResources(pins="10", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + + UARTResource(0, + rx="6", tx="9", + attrs=Attrs(IO_STANDARD="SB_LVTTL", PULLUP=1) + ), + + *SPIFlashResources(0, + cs_n="16", clk="15", copi="14", cipo="17", wp_n="12", hold_n="13", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + ] + connectors = [ + Connector("pmod", 0, " 4 2 47 45 - - 3 48 46 44 - -"), # PMOD1A + Connector("pmod", 1, "43 38 34 31 - - 42 36 32 28 - -"), # PMOD1B + Connector("pmod", 2, "27 25 21 19 - - 26 23 20 18 - -"), # PMOD2 + ] + # The attached LED/button section can be either used standalone or as a PMOD. + # Attach to platform using: + # p.add_resources(p.break_off_pmod) + # pmod_btn = plat.request("user_btn") + break_off_pmod = [ + *LEDResources(pins={2: "7", 3: "1", 4: "2", 5: "8", 6: "3"}, conn=("pmod", 2), + attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + # Semantic aliases + Resource("led_r", 1, Pins("7", dir="o", conn=("pmod", 2)), + Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 1, Pins("1", dir="o", conn=("pmod", 2)), + Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 2, Pins("2", dir="o", conn=("pmod", 2)), + Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 3, Pins("8", dir="o", conn=("pmod", 2)), + Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 4, Pins("3", dir="o", conn=("pmod", 2)), + Attrs(IO_STANDARD="SB_LVCMOS")), + + *ButtonResources(pins={1: "9", 2: "4", 3: "10"}, conn=("pmod", 2), + attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + ] + + def toolchain_program(self, products, name): + iceprog = os.environ.get("ICEPROG", "iceprog") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([iceprog, bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + p = ICEBreakerPlatform() + p.add_resources(p.break_off_pmod) + p.build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/icebreaker_bitsy.py b/re-bba/amaranth_boards/icebreaker_bitsy.py new file mode 100644 index 0000000..3d25236 --- /dev/null +++ b/re-bba/amaranth_boards/icebreaker_bitsy.py @@ -0,0 +1,70 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["ICEBreakerBitsyPlatform"] + + +class ICEBreakerBitsyPlatform(LatticeICE40Platform): + device = "iCE40UP5K" + package = "SG48" + default_clk = "clk12" + resources = [ + Resource("clk12", 0, Pins("35", dir="i"), + Clock(12e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + DirectUSBResource(0, d_p="42", d_n="38", pullup="37", + attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + + *SPIFlashResources(0, + cs_n="16", clk="15", copi="14", cipo="17", wp_n="18", hold_n="19", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + + RGBLEDResource(0, r="39", g="40", b="41", invert=True, + attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + *LEDResources(pins="25 6", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_r", 0, PinsN("25", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 0, PinsN("6", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), + + *ButtonResources(pins="2", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + ] + connectors = [ + Connector("edge", 0, # Pins bottom P0 - P12, + {"0":"47", "1":"44", "2":"48", "3":"45", "4": "4", "5": "3", + "6": "9", "7":"10", "8":"11", "9":"12", "10":"21", "11":"13", + "12":"20", "13":"25", "14":"23", "15":"27", "16":"26", "17":"28", + "18":"31", "19":"32", "20":"34", "21":"36", "22":"43", "23":"46"} + ), + Connector("pmod", 1, " 0 2 4 6 - - 1 3 5 7 - -", conn=("edge", "0")), # PMOD 1 + Connector("pmod", 2, "22 19 16 17 - - 21 18 15 20 - -", conn=("edge", "0")), # PMOD 2 + Connector("pmod", 3, "14 9 11 8 - - 13 10 12 23 - -", conn=("edge", "0")) # PMOD 3 + ] + + def toolchain_program(self, products, name, run_vid=None, run_pid=None, dfu_vid="1d50", dfu_pid="6146", reset=True): + dfu_util = os.environ.get("DFU_UTIL", "dfu-util") + + # Construct the device runtime and DFU vid pid string + dev_str = "" + if run_vid or run_pid: + dev_str = "{}:{}".format(run_vid or "", run_pid or "") + dev_str += ",{}:{}".format(dfu_vid or "", dfu_pid or "") + + # Construct the argument list for dfu-util + args = [dfu_util, "-d", dev_str, "-a", "0"] + if reset: args.append("-R") + args.append("-D") + + # Run dfu-util + with products.extract("{}.bin".format(name)) as bitstream_filename: + args.append(bitstream_filename) + subprocess.check_call(args) + + +if __name__ == "__main__": + from .test.blinky import * + ICEBreakerBitsyPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/icestick.py b/re-bba/amaranth_boards/icestick.py new file mode 100644 index 0000000..453d84f --- /dev/null +++ b/re-bba/amaranth_boards/icestick.py @@ -0,0 +1,53 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["ICEStickPlatform"] + + +class ICEStickPlatform(LatticeICE40Platform): + device = "iCE40HX1K" + package = "TQ144" + default_clk = "clk12" + resources = [ + Resource("clk12", 0, Pins("21", dir="i"), + Clock(12e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")), + + *LEDResources(pins="99 98 97 96 95", attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + + UARTResource(0, + rx="9", tx="8", rts="7", cts="4", dtr="3", dsr="2", dcd="1", + attrs=Attrs(IO_STANDARD="SB_LVTTL", PULLUP=1), + role="dce" + ), + + IrDAResource(0, + rx="106", tx="105", sd="107", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + + *SPIFlashResources(0, + cs_n="71", clk="70", copi="67", cipo="68", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + ] + connectors = [ + Connector("pmod", 0, "78 79 80 81 - - 87 88 90 91 - -"), # J2 + + Connector("j", 1, "- - 112 113 114 115 116 117 118 119"), # J1 + Connector("j", 3, "- - 62 61 60 56 48 47 45 44"), # J3 + ] + + def toolchain_program(self, products, name): + iceprog = os.environ.get("ICEPROG", "iceprog") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([iceprog, bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + ICEStickPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/icesugar.py b/re-bba/amaranth_boards/icesugar.py new file mode 100644 index 0000000..d78c398 --- /dev/null +++ b/re-bba/amaranth_boards/icesugar.py @@ -0,0 +1,64 @@ +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["ICESugarPlatform"] + + +class ICESugarPlatform(LatticeICE40Platform): + device = "iCE40UP5K" + package = "SG48" + default_clk = "clk12" + + resources = [ + Resource("clk12", 0, Pins("35", dir="i"), + Clock(12e6), Attrs(GLOBAL=True, IO_STANDARD="LVCMOS33")), + + *LEDResources(pins="40 41 39", invert=True, attrs=Attrs(IO_STANDARD="LVCMOS33")), + + # Semantic aliases + Resource("led_r", 0, PinsN("40", dir="o"), Attrs(IO_STANDARD="LVCMOS33")), + Resource("led_g", 0, PinsN("41", dir="o"), Attrs(IO_STANDARD="LVCMOS33")), + Resource("led_b", 0, PinsN("39", dir="o"), Attrs(IO_STANDARD="LVCMOS33")), + + *SwitchResources( + pins="18 19 20 21", + attrs=Attrs(IO_STANDARD="LVCMOS33") + ), + + UARTResource(0, + rx="4", tx="6", + attrs=Attrs(IO_STANDARD="LVTTL33", PULLUP=1) + ), + + *SPIFlashResources(0, + cs_n="16", clk="15", copi="14", cipo="17", wp_n="12", hold_n="13", + attrs=Attrs(IO_STANDARD="LVCMOS33") + ), + + Resource("usb", 0, + Subsignal("d_p", Pins("10", dir="io")), + Subsignal("d_n", Pins("9", dir="io")), + Subsignal("pullup", Pins("11", dir="o")), + Attrs(IO_STANDARD="LVCMOS33") + ), + ] + + connectors = [ + Connector("pmod", 0, "10 6 3 48 - - 9 4 2 47 - -"), # PMOD1 - IO pins shared by USB + Connector("pmod", 1, "46 44 42 37 - - 45 43 38 36 - -"), # PMOD2 + Connector("pmod", 2, "34 31 27 25 - - 32 28 26 23 - -"), # PMOD3 + Connector("pmod", 3, "21 20 19 18 - - - - - - - -"), # PMOD4 - IO pins used for switches via jumpers + ] + + def toolchain_program(self, products, name): + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call(["icesprog", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + ICESugarPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/icesugar_nano.py b/re-bba/amaranth_boards/icesugar_nano.py new file mode 100644 index 0000000..1f2b07b --- /dev/null +++ b/re-bba/amaranth_boards/icesugar_nano.py @@ -0,0 +1,48 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["ICESugarNanoPlatform"] + + +class ICESugarNanoPlatform(LatticeICE40Platform): + device = "iCE40LP1K" + package = "CM36" + default_clk = "clk12" + + resources = [ + Resource("clk12", 0, Pins("D1", dir="i"), + Clock(12e6), Attrs(GLOBAL=True, IO_STANDARD="LVCMOS33")), + + *LEDResources(pins="B6", invert=False, attrs=Attrs(IO_STANDARD="LVCMOS33")), + + UARTResource(0, + tx="B3", rx="A3", + attrs=Attrs(IO_STANDARD="LVTTL33", PULLUP=1) + ), + + *SPIFlashResources(0, + cs_n="D5", clk="E5", copi="E4", cipo="F5", + attrs=Attrs(IO_STANDARD="LVCMOS33") + ), + ] + + connectors = [ + Connector("pmod", 0, "E2 D1 B1 A1 - -"), # PMOD1 + Connector("pmod", 1, "B3 A3 B6 C5 - -"), # PMOD2 + Connector("pmod", 2, "B4 B5 E1 B1 - - C6 E3 C2 A1 - -"), # PMOD3 + ] + + def toolchain_program(self, products, name): + icesprog = os.environ.get("ICESPROG", "icesprog") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([icesprog, bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + ICESugarNanoPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/kc705.py b/re-bba/amaranth_boards/kc705.py new file mode 100644 index 0000000..d513da2 --- /dev/null +++ b/re-bba/amaranth_boards/kc705.py @@ -0,0 +1,42 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["KC705Platform"] + + +class KC705Platform(Xilinx7SeriesPlatform): + device = "xc7k325t" + package = "ffg900" + speed = "2" + default_clk = "clk156" + resources = [ + Resource("clk156", 0, DiffPairs("K28", "K29", dir="i"), + Clock(156e6), Attrs(IOSTANDARD="LVDS_25")), + + *LEDResources(pins="AB8 AA8 AC9 AB9 AE26 G19 E18 F16", + attrs=Attrs(IOSTANDARD="LVCMOS15")), + + UARTResource(0, + rx="M19", tx="K24", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + ] + connectors = [] + + def toolchain_program(self, products, name): + openocd = os.environ.get("OPENOCD", "openocd") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.check_call([openocd, + "-c", "source [find board/kc705.cfg]; init; pld load 0 {}; exit" + .format(bitstream_filename) + ]) + + +if __name__ == "__main__": + from .test.blinky import * + KC705Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/kcu105.py b/re-bba/amaranth_boards/kcu105.py new file mode 100644 index 0000000..1a886d2 --- /dev/null +++ b/re-bba/amaranth_boards/kcu105.py @@ -0,0 +1,37 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_ultrascale import * +from .resources import * + + +__all__ = ["KCU105Platform"] + + +class KCU105Platform(XilinxUltraScalePlatform): + device = "xcku040" + package = "ffva1156" + speed = "2-e" + default_clk = "clk125" + resources = [ + Resource("clk125", 0, DiffPairs("G10", "F10", dir="i"), + Clock(125e6), Attrs(IOSTANDARD="LVDS")), + + *LEDResources(pins="AP8 H23 P20 P21 N22 M22 R23 P23", + attrs=Attrs(IOSTANDARD="LVCMOS18")), + ] + connectors = [] + + def toolchain_program(self, products, name): + openocd = os.environ.get("OPENOCD", "openocd") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.check_call([openocd, + "-c", "source [find board/kcu105.cfg]; init; pld load 0 {}; exit" + .format(bitstream_filename) + ]) + + +if __name__ == "__main__": + from .test.blinky import * + KCU105Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/machxo3_sk.py b/re-bba/amaranth_boards/machxo3_sk.py new file mode 100644 index 0000000..d4bba2b --- /dev/null +++ b/re-bba/amaranth_boards/machxo3_sk.py @@ -0,0 +1,74 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_machxo_2_3l import * +from .resources import * + + +__all__ = ["MachXO3SKPlatform"] + + +class MachXO3SKPlatform(LatticeMachXO3LPlatform): + device = "LCMXO3LF-6900C" + package = "BG256" + speed = "5" + default_clk = "clk12" + resources = [ + Resource("clk12", 0, Pins("C8", dir="i"), + Clock(12e6), Attrs(IO_TYPE="LVCMOS33") + ), + + UARTResource(0, + rx="A11", tx="C11", rts="F10", cts="D11", dtr="B11", dsr="A12", dcd="B13", ri="A14", + attrs=Attrs(IO_TYPE="LVCMOS33"), role="dce" + ), # need to solder R14-R18, R20-R22 + + *LEDResources( + pins="H11 J13 J11 L12 K11 L13 N15 P16", + invert=True, attrs=Attrs(IO_TYPE="LVCMOS33") + ), # D9..D2 + + *ButtonResources(pins="B3", invert=True, attrs=Attrs(IO_TYPE="LVCMOS33")), + + *SwitchResources(pins="N2 P1 M3 N1", + invert=True, attrs=Attrs(IO_TYPE="LVCMOS33") + ), # SW2 + + *SPIFlashResources(0, + cs_n="R5", clk="P6", copi="T13", cipo="T6", + attrs=Attrs(IO_TYPE="LVCMOS33") + ), + ] + connectors = [ + Connector("j", 3, # J3 + "- - A13 C13 F8 B12 C12 E11 E10 D10 " + "- - F9 C10 E8 E9 E7 D8 D7 C7 " + "- - C5 D6 E6 C4 A10 F7 D9 B9 " + "- - B6 B7 B5 A5 B4 A4 - A3 "), + Connector("j", 4, # J4 + "- - K12 K13 M14 N14 L14 N16 M15 M16 " + "- - L15 L16 K14 K16 K15 J14 H14 J15 " + "- - J16 H15 H16 G15 G16 F15 F16 E15 " + "- - E16 E14 D16 C15 D14 F14 G14 B16 "), + Connector("j", 6, # J6 + "- - T12 T14 R11 R13 T11 M11 P11 N10 " + "- - T10 P10 R9 R10 T9 N9 P9 M8 " + "- - T8 L8 P8 M6 R7 R8 P7 T7 " + "- - L7 R6 N6 T5 R4 P4 T3 T4 "), + Connector("j", 8, # J8 + "- - H6 N3 M2 M1 L2 L1 L3 L5 " + "- - K4 J1 K1 J2 J3 H3 H2 H1 " + "- - G2 G1 F2 F1 E2 E1 D2 D1 " + "- - C2 C1 G3 B1 D3 E3 F3 F5 "), + ] + + def toolchain_program(self, products, name): + openFPGALoader = os.environ.get("OPENFPGALOADER", "openFPGALoader") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.check_call([openFPGALoader, bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + MachXO3SKPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/mercury.py b/re-bba/amaranth_boards/mercury.py new file mode 100644 index 0000000..59b61c1 --- /dev/null +++ b/re-bba/amaranth_boards/mercury.py @@ -0,0 +1,214 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_spartan_3_6 import * +from .resources import * + + +__all__ = ["MercuryPlatform"] + + +class MercuryPlatform(XilinxSpartan3APlatform): + """ + Original Mercury Board from Micro-Nova: https://www.micro-nova.com + + Mercury Manual: https://www.micro-nova.com/s/mercury_rm.pdf + Mercury Schematic: https://www.micro-nova.com/s/mercury_schematic.pdf + + The Mercury board is often paired with an extension board called the + Baseboard, which provides an ample set of I/O for FPGA beginners. + + Baseboard Manual: https://www.micro-nova.com/s/baseboard_rm.pdf + Baseboard Schematics: https://www.micro-nova.com/s/baseboard_schematic.pdf + + Mercury and Baseboard Resources: https://www.micro-nova.com/resources-mercury + """ + + device = "xc3s200a" + package = "vq100" + speed = "4" + + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("P43", dir="i"), + Attrs(IOSTANDARD="LVCMOS33"), Clock(50e6)), + + Resource("button", 0, Pins("P41", dir="i"), + Attrs(IOSTANDARD="LVTTL")), + + # The serial interface and flash memory have a shared SPI bus. + # FPGA is secondary. + SPIResource("spi_serial", 0, role="peripheral", + cs_n="P39", clk="P53", copi="P46", cipo="P51", + attrs=Attrs(IOSTANDARD="LVTTL"), + ), + + # FPGA is primary. + *SPIFlashResources(0, + cs_n="P27", clk="P53", copi="P46", cipo="P51", + attrs=Attrs(IOSTANDARD="LVTTL") + ), + + # ADC over SPI- FPGA is primary. + SPIResource("spi_adc", 0, role="controller", + cs_n="P12", clk="P9", copi="P10", cipo="P21", + attrs=Attrs(IOSTANDARD="LVTTL"), + ), + + # GPIO/SRAM Control + # 5V tolerant GPIO is shared w/ the SRAM (on 200k gate devices) using + # this pin. All GPIO except gpio:30 (and gpio:20, though see comment + # under SRAMResource) interface to the SRAM. On assertion, this signal + # will tristate the level-shifters, preventing any output on the 5V + # GPIO pins (including gpio:30 and gpio:20). + Resource("bussw_oe", 0, PinsN("P30N", dir="o"), + Attrs(IOSTANDARD="LVTTL")) + ] + + # Perhaps define some connectors as having a specific purpose- i.e. a 5V GPIO + # bus with data, peripheral-select, and control signals? + connectors = [ + Connector("gpio", 0, """P59 P60 P61 P62 P64 P57 + P56 P52 P50 P49 P85 P84 + P83 P78 P77 P65 P70 P71 + P72 P73 P5 P4 P6 P98 + P94 P93 P90 P89 P88 P86"""), # 5V I/O- LVTTL. + Connector("dio", 0, "P20 P32 P33 P34 P35 P36 P37"), # Fast 3.3V IO + # (Directly attached to FPGA)- LVCMOS33. + Connector("clkio", 0, "P40 P44"), # Clock IO (Can be used as GPIO)- + # LVCMOS33. + Connector("input", 0, "P68 P97 P7 P82"), # Input-only pins- LVCMOS33. + Connector("led", 0, "P13 P15 P16 P19"), # LEDs can be used as pins + # as well- LVTTL. + Connector("pmod", 0, "P5 P4 P6 P98 P94 P93 P90 P89") # Baseboard PMOD. + # Overlaps w/ GPIO bus. + ] + + # Some default useful extensions. Attach to platform using: + # p.add_resources(p.leds) + # pmod_btn = plat.request("led") + leds = [ + Resource("led", 0, Pins("1", dir="o", conn=("led", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("led", 1, Pins("2", dir="o", conn=("led", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("led", 2, Pins("3", dir="o", conn=("led", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("led", 3, Pins("4", dir="o", conn=("led", 0)), + Attrs(IOSTANDARD="LVTTL")), + ] + + sram = [ + SRAMResource(0, + cs_n="P3", we_n="gpio_0:29", + # According to the schematic, A19/Pin 25 on the SRAM is wired to + # gpio-0:20. However, according to the SRAM's datasheet, pin 25 is + # a NC. Do not expose for now. + a=""" gpio_0:1 gpio_0:2 gpio_0:3 gpio_0:4 gpio_0:5 gpio_0:6 + gpio_0:7 gpio_0:8 gpio_0:9 gpio_0:10 gpio_0:11 gpio_0:12 + gpio_0:13 gpio_0:14 gpio_0:15 gpio_0:16 gpio_0:17 gpio_0:18 + gpio_0:19""", + d="""gpio_0:21 gpio_0:22 gpio_0:23 gpio_0:24 gpio_0:25 gpio_0:26 + gpio_0:27 gpio_0:28""", + attrs=Attrs(IOSTANDARD="LVTTL", SLEW="FAST") + ) + ] + + # The "serial port" is in fact over SPI. The creators of the board provide + # a VHDL file for talking over this interface. In light of space + # constraints and the fact that both the FT245RL and FPGA can BOTH be + # SPI primaries, however, it may be necessary to sacrifice two "high-speed" + # (DIO, INPUT) pins instead. + serial = [ + # RX: FTDI D0, TX: FTDI D1 + UARTResource(0, rx="input_0:1", tx="dio_0:1", + attrs=Attrs(IOSTANDARD="LVCMOS33")) + ] + + # The remaining peripherals only make sense w/ the Baseboard installed. + # See: http://www.micro-nova.com/mercury-baseboard/ + _switches = [ + Resource("switch", 0, Pins("1", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("switch", 1, Pins("2", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("switch", 2, Pins("3", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("switch", 3, Pins("4", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("switch", 4, Pins("5", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("switch", 5, Pins("6", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("switch", 6, Pins("7", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("switch", 7, Pins("8", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")) + ] + + _buttons = [ + Resource("button", 1, Pins("1", dir="i", conn=("input", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("button", 2, Pins("2", dir="i", conn=("input", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("button", 3, Pins("3", dir="i", conn=("input", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("button", 4, Pins("4", dir="i", conn=("input", 0)), + Attrs(IOSTANDARD="LVTTL")) + ] + + _vga = [ + VGAResource(0, + r="dio_0:1 dio_0:2 dio_0:3", + g="dio_0:4 dio_0:5 dio_0:6", + b="dio_0:7 clkio_0:1", + hs="led_0:3", vs="led_0:4", invert_sync=True, + attrs=Attrs(IOSTANDARD="LVCMOS33", SLEW="FAST")) + ] + + _extclk = [ + Resource("extclk", 0, Pins("1", dir="i", conn=("clkio", 1)), + Attrs(IOSTANDARD="LVCMOS33")) + ] + + _sevenseg = [ + Display7SegResource(0, + a="gpio_0:13", b="gpio_0:14", c="gpio_0:15", d="gpio_0:16", + e="gpio_0:17", f="gpio_0:18", g="gpio_0:19", dp="gpio_0:20", + invert=True, attrs=Attrs(IOSTANDARD="LVTTL") + ), + Resource("display_7seg_ctrl", 0, + Subsignal("en", Pins("9 10 11 12", dir="o", conn=("gpio", 0))), + Attrs(IOSTANDARD="LVTTL") + ) + ] + + _ps2 = [ + PS2Resource(0, + clk="2", dat="1", conn=("led", 0), attrs=Attrs(IOSTANDARD="LVTTL")), + ] + + _audio = [ + Resource("audio", 0, + Subsignal("l", Pins("30", dir="o", conn=("gpio", 0))), + Subsignal("r", Pins("29", dir="o", conn=("gpio", 0))), + Attrs(IOSTANDARD="LVTTL") + ) + ] + + baseboard_sram = _buttons + _vga + _extclk + _ps2 + baseboard_no_sram = baseboard_sram + _switches + _sevenseg + _audio + + def toolchain_program(self, products, name): + # https://github.com/cr1901/mercpcl + mercpcl = os.environ.get("MERCPCL", "mercpcl") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([mercpcl, bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + plat = MercuryPlatform() + plat.add_resources(plat.leds) + plat.build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/microzed_z010.py b/re-bba/amaranth_boards/microzed_z010.py new file mode 100644 index 0000000..799720f --- /dev/null +++ b/re-bba/amaranth_boards/microzed_z010.py @@ -0,0 +1,116 @@ +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * + +__all__ = ["MicroZedZ010Platform"] + +class MicroZedZ010Platform(Xilinx7SeriesPlatform): + device = "xc7z010" + package = "clg400" + speed = "1" + resources = [] + connectors = [ + Connector("JX1", 0, + "F9 J6 " + "F6 G6 " + "- - " + "- R11 " + "R19 T19 " + "T11 T12 " + "T10 U12 " + "- - " + "U13 V12 " + "V13 W13 " + "- - " + "T14 P14 " + "T15 R14 " + "- - " + "Y16 Y17 " + "W14 Y14 " + "- - " + "T16 V15 " + "U17 W15 " + "- - " + "U14 U18 " + "U15 U19 " + "- - " + "N18 N20 " + "P19 P20 " + "- - " + "T20 V20 " + "U20 W20 " + "- - " + "- - " + "Y18 V16 " + "Y19 W16 " + "- - " + "R16 T17 " + "R17 R18 " + "- - " + "V17 W18 " + "V18 W19 " + "- - " + "- - " + "N17 P15 " + "P18 P16 " + "- - " + "- - " + "- - " + "- - " + "- - " + "- - " + "K9 M9 " + "L10 M10 " + ), + Connector("JX2", 0, + "E8 E9 " + "C6 D9 " + "E6 B5 " + "C5 C8 " + "R10 - " + "C7 - " + "G14 J15 " + "- - " + "C20 B19 " + "B20 A20 " + "- - " + "E17 D19 " + "D18 D20 " + "- - " + "E18 F16 " + "E19 F17 " + "- - " + "L19 M19 " + "L20 M20 " + "- - " + "M17 K19 " + "M18 J19 " + "- - " + "L16 K17 " + "L17 K18 " + "- - " + "H16 J18 " + "H17 H18 " + "- - " + "- - " + "G17 F19 " + "G18 F20 " + "- - " + "G19 J20 " + "G20 H20 " + "- - " + "K14 H15 " + "J14 G15 " + "- - " + "- - " + "N15 L14 " + "N16 L15 " + "- - " + "M14 K16 " + "M15 J16 " + "- - " + "- - " + "- - " + "- - " + "- - " + ), + ] diff --git a/re-bba/amaranth_boards/microzed_z020.py b/re-bba/amaranth_boards/microzed_z020.py new file mode 100644 index 0000000..87b763a --- /dev/null +++ b/re-bba/amaranth_boards/microzed_z020.py @@ -0,0 +1,116 @@ +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * + +__all__ = ["MicroZedZ020Platform"] + +class MicroZedZ020Platform(Xilinx7SeriesPlatform): + device = "xc7z020" + package = "clg400" + speed = "1" + resources = [] + connectors = [ + Connector("JX1", 0, + "F9 J6 " + "F6 G6 " + "- - " + "- R11 " + "R19 T19 " + "T11 T12 " + "T10 U12 " + "- - " + "U13 V12 " + "V13 W13 " + "- - " + "T14 P14 " + "T15 R14 " + "- - " + "Y16 Y17 " + "W14 Y14 " + "- - " + "T16 V15 " + "U17 W15 " + "- - " + "U14 U18 " + "U15 U19 " + "- - " + "N18 N20 " + "P19 P20 " + "- - " + "T20 V20 " + "U20 W20 " + "- - " + "- - " + "Y18 V16 " + "Y19 W16 " + "- - " + "R16 T17 " + "R17 R18 " + "- - " + "V17 W18 " + "V18 W19 " + "- - " + "- - " + "N17 P15 " + "P18 P16 " + "- - " + "U7 T9 " + "V7 U10 " + "V8 T5 " + "W8 U5 " + "- - " + "K9 M9 " + "L10 M10 " + ), + Connector("JX2", 0, + "E8 E9 " + "C6 D9 " + "E6 B5 " + "C5 C8 " + "R10 - " + "C7 - " + "G14 J15 " + "- - " + "C20 B19 " + "B20 A20 " + "- - " + "E17 D19 " + "D18 D20 " + "- - " + "E18 F16 " + "E19 F17 " + "- - " + "L19 M19 " + "L20 M20 " + "- - " + "M17 K19 " + "M18 J19 " + "- - " + "L16 K17 " + "L17 K18 " + "- - " + "H16 J18 " + "H17 H18 " + "- - " + "- - " + "G17 F19 " + "G18 F20 " + "- - " + "G19 J20 " + "G20 H20 " + "- - " + "K14 H15 " + "J14 G15 " + "- - " + "- - " + "N15 L14 " + "N16 L15 " + "- - " + "M14 K16 " + "M15 J16 " + "- - " + "Y12 V11 " + "Y13 V10 " + "V6 - " + "W6 V5 " + ), + ] diff --git a/re-bba/amaranth_boards/mister.py b/re-bba/amaranth_boards/mister.py new file mode 100644 index 0000000..d6217ff --- /dev/null +++ b/re-bba/amaranth_boards/mister.py @@ -0,0 +1,134 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["MisterPlatform"] + + +# The MiSTer platform is built around the DE10-Nano; if you update one you should update the other. +class MisterPlatform(IntelPlatform): + device = "5CSEBA6" # Cyclone V 110K LEs + package = "U23" # UBGA-484 + speed = "I7" + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("V11", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 1, Pins("Y13", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + Resource("clk50", 2, Pins("E11", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + + *LEDResources( + pins="W15 AA24 V16 V15 AF26 AE26 Y16 AA23", + attrs=Attrs(io_standard="3.3-V LVTTL")), + *ButtonResources( + pins="AH17 AH16", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + *SwitchResources( + pins="Y24 W24 W21 W20", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # Arduino header + UARTResource(0, + rx="AG13", tx="AF13", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # LTC2308 analogue-to-digital converter + SPIResource(0, + cs_n="U9", clk="V10", copi="AC4", cipo="AD4", + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # ADV7513 HDMI transmitter + # Note this has a lot of input formats for tx_d, but this defaults to RGB24 + Resource("adv7513", 0, + Subsignal("tx_d_r", Pins("AD12 AE12 W8 Y8 AD11 AD10 AE11 Y5", dir="o")), + Subsignal("tx_d_g", Pins("AF10 Y4 AE9 AB4 AE7 AF6 AF8 AF5", dir="o")), + Subsignal("tx_d_b", Pins("AE4 AH2 AH4 AH5 AH6 AG6 AF9 AE8", dir="o")), + Subsignal("tx_clk", Pins("AG5", dir="o")), + Subsignal("tx_de", Pins("AD19", dir="o")), + Subsignal("tx_hs", Pins("T8", dir="o")), + Subsignal("tx_vs", Pins("V13", dir="o")), + Subsignal("tx_int", Pins("AF11", dir="i")), + Subsignal("i2s0", Pins("T13", dir="o")), + Subsignal("mclk", Pins("U11", dir="o")), + Subsignal("lrclk", Pins("T11", dir="o")), + Subsignal("sclk", Pins("T12", dir="o")), + Subsignal("scl", Pins("U10", dir="o")), + Subsignal("sda", Pins("AA4", dir="io")), + Attrs(io_standard="3.3-V LVTTL")), + + # MiSTer SDRAM Board (required) + # https://github.com/MiSTer-devel/Hardware_MiSTer/blob/master/releases/sdram_xs_2.2.pdf + SDRAMResource(0, + clk="20", cs_n="33", we_n="27", ras_n="32", cas_n="31", + ba="34 35", a="37 38 39 40 28 25 26 23 24 21 36 22 19", + dq="1 2 3 4 5 6 7 8 18 17 16 15 14 13 9 10", + dqm="", conn=("gpio", 0), attrs=Attrs(io_standard="3.3-V LVCMOS")), + + # MiSTer I/O Board (optional, but highly recommended) + # https://github.com/MiSTer-devel/Hardware_MiSTer/blob/master/releases/iobrd_6.0.pdf + Resource("power_led", 0, PinsN("1", dir="o", conn=("gpio", 1)), Attrs(io_standard="3.3-V LVTTL")), + Resource("disk_led", 0, PinsN("3", dir="o", conn=("gpio", 1)), Attrs(io_standard="3.3-V LVTTL")), + Resource("user_led", 0, PinsN("5", dir="o", conn=("gpio", 1)), Attrs(io_standard="3.3-V LVTTL")), + + Resource("reset_switch", 0, PinsN("17", dir="i", conn=("gpio", 1)), Attrs(io_standard="3.3-V LVTTL")), + Resource("osd_switch", 0, PinsN("13", dir="i", conn=("gpio", 1)), Attrs(io_standard="3.3-V LVTTL")), + Resource("user_switch", 0, PinsN("15", dir="i", conn=("gpio", 1)), Attrs(io_standard="3.3-V LVTTL")), + + Resource("audio", 0, + Subsignal("l", Pins("2", dir="o", conn=("gpio", 1))), + Subsignal("r", Pins("7", dir="o", conn=("gpio", 1))), + Attrs(io_standard="3.3-V LVTTL")), + + Resource("toslink", 0, Pins("9", dir="o", conn=("gpio", 1))), + + *SDCardResources(0, + clk="13", cmd="8", + dat0="16", dat1="18", dat2="4", dat3="6", + conn=("gpio", 1), attrs=Attrs(io_standard="3.3-V LVTTL")), + + # The schematic is difficult to understand here... + VGAResource(0, + r="28 32 34 36 38 40", + g="27 31 33 35 37 39", + b="21 23 25 26 24 24", + hs="20", vs="19", + conn=("gpio", 1), + attrs=Attrs(io_standard="3.3-V LVTTL")) + ] + connectors = [ + # Located on the top of the board, above the chip. + Connector("gpio", 0, + "V12 E8 W12 D11 D8 AH13 AF7 AH14 AF4 AH3 " + "- - AD5 AG14 AE23 AE6 AD23 AE24 D12 AD20 " + "C12 AD17 AC23 AC22 Y19 AB23 AA19 W11 - - " + "AA18 W14 Y18 Y17 AB25 AB26 Y11 AA26 AA13 AA11 "), + # Located on the bottom of the board. + Connector("gpio", 1, + "Y15 AC24 AA15 AD26 AG28 AF28 AE25 AF27 AG26 AH27 " + "- - AG25 AH26 AH24 AF25 AG23 AF23 AG24 AH22 " + "AH21 AG21 AH23 AA20 AF22 AE22 AG20 AF21 - - " + "AG19 AH19 AG18 AH18 AF18 AF20 AG15 AE20 AE19 AE17 "), + Connector("arduino", 0, + "AG13 AF13 AG10 AG9 U14 U13 AG8 AH8 " + "AF17 AE15 AF15 AG16 AH11 AH12 AH9 AG11 " + "AH7"), + ] + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + # The @2 selects the second device in the JTAG chain, because this chip + # puts the ARM cores first. + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename + "@2"]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + MisterPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/nandland_go.py b/re-bba/amaranth_boards/nandland_go.py new file mode 100644 index 0000000..d5c970a --- /dev/null +++ b/re-bba/amaranth_boards/nandland_go.py @@ -0,0 +1,50 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["NandlandGoPlatform"] + + +class NandlandGoPlatform(LatticeICE40Platform): + device = "iCE40HX1K" + package = "VQ100" + default_clk = "clk25" + resources = [ + Resource("clk25", 0, Pins("15", dir="i"), + Clock(25e6)), + + *LEDResources(pins="56 57 59 60"), + *ButtonResources(pins="53 51 54 52"), + + Display7SegResource(0, + a="3", b="4", c="93", d="91", e="90", f="1", g="2", invert=True), + Display7SegResource(1, + a="100", b="99", c="97", d="95", e="94", f="8", g="96", invert=True), + + UARTResource(0, rx="73", tx="74"), + + *SPIFlashResources(0, cs_n="49", clk="48", copi="45", cipo="46"), + + VGAResource(0, + r="36 37 40", + g="29 30 33", + b="28 41 42", + hs="26", vs="27"), + ] + connectors = [ + Connector("pmod", 0, "65 64 63 62 - - 78 79 80 81 - -"), + ] + + def toolchain_program(self, products, name): + iceprog = os.environ.get("ICEPROG", "iceprog") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([iceprog, bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + NandlandGoPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/nexys4ddr.py b/re-bba/amaranth_boards/nexys4ddr.py new file mode 100644 index 0000000..b4e6a79 --- /dev/null +++ b/re-bba/amaranth_boards/nexys4ddr.py @@ -0,0 +1,183 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["Nexys4DDRPlatform"] + + +class Nexys4DDRPlatform(Xilinx7SeriesPlatform): + device = "xc7a100t" + package = "csg324" + speed = "1" + default_clk = "clk100" + default_rst = "rst" + resources = [ + Resource("clk100", 0, + Pins("E3", dir="i"), Clock(100e6), Attrs(IOSTANDARD="LVCMOS33")), + Resource("rst", 0, + PinsN("C12", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + + *SwitchResources( + pins={0: 'J15', 1: 'L16', 2: 'M13', 3: 'R15', 4: 'R17', 5: 'T18', + 6: 'U18', 7: 'R13', 10: 'R16', 11: 'T13', 12: 'H6', + 13: 'U12', 14: 'U11', 15: 'V10'}, + attrs=Attrs(IOSTANDARD="LVCMOS33")), + *SwitchResources( + pins={8: 'T8', 9: 'U8'}, + attrs=Attrs(IOSTANDARD="LVCMOS18")), + + *LEDResources( + pins="H17 K15 J13 N14 R18 V17 U17 U16 V16 T15 U14 T16 V15 V14 V12 V11", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + RGBLEDResource(0, + r="N15", g="M16", b="R12", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + RGBLEDResource(1, + r="N16", g="R11", b="G14", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + Display7SegResource(0, + a="T10", b="R10", c="K16", d="K13", e="P15", + f="T11", g="L18", dp="H15", invert=True, + attrs=Attrs(IOSTANDARD="LVCMOS33")), + Resource("display_7seg_an", 0, + PinsN("J17 J18 T9 J14 P14 T14 K2 U13", dir="o"), + Attrs(IOSTANDARD="LVCMOS33")), + + Resource("button_reset", 0, + PinsN("C12", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + Resource("button_center", 0, + Pins("N17", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + Resource("button_up", 0, + Pins("M18", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + Resource("button_left", 0, + Pins("P17", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + Resource("button_right", 0, + Pins("M17", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + Resource("button_down", 0, + Pins("P18", dir="i"), Attrs(IOSTANDARD="LVCMOS33")), + + VGAResource(0, + r="A3 B4 C5 A4", + g="C6 A5 B6 A6", + b="B7 C7 D7 D8", + hs="B11", vs="B12", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + *SDCardResources(0, + clk="B1", cmd="C1", cd="A1", + dat0="C2", dat1="E1", dat2="F1", dat3="D2", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + Resource("sd_card_reset", 0, + Pins("E2", dir="o"), Attrs(IOSTANDARD="LVCMOS33")), + + Resource("accelerometer", 0, # ADXL362 + Subsignal("cs", PinsN("D15", dir="o")), + Subsignal("clk", Pins("F15", dir="o")), + Subsignal("copi", Pins("F14", dir="o")), + Subsignal("cipo", Pins("E15", dir="i")), + Subsignal("int", Pins("B13 C16", dir="i"), + Attrs(IOSTANDARD="LVCMOS33", PULLUP="TRUE")), + Attrs(IOSTANDARD="LVCMOS33")), + + Resource("temp_sensor", 0, # ADT7420 + Subsignal("scl", Pins("C14", dir="o")), + Subsignal("sda", Pins("C15", dir="io")), + Subsignal("int", Pins("D13", dir="i"), Attrs(PULLUP="TRUE")), + Subsignal("ct", Pins("B14", dir="i"), Attrs(PULLUP="TRUE")), + Attrs(IOSTANDARD="LVCMOS33")), + + Resource("microphone", 0, # ADMP421 + Subsignal("clk", Pins("J5", dir="o")), + Subsignal("data", Pins("H5", dir="i")), + Subsignal("lr_sel", Pins("F5", dir="o")), + Attrs(IOSTANDARD="LVCMOS33")), + + Resource("audio", 0, + Subsignal("pwm", Pins("A11", dir="o")), + Subsignal("sd", PinsN("D12", dir="o")), + Attrs(IOSTANDARD="LVCMOS33")), + + UARTResource(0, + rx="C4", tx="D4", rts="E5", cts="D3", + attrs=Attrs(IOSTANDARD="LVCMOS33"), + role="dce"), + + PS2Resource(0, + clk="F4", dat="B2", + attrs=Attrs(IOSTANDARD="LVCMOS33", PULLUP="TRUE")), + + Resource("eth", 0, # LAN8720A + Subsignal("mdio", Pins("A9", dir="io")), + Subsignal("mdc", Pins("C9", dir="o")), + Subsignal("reset", Pins("B3", dir="o")), + Subsignal("rxd", Pins("C11 D10", dir="io")), + Subsignal("rxerr", Pins("C10", dir="io")), + Subsignal("txd", Pins("A10 A8", dir="o")), + Subsignal("txen", Pins("B9", dir="o")), + Subsignal("crs_dv", Pins("D9", dir="io")), + Subsignal("int", PinsN("B8", dir="io")), + Subsignal("clk", Pins("D5", dir="o"), Clock(50e6)), + Attrs(IOSTANDARD="LVCMOS33")), + + *SPIFlashResources(0, + cs_n="L13", clk="E9", copi="K17", cipo="K18", wp_n="L14", hold_n="M14", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + + Resource("ddr2", 0, # MT47H64M16HR-25:H + Subsignal("a", + Pins("M4 P4 M6 T1 L3 P5 M2 N1 L4 N5 R2 K5 N6 K3", dir="o")), + Subsignal("dq", + Pins("R7 V6 R8 U7 V7 R6 U6 R5 T5 U3 V5 U4 V4 T4 V1 T3", dir="io"), + Attrs(IN_TERM="UNTUNED_SPLIT_50")), + Subsignal("ba", Pins("P2 P3 R1", dir="o")), + Subsignal("clk", DiffPairs("L6", "L5", dir="o"), + Attrs(IOSTANDARD="DIFF_SSTL18_I")), + Subsignal("clk_en", Pins("M1", dir="o")), + Subsignal("cs", PinsN("K6", dir="o")), + Subsignal("we", PinsN("N2", dir="o")), + Subsignal("ras", PinsN("N4", dir="o")), + Subsignal("cas", PinsN("L1", dir="o")), + Subsignal("dqs", DiffPairs("U9 U2", "V9 V2", dir="o"), + Attrs(IOSTANDARD="DIFF_SSTL18_I")), + Subsignal("dm", Pins("T6 U1", dir="o")), + Subsignal("odt", Pins("R5", dir="o")), + Attrs(IOSTANDARD="SSTL18_I", SLEW="FAST")) + ] + connectors = [ + Connector("pmod", 0, "C17 D18 E18 G17 - - D17 E17 F18 G18 - -"), # JA + Connector("pmod", 1, "D14 F16 G16 H14 - - E16 F13 G13 H16 - -"), # JB + Connector("pmod", 2, "K1 F6 J2 G6 - - E7 J3 J4 E6 - -"), # JC + Connector("pmod", 3, "H4 H1 G1 G3 - - H2 G4 G2 F3 - -") # JD + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = { + "script_before_bitstream": + "set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]", + "script_after_bitstream": + "write_cfgmem -force -format bin -interface spix4 -size 16 " + "-loadbit \"up 0x0 {name}.bit\" -file {name}.bin".format(name=name), + "add_constraints": + """ + set_property INTERNAL_VREF 0.9 [get_iobanks 34] + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + """ + } + return super().toolchain_prepare(fragment, name, **overrides, **kwargs) + + def toolchain_program(self, products, name): + xc3sprog = os.environ.get("XC3SPROG", "xc3sprog") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.run([xc3sprog, "-c", "nexys4", bitstream_filename], check=True) + + +if __name__ == "__main__": + from .test.blinky import * + Nexys4DDRPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/numato_mimas.py b/re-bba/amaranth_boards/numato_mimas.py new file mode 100644 index 0000000..a3f8930 --- /dev/null +++ b/re-bba/amaranth_boards/numato_mimas.py @@ -0,0 +1,51 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_spartan_3_6 import * +from .resources import * + + +__all__ = ["NumatoMimasPlatform"] + + +class NumatoMimasPlatform(XilinxSpartan6Platform): + device = "xc6slx9" + package = "tqg144" + speed = "2" + default_clk = "clk100" + resources = [ + Resource("clk100", 0, Pins("P126", dir="i"), + Clock(100e6), Attrs(IOSTANDARD="LVCMOS33")), + + *LEDResources(pins="P119 P118 P117 P116 P115 P114 P112 P111", + attrs=Attrs(IOSTANDARD="LVCMOS33")), + *ButtonResources(pins="P124 P123 P121 P120", + attrs=Attrs(IOSTANDARD="LVCMOS33", PULLUP="TRUE")), + + *SPIFlashResources(0, + cs_n="P38", clk="P70", copi="P64", cipo="65", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + ] + connectors = [ + Connector("p", 1, + "- - P35 P34 P33 P32 P30 P29 P27 P26 " + "P24 P23 P22 P21 P17 P16 P15 P14 P12 P11 " + "P10 P9 P8 P7 P6 P5 P2 P1 P142 P141 " + "P140 P139 P138 P137 P134 P133 P132 P131 - - " + ), + Connector("p", 2, + "- - P43 P44 P45 P46 P47 P48 P50 P51 " + "P55 P56 P74 P75 P78 P79 P80 P81 - - " + "P82 P83 P84 P85 P87 P88 P92 P93 P94 P95 " + "P97 P98 P99 P100 P101 P102 P104 P105 - - " + ) + ] + + # Programming this board is not currently supported. + + +if __name__ == "__main__": + from .test.blinky import * + NumatoMimasPlatform().build(Blinky()) diff --git a/re-bba/amaranth_boards/orangecrab_r0_1.py b/re-bba/amaranth_boards/orangecrab_r0_1.py new file mode 100644 index 0000000..2316461 --- /dev/null +++ b/re-bba/amaranth_boards/orangecrab_r0_1.py @@ -0,0 +1,122 @@ +import os +import subprocess +import shutil + +from amaranth.build import * +from amaranth.vendor.lattice_ecp5 import * +from .resources import * + + +__all__ = ["OrangeCrabR0_1Platform"] + + +class OrangeCrabR0_1Platform(LatticeECP5Platform): + device = "LFE5U-25F" + package = "MG285" + speed = "8" + default_clk = "clk" + resources = [ + Resource("clk", 0, Pins("A9", dir="i"), + Clock(48e6), Attrs(IO_TYPE="LVCMOS33")), + + # Used to reload FPGA configuration. + # Can enter USB bootloader by assigning button 0 to program. + Resource("program", 0, PinsN("R16", dir="o"), Attrs(IO_TYPE="LVCMOS33")), + + RGBLEDResource(0, + r="V17", g="T17", b="J3", invert=True, + attrs=Attrs(IO_TYPE="LVCMOS33")), + + *SPIFlashResources(0, + cs_n="U17", clk="U16", cipo="T18", copi="U18", wp_n="R18", hold_n="N18", + attrs=Attrs(IO_TYPE="LVCMOS33"), + ), + + Resource("ddr3", 0, + Subsignal("rst", PinsN("B1", dir="o")), + Subsignal("clk", DiffPairs("J18", "K18", dir="o"), Attrs(IO_TYPE="SSTL135D_I")), + Subsignal("clk_en", Pins("D6", dir="o")), + Subsignal("cs", PinsN("A12", dir="o")), + Subsignal("we", PinsN("B12", dir="o")), + Subsignal("ras", PinsN("C12", dir="o")), + Subsignal("cas", PinsN("D13", dir="o")), + Subsignal("a", Pins("A4 D2 C3 C7 D3 D4 D1 B2 C1 A2 A7 C2 C4", dir="o")), + Subsignal("ba", Pins("B6 B7 A6", dir="o")), + Subsignal("dqs", DiffPairs("G18 H17", "B15 A16", dir="io"), + Attrs(IO_TYPE="SSTL135D_I", TERMINATION="OFF", + DIFFRESISTOR="100")), + Subsignal("dq", Pins("F17 F16 G15 F15 J16 C18 H16 F18 C17 D15 B17 C16 A15 B13 A17 A13", dir="io"), + Attrs(TERMINATION="75")), + Subsignal("dm", Pins("G16 D16", dir="o")), + Subsignal("odt", Pins("C13", dir="o")), + Attrs(IO_TYPE="SSTL135_I", SLEWRATE="FAST") + ), + + Resource("ddr3_pseudo_power", 0, + # pseudo power pins, leave these at their default value + Subsignal("vcc_virtual", PinsN("A3 B18 C6 C15 D17 D18 K15 K16 K17", dir="o")), + Subsignal("gnd_virtual", Pins("L15 L16 L18", dir="o")), + Attrs(IO_TYPE="SSTL135_II", SLEWRATE="FAST") + ), + + *SDCardResources(0, + dat0="J1", dat1="K3", dat2="L3", dat3="M1", clk="K1", cmd="K2", cd="L1", + attrs=Attrs(IO_TYPE="LVCMOS33", SLEWRATE="FAST") + ), + + DirectUSBResource(0, d_p="N1", d_n="M2", pullup="N2", attrs=Attrs(IO_TYPE="LVCMOS33")) + ] + connectors = [ + Connector("io", 0, { + "0": "N17", + "1": "M18", + "5": "B10", + "6": "B9", + "9": "C8", + "10": "B8", + "11": "A8", + "12": "H2", + "13": "J2", + "cipo": "N15", + "copi": "N16", + "sck": "R17", + "scl": "C9", + "sda": "C10" + }), + Connector("mcu", 0, { + "0": "A10", + "1": "C11", + "2": "A11", + "3": "B11", + }), + ] + + @property + def required_tools(self): + return super().required_tools + [ + "dfu-suffix" + ] + + @property + def command_templates(self): + return super().command_templates + [ + r""" + {{invoke_tool("dfu-suffix")}} + -v 1209 -p 5af0 -a {{name}}.bit + """ + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = dict(ecppack_opts="--compress --freq 38.8") + overrides.update(kwargs) + return super().toolchain_prepare(fragment, name, **overrides) + + def toolchain_program(self, products, name): + dfu_util = os.environ.get("DFU_UTIL", "dfu-util") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.check_call([dfu_util, "-D", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + OrangeCrabR0_1Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/orangecrab_r0_2.py b/re-bba/amaranth_boards/orangecrab_r0_2.py new file mode 100644 index 0000000..75bac4a --- /dev/null +++ b/re-bba/amaranth_boards/orangecrab_r0_2.py @@ -0,0 +1,132 @@ +import os +import subprocess +import shutil + +from amaranth.build import * +from amaranth.vendor.lattice_ecp5 import * +from .resources import * + + +__all__ = ["OrangeCrabR0_2Platform"] + + +class OrangeCrabR0_2Platform(LatticeECP5Platform): + device = "LFE5U-25F" + package = "MG285" + speed = "8" + default_clk = "clk" + resources = [ + Resource("clk", 0, Pins("A9", dir="i"), + Clock(48e6), Attrs(IO_TYPE="LVCMOS33")), + + # Used to reload FPGA configuration. + # Can enter USB bootloader by assigning button 0 to program. + Resource("program", 0, PinsN("V17", dir="o"), Attrs(IO_TYPE="LVCMOS33")), + + RGBLEDResource(0, + r="K4", g="M3", b="J3", invert=True, + attrs=Attrs(IO_TYPE="LVCMOS33")), + + *ButtonResources( + pins={0: "J17" }, invert=True, + attrs=Attrs(IO_TYPE="SSTL135_I")), + + *SPIFlashResources(0, + cs_n="U17", clk="U16", cipo="T18", copi="U18", wp_n="R18", hold_n="N18", + attrs=Attrs(IO_TYPE="LVCMOS33"), + ), + + Resource("ddr3", 0, + Subsignal("rst", PinsN("L18", dir="o")), + Subsignal("clk", DiffPairs("J18", "K18", dir="o"), Attrs(IO_TYPE="SSTL135D_I")), + Subsignal("clk_en", Pins("D18", dir="o")), + Subsignal("cs", PinsN("A12", dir="o")), + Subsignal("we", PinsN("B12", dir="o")), + Subsignal("ras", PinsN("C12", dir="o")), + Subsignal("cas", PinsN("D13", dir="o")), + Subsignal("a", Pins("C4 D2 D3 A3 A4 D4 C3 B2 B1 D1 A7 C2 B6 C1 A2 C7", dir="o")), + Subsignal("ba", Pins("P5 N3 M3", dir="o")), + Subsignal("dqs", DiffPairs("G18 H17", "B15 A16", dir="io"), + Attrs(IO_TYPE="SSTL135D_I", TERMINATION="OFF", + DIFFRESISTOR="100")), + Subsignal("dq", Pins("C17 D15 B17 C16 A15 B13 A17 A13 F17 F16 G15 F15 J16 C18 H16 F18", + dir="io"), Attrs(TERMINATION="75")), + Subsignal("dm", Pins("G16 D16", dir="o")), + Subsignal("odt", Pins("C13", dir="o")), + Attrs(IO_TYPE="SSTL135_I", SLEWRATE="FAST") + ), + + Resource("ddr3_pseudo_power", 0, + # pseudo power pins, leave these at their default value + Subsignal("vcc_virtual", PinsN("K16 D17 K15 K17 B18 C6", dir="o")), + Subsignal("gnd_virtual", Pins("L15 L16", dir="o")), + Attrs(IO_TYPE="SSTL135_II", SLEWRATE="FAST") + ), + + Resource("adc", 0, + Subsignal("ctrl", Pins("G1 F1", dir="o")), + Subsignal("mux", Pins("F4 F3 F2 H1", dir="o")), + Subsignal("sense", DiffPairs("H3", "G3", dir="i"), Attrs(IO_TYPE="LVCMOS33D")), + Attrs(IO_TYPE="LVCMOS33") + ), + + *SDCardResources(0, + dat0="J1", dat1="K3", dat2="L3", dat3="M1", clk="K1", cmd="K2", cd="L1", + attrs=Attrs(IO_TYPE="LVCMOS33", SLEWRATE="FAST") + ), + + DirectUSBResource(0, d_p="N1", d_n="M2", pullup="N2", attrs=Attrs(IO_TYPE="LVCMOS33")) + ] + connectors = [ + Connector("io", 0, { + "0": "N17", + "1": "M18", + "5": "B10", + "6": "B9", + "9": "C8", + "10": "B8", + "11": "A8", + "12": "H2", + "13": "J2", + "a0": "L4", + "a1": "N3", + "a2": "N4", + "a3": "H4", + "a4": "G4", + "cipo": "N15", + "copi": "N16", + "sck": "R17", + "scl": "C9", + "sda": "C10" + }) + ] + + @property + def required_tools(self): + return super().required_tools + [ + "dfu-suffix" + ] + + @property + def command_templates(self): + return super().command_templates + [ + r""" + {{invoke_tool("dfu-suffix")}} + -v 1209 -p 5af0 -a {{name}}.bit + """ + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = dict(ecppack_opts="--compress --freq 38.8") + overrides.update(kwargs) + return super().toolchain_prepare(fragment, name, **overrides) + + def toolchain_program(self, products, name): + dfu_util = os.environ.get("DFU_UTIL", "dfu-util") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.check_call([dfu_util, "-D", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + OrangeCrabR0_2Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/quickfeather.py b/re-bba/amaranth_boards/quickfeather.py new file mode 100644 index 0000000..26ef4dd --- /dev/null +++ b/re-bba/amaranth_boards/quickfeather.py @@ -0,0 +1,82 @@ +import os +import sys +import subprocess + +from amaranth.build import * +from amaranth.vendor.quicklogic import * +from amaranth_boards.resources import * + + +__all__ = ["QuickfeatherPlatform"] + + +class QuickfeatherPlatform(QuicklogicPlatform): + device = "ql-eos-s3_wlcsp" + package = "PU64" + default_clk = "sys_clk0" + # It is possible to configure both oscillator frequency and + # clock divider. Resulting frequency is: 60MHz / 12 = 5MHz + osc_freq = int(60e6) + osc_div = 12 + connectors = [ + Connector("J", 2, "- 28 22 21 37 36 42 40 7 2 4 5"), + Connector("J", 3, "- 8 9 17 16 20 6 55 31 25 47 - - - - 41"), + Connector("J", 8, "27 26 33 32 23 57 56 3 64 62 63 61 59 - - -"), + ] + resources = [ + *ButtonResources(pins="62"), + + RGBLEDResource(0, r="34", g="39", b="38"), + + UARTResource(0, + rx="9", tx="8", + ), + + SPIResource(0, + cs_n="11", clk="20", copi="16", cipo="17" + ), + SPIResource(1, + cs_n="37", clk="40", copi="36", cipo="42", + role="peripheral" + ), + + I2CResource(0, + scl="4", sda="5" + ), + I2CResource(1, + scl="22", sda="21" + ), + + DirectUSBResource(0, d_p="10", d_n="14"), + + Resource("swd", 0, + Subsignal("clk", Pins("54", dir="io")), + Subsignal("io", Pins("53", dir="io")), + ), + ] + + # This programmer requires OpenOCD with support for eos-s3: + # https://github.com/antmicro/openocd/tree/eos-s3-support + def toolchain_program(self, products, name): + openocd = os.environ.get("OPENOCD", "openocd") + with products.extract("{}.openocd".format(name), + "{}_iomux.openocd".format(name)) as \ + (bitstream_openocd_filename, iomux_openocd_filename): + subprocess.check_call([ + openocd, + "-s", "tcl", + "-f", "interface/ftdi/antmicro-ftdi-adapter.cfg", + "-f", "interface/ftdi/swd-resistor-hack.cfg", + "-f", "board/quicklogic_quickfeather.cfg", + "-f", bitstream_openocd_filename, + "-c", "init", + "-c", "reset halt", + "-c", "load_bitstream", + "-f", iomux_openocd_filename, + "-c", "exit" + ]) + + +if __name__ == "__main__": + from .test.blinky import * + QuickfeatherPlatform().build(Blinky()) diff --git a/re-bba/amaranth_boards/resources/__init__.py b/re-bba/amaranth_boards/resources/__init__.py new file mode 100644 index 0000000..531eb5e --- /dev/null +++ b/re-bba/amaranth_boards/resources/__init__.py @@ -0,0 +1,4 @@ +from .display import * +from .interface import * +from .memory import * +from .user import * diff --git a/re-bba/amaranth_boards/resources/__pycache__/__init__.cpython-310.pyc b/re-bba/amaranth_boards/resources/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..9ad9bb9 Binary files /dev/null and b/re-bba/amaranth_boards/resources/__pycache__/__init__.cpython-310.pyc differ diff --git a/re-bba/amaranth_boards/resources/__pycache__/display.cpython-310.pyc b/re-bba/amaranth_boards/resources/__pycache__/display.cpython-310.pyc new file mode 100644 index 0000000..7c88b6b Binary files /dev/null and b/re-bba/amaranth_boards/resources/__pycache__/display.cpython-310.pyc differ diff --git a/re-bba/amaranth_boards/resources/__pycache__/interface.cpython-310.pyc b/re-bba/amaranth_boards/resources/__pycache__/interface.cpython-310.pyc new file mode 100644 index 0000000..98d2942 Binary files /dev/null and b/re-bba/amaranth_boards/resources/__pycache__/interface.cpython-310.pyc differ diff --git a/re-bba/amaranth_boards/resources/__pycache__/memory.cpython-310.pyc b/re-bba/amaranth_boards/resources/__pycache__/memory.cpython-310.pyc new file mode 100644 index 0000000..0804a39 Binary files /dev/null and b/re-bba/amaranth_boards/resources/__pycache__/memory.cpython-310.pyc differ diff --git a/re-bba/amaranth_boards/resources/__pycache__/user.cpython-310.pyc b/re-bba/amaranth_boards/resources/__pycache__/user.cpython-310.pyc new file mode 100644 index 0000000..8676eda Binary files /dev/null and b/re-bba/amaranth_boards/resources/__pycache__/user.cpython-310.pyc differ diff --git a/re-bba/amaranth_boards/resources/display.py b/re-bba/amaranth_boards/resources/display.py new file mode 100644 index 0000000..cf245e8 --- /dev/null +++ b/re-bba/amaranth_boards/resources/display.py @@ -0,0 +1,36 @@ +from amaranth.build import * + + +__all__ = ["Display7SegResource", "VGAResource"] + + +def Display7SegResource(*args, a, b, c, d, e, f, g, dp=None, invert=False, + conn=None, attrs=None): + ios = [] + ios.append(Subsignal("a", Pins(a, dir="o", invert=invert, conn=conn, assert_width=1))) + ios.append(Subsignal("b", Pins(b, dir="o", invert=invert, conn=conn, assert_width=1))) + ios.append(Subsignal("c", Pins(c, dir="o", invert=invert, conn=conn, assert_width=1))) + ios.append(Subsignal("d", Pins(d, dir="o", invert=invert, conn=conn, assert_width=1))) + ios.append(Subsignal("e", Pins(e, dir="o", invert=invert, conn=conn, assert_width=1))) + ios.append(Subsignal("f", Pins(f, dir="o", invert=invert, conn=conn, assert_width=1))) + ios.append(Subsignal("g", Pins(g, dir="o", invert=invert, conn=conn, assert_width=1))) + if dp is not None: + ios.append(Subsignal("dp", Pins(dp, dir="o", invert=invert, conn=conn, assert_width=1))) + if attrs is not None: + ios.append(attrs) + return Resource.family(*args, default_name="display_7seg", ios=ios) + + +def VGAResource(*args, r, g, b, vs, hs, invert_sync=False, conn=None, attrs=None): + ios = [] + + ios.append(Subsignal("r", Pins(r, dir="o", conn=conn))) + ios.append(Subsignal("g", Pins(g, dir="o", conn=conn))) + ios.append(Subsignal("b", Pins(b, dir="o", conn=conn))) + ios.append(Subsignal("hs", Pins(hs, dir="o", invert=invert_sync, conn=conn, assert_width=1))) + ios.append(Subsignal("vs", Pins(vs, dir="o", invert=invert_sync, conn=conn, assert_width=1))) + + if attrs is not None: + ios.append(attrs) + + return Resource.family(*args, default_name="vga", ios=ios) diff --git a/re-bba/amaranth_boards/resources/interface.py b/re-bba/amaranth_boards/resources/interface.py new file mode 100644 index 0000000..8941be1 --- /dev/null +++ b/re-bba/amaranth_boards/resources/interface.py @@ -0,0 +1,144 @@ +from amaranth.build import * + + +__all__ = [ + "UARTResource", "IrDAResource", "SPIResource", "I2CResource", + "DirectUSBResource", "ULPIResource", "PS2Resource", +] + + +def UARTResource(*args, rx, tx, rts=None, cts=None, dtr=None, dsr=None, dcd=None, ri=None, + conn=None, attrs=None, role=None): + if any(line is not None for line in (rts, cts, dtr, dsr, dcd, ri)): + assert role in ("dce", "dte") + if role == "dte": + dce_to_dte = "i" + dte_to_dce = "o" + else: + dce_to_dte = "o" + dte_to_dce = "i" + + io = [] + io.append(Subsignal("rx", Pins(rx, dir="i", conn=conn, assert_width=1))) + io.append(Subsignal("tx", Pins(tx, dir="o", conn=conn, assert_width=1))) + if rts is not None: + io.append(Subsignal("rts", Pins(rts, dir=dte_to_dce, conn=conn, assert_width=1))) + if cts is not None: + io.append(Subsignal("cts", Pins(cts, dir=dce_to_dte, conn=conn, assert_width=1))) + if dtr is not None: + io.append(Subsignal("dtr", Pins(dtr, dir=dte_to_dce, conn=conn, assert_width=1))) + if dsr is not None: + io.append(Subsignal("dsr", Pins(dsr, dir=dce_to_dte, conn=conn, assert_width=1))) + if dcd is not None: + io.append(Subsignal("dcd", Pins(dcd, dir=dce_to_dte, conn=conn, assert_width=1))) + if ri is not None: + io.append(Subsignal("ri", Pins(ri, dir=dce_to_dte, conn=conn, assert_width=1))) + if attrs is not None: + io.append(attrs) + return Resource.family(*args, default_name="uart", ios=io) + + +def IrDAResource(number, *, rx, tx, en=None, sd=None, + conn=None, attrs=None): + # Exactly one of en (active-high enable) or sd (shutdown, active-low enable) should + # be specified, and it is mapped to a logic level en subsignal. + assert (en is not None) ^ (sd is not None) + + io = [] + io.append(Subsignal("rx", Pins(rx, dir="i", conn=conn, assert_width=1))) + io.append(Subsignal("tx", Pins(tx, dir="o", conn=conn, assert_width=1))) + if en is not None: + io.append(Subsignal("en", Pins(en, dir="o", conn=conn, assert_width=1))) + if sd is not None: + io.append(Subsignal("en", PinsN(sd, dir="o", conn=conn, assert_width=1))) + if attrs is not None: + io.append(attrs) + return Resource("irda", number, *io) + + +def SPIResource(*args, cs_n, clk, copi, cipo, int=None, reset=None, + conn=None, attrs=None, role="controller"): + assert role in ("controller", "peripheral") + assert copi is not None or cipo is not None # support unidirectional SPI + + io = [] + if role == "controller": + io.append(Subsignal("cs", PinsN(cs_n, dir="o", conn=conn))) + io.append(Subsignal("clk", Pins(clk, dir="o", conn=conn, assert_width=1))) + if copi is not None: + io.append(Subsignal("copi", Pins(copi, dir="o", conn=conn, assert_width=1))) + if cipo is not None: + io.append(Subsignal("cipo", Pins(cipo, dir="i", conn=conn, assert_width=1))) + else: # peripheral + io.append(Subsignal("cs", PinsN(cs_n, dir="i", conn=conn, assert_width=1))) + io.append(Subsignal("clk", Pins(clk, dir="i", conn=conn, assert_width=1))) + if copi is not None: + io.append(Subsignal("copi", Pins(copi, dir="i", conn=conn, assert_width=1))) + if cipo is not None: + io.append(Subsignal("cipo", Pins(cipo, dir="oe", conn=conn, assert_width=1))) + if int is not None: + if role == "controller": + io.append(Subsignal("int", Pins(int, dir="i", conn=conn))) + else: + io.append(Subsignal("int", Pins(int, dir="oe", conn=conn, assert_width=1))) + if reset is not None: + if role == "controller": + io.append(Subsignal("reset", Pins(reset, dir="o", conn=conn))) + else: + io.append(Subsignal("reset", Pins(reset, dir="i", conn=conn, assert_width=1))) + if attrs is not None: + io.append(attrs) + return Resource.family(*args, default_name="spi", ios=io) + + +def I2CResource(*args, scl, sda, conn=None, attrs=None): + io = [] + io.append(Subsignal("scl", Pins(scl, dir="io", conn=conn, assert_width=1))) + io.append(Subsignal("sda", Pins(sda, dir="io", conn=conn, assert_width=1))) + if attrs is not None: + io.append(attrs) + return Resource.family(*args, default_name="i2c", ios=io) + + +def DirectUSBResource(*args, d_p, d_n, pullup=None, vbus_valid=None, conn=None, attrs=None): + + io = [] + io.append(Subsignal("d_p", Pins(d_p, dir="io", conn=conn, assert_width=1))) + io.append(Subsignal("d_n", Pins(d_n, dir="io", conn=conn, assert_width=1))) + if pullup: + io.append(Subsignal("pullup", Pins(pullup, dir="o", conn=conn, assert_width=1))) + if vbus_valid: + io.append(Subsignal("vbus_valid", Pins(vbus_valid, dir="i", conn=conn, assert_width=1))) + if attrs is not None: + io.append(attrs) + return Resource.family(*args, default_name="usb", ios=io) + + +def ULPIResource(*args, data, clk, dir, nxt, stp, rst=None, + clk_dir='i', rst_invert=False, attrs=None, conn=None): + assert clk_dir in ('i', 'o',) + + io = [] + io.append(Subsignal("data", Pins(data, dir="io", conn=conn, assert_width=8))) + io.append(Subsignal("clk", Pins(clk, dir=clk_dir, conn=conn, assert_width=1))) + io.append(Subsignal("dir", Pins(dir, dir="i", conn=conn, assert_width=1))) + io.append(Subsignal("nxt", Pins(nxt, dir="i", conn=conn, assert_width=1))) + io.append(Subsignal("stp", Pins(stp, dir="o", conn=conn, assert_width=1))) + if rst is not None: + io.append(Subsignal("rst", Pins(rst, dir="o", invert=rst_invert, + conn=conn, assert_width=1))) + if attrs is not None: + io.append(attrs) + return Resource.family(*args, default_name="usb", ios=io) + + +def PS2Resource(*args, clk, dat, conn=None, attrs=None): + ios = [] + + ios.append(Subsignal("clk", Pins(clk, dir="i", conn=conn, assert_width=1))), + ios.append(Subsignal("dat", Pins(dat, dir="io", conn=conn, assert_width=1))), + + if attrs is not None: + ios.append(attrs) + + return Resource.family(*args, default_name="ps2", ios=ios) diff --git a/re-bba/amaranth_boards/resources/memory.py b/re-bba/amaranth_boards/resources/memory.py new file mode 100644 index 0000000..65eb5d5 --- /dev/null +++ b/re-bba/amaranth_boards/resources/memory.py @@ -0,0 +1,190 @@ +from amaranth.build import * + + +__all__ = [ + "SPIFlashResources", "SDCardResources", + "SRAMResource", "SDRAMResource", "NORFlashResources", + "DDR3Resource", +] + + +def SPIFlashResources(*args, cs_n, clk, copi, cipo, wp_n=None, hold_n=None, + conn=None, attrs=None): + resources = [] + + io_all = [] + if attrs is not None: + io_all.append(attrs) + io_all.append(Subsignal("cs", PinsN(cs_n, dir="o", conn=conn))) + io_all.append(Subsignal("clk", Pins(clk, dir="o", conn=conn, assert_width=1))) + + io_1x = list(io_all) + io_1x.append(Subsignal("copi", Pins(copi, dir="o", conn=conn, assert_width=1))) + io_1x.append(Subsignal("cipo", Pins(cipo, dir="i", conn=conn, assert_width=1))) + if wp_n is not None and hold_n is not None: + io_1x.append(Subsignal("wp", PinsN(wp_n, dir="o", conn=conn, assert_width=1))) + io_1x.append(Subsignal("hold", PinsN(hold_n, dir="o", conn=conn, assert_width=1))) + resources.append(Resource.family(*args, default_name="spi_flash", ios=io_1x, + name_suffix="1x")) + + io_2x = list(io_all) + io_2x.append(Subsignal("dq", Pins(" ".join([copi, cipo]), dir="io", conn=conn, + assert_width=2))) + resources.append(Resource.family(*args, default_name="spi_flash", ios=io_2x, + name_suffix="2x")) + + if wp_n is not None and hold_n is not None: + io_4x = list(io_all) + io_4x.append(Subsignal("dq", Pins(" ".join([copi, cipo, wp_n, hold_n]), dir="io", conn=conn, + assert_width=4))) + resources.append(Resource.family(*args, default_name="spi_flash", ios=io_4x, + name_suffix="4x")) + + return resources + + +def SDCardResources(*args, clk, cmd, dat0, dat1=None, dat2=None, dat3=None, cd=None, wp_n=None, + conn=None, attrs=None): + resources = [] + + io_common = [] + if attrs is not None: + io_common.append(attrs) + if cd is not None: + io_common.append(Subsignal("cd", Pins(cd, dir="i", conn=conn, assert_width=1))) + if wp_n is not None: + io_common.append(Subsignal("wp", PinsN(wp_n, dir="i", conn=conn, assert_width=1))) + + io_native = list(io_common) + io_native.append(Subsignal("clk", Pins(clk, dir="o", conn=conn, assert_width=1))) + io_native.append(Subsignal("cmd", Pins(cmd, dir="o", conn=conn, assert_width=1))) + + io_1bit = list(io_native) + io_1bit.append(Subsignal("dat", Pins(dat0, dir="io", conn=conn, assert_width=1))) + if dat3 is not None: + # DAT3 has a pullup and works as electronic card detect + io_1bit.append(Subsignal("ecd", Pins(dat3, dir="i", conn=conn, assert_width=1))) + resources.append(Resource.family(*args, default_name="sd_card", ios=io_1bit, + name_suffix="1bit")) + + if dat1 is not None and dat2 is not None and dat3 is not None: + io_4bit = list(io_native) + io_4bit.append(Subsignal("dat", Pins(" ".join((dat0, dat1, dat2, dat3)), dir="io", + conn=conn, assert_width=4))) + resources.append(Resource.family(*args, default_name="sd_card", ios=io_4bit, + name_suffix="4bit")) + + if dat3 is not None: + io_spi = list(io_common) + # DAT3/CS# has a pullup and doubles as electronic card detect + io_spi.append(Subsignal("cs", PinsN(dat3, dir="io", conn=conn, assert_width=1))) + io_spi.append(Subsignal("clk", Pins(clk, dir="o", conn=conn, assert_width=1))) + io_spi.append(Subsignal("copi", Pins(cmd, dir="o", conn=conn, assert_width=1))) + io_spi.append(Subsignal("cipo", Pins(dat0, dir="i", conn=conn, assert_width=1))) + resources.append(Resource.family(*args, default_name="sd_card", ios=io_spi, + name_suffix="spi")) + + return resources + + +def SRAMResource(*args, cs_n, oe_n=None, we_n, a, d, dm_n=None, + conn=None, attrs=None): + io = [] + io.append(Subsignal("cs", PinsN(cs_n, dir="o", conn=conn, assert_width=1))) + if oe_n is not None: + # Asserted WE# deactivates the D output buffers, so WE# can be used to replace OE#. + io.append(Subsignal("oe", PinsN(oe_n, dir="o", conn=conn, assert_width=1))) + io.append(Subsignal("we", PinsN(we_n, dir="o", conn=conn, assert_width=1))) + io.append(Subsignal("a", Pins(a, dir="o", conn=conn))) + io.append(Subsignal("d", Pins(d, dir="io", conn=conn))) + if dm_n is not None: + io.append(Subsignal("dm", PinsN(dm_n, dir="o", conn=conn))) # dm="LB# UB#" + if attrs is not None: + io.append(attrs) + return Resource.family(*args, default_name="sram", ios=io) + + +def SDRAMResource(*args, clk, cke=None, cs_n=None, we_n, ras_n, cas_n, ba, a, dq, dqm=None, + conn=None, attrs=None): + io = [] + io.append(Subsignal("clk", Pins(clk, dir="o", conn=conn, assert_width=1))) + if cke is not None: + io.append(Subsignal("clk_en", Pins(cke, dir="o", conn=conn, assert_width=1))) + if cs_n is not None: + io.append(Subsignal("cs", PinsN(cs_n, dir="o", conn=conn, assert_width=1))) + io.append(Subsignal("we", PinsN(we_n, dir="o", conn=conn, assert_width=1))) + io.append(Subsignal("ras", PinsN(ras_n, dir="o", conn=conn, assert_width=1))) + io.append(Subsignal("cas", PinsN(cas_n, dir="o", conn=conn, assert_width=1))) + io.append(Subsignal("ba", Pins(ba, dir="o", conn=conn))) + io.append(Subsignal("a", Pins(a, dir="o", conn=conn))) + io.append(Subsignal("dq", Pins(dq, dir="io", conn=conn))) + if dqm is not None: + io.append(Subsignal("dqm", Pins(dqm, dir="o", conn=conn))) # dqm="LDQM# UDQM#" + if attrs is not None: + io.append(attrs) + return Resource.family(*args, default_name="sdram", ios=io) + + +def NORFlashResources(*args, rst=None, byte_n=None, cs_n, oe_n, we_n, wp_n, by, a, dq, + conn=None, attrs=None): + resources = [] + + io_common = [] + if rst is not None: + io_common.append(Subsignal("rst", Pins(rst, dir="o", conn=conn, assert_width=1))) + io_common.append(Subsignal("cs", PinsN(cs_n, dir="o", conn=conn, assert_width=1))) + io_common.append(Subsignal("oe", PinsN(oe_n, dir="o", conn=conn, assert_width=1))) + io_common.append(Subsignal("we", PinsN(we_n, dir="o", conn=conn, assert_width=1))) + io_common.append(Subsignal("wp", PinsN(wp_n, dir="o", conn=conn, assert_width=1))) + io_common.append(Subsignal("rdy", Pins(by, dir="i", conn=conn, assert_width=1))) + + if byte_n is None: + io_8bit = list(io_common) + io_8bit.append(Subsignal("a", Pins(a, dir="o", conn=conn))) + io_8bit.append(Subsignal("dq", Pins(dq, dir="io", conn=conn, assert_width=8))) + resources.append(Resource.family(*args, default_name="nor_flash", ios=io_8bit, + name_suffix="8bit")) + else: + *dq_0_14, dq15_am1 = dq.split() + + # If present in a requested resource, this pin needs to be strapped correctly. + io_common.append(Subsignal("byte", PinsN(byte_n, dir="o", conn=conn, assert_width=1))) + + io_8bit = list(io_common) + io_8bit.append(Subsignal("a", Pins(" ".join((dq15_am1, a)), dir="o", conn=conn))) + io_8bit.append(Subsignal("dq", Pins(" ".join(dq_0_14[:8]), dir="io", conn=conn, + assert_width=8))) + resources.append(Resource.family(*args, default_name="nor_flash", ios=io_8bit, + name_suffix="8bit")) + + io_16bit = list(io_common) + io_16bit.append(Subsignal("a", Pins(a, dir="o", conn=conn))) + io_16bit.append(Subsignal("dq", Pins(dq, dir="io", conn=conn, assert_width=16))) + resources.append(Resource.family(*args, default_name="nor_flash", ios=io_16bit, + name_suffix="16bit")) + + return resources + + +def DDR3Resource(*args, rst_n=None, clk_p, clk_n, clk_en, cs_n, we_n, ras_n, cas_n, a, ba, dqs_p, dqs_n, dq, dm, odt, + conn=None, diff_attrs=None, attrs=None): + ios = [] + + ios.append(Subsignal("rst", PinsN(rst_n, dir="o", conn=conn, assert_width=1))) + ios.append(Subsignal("clk", DiffPairs(clk_p, clk_n, dir="o", conn=conn, assert_width=1), diff_attrs)) + ios.append(Subsignal("clk_en", Pins(clk_en, dir="o", conn=conn, assert_width=1))) + ios.append(Subsignal("cs", PinsN(cs_n, dir="o", conn=conn, assert_width=1))) + ios.append(Subsignal("we", PinsN(we_n, dir="o", conn=conn, assert_width=1))) + ios.append(Subsignal("ras", PinsN(ras_n, dir="o", conn=conn, assert_width=1))) + ios.append(Subsignal("cas", PinsN(cas_n, dir="o", conn=conn, assert_width=1))) + ios.append(Subsignal("a", Pins(a, dir="o", conn=conn))) + ios.append(Subsignal("ba", Pins(ba, dir="o", conn=conn))) + ios.append(Subsignal("dqs", DiffPairs(dqs_p, dqs_n, dir="io", conn=conn), diff_attrs)) + ios.append(Subsignal("dq", Pins(dq, dir="io", conn=conn))) + ios.append(Subsignal("dm", Pins(dm, dir="o", conn=conn))) + ios.append(Subsignal("odt", Pins(odt, dir="o", conn=conn, assert_width=1))) + + if attrs is not None: + ios.append(attrs) + + return Resource.family(*args, default_name="ddr3", ios=ios) diff --git a/re-bba/amaranth_boards/resources/user.py b/re-bba/amaranth_boards/resources/user.py new file mode 100644 index 0000000..046f122 --- /dev/null +++ b/re-bba/amaranth_boards/resources/user.py @@ -0,0 +1,43 @@ +from amaranth.build import * + + +__all__ = ["LEDResources", "RGBLEDResource", "ButtonResources", "SwitchResources"] + + +def _SplitResources(*args, pins, invert=False, conn=None, attrs=None, default_name, dir): + assert isinstance(pins, (str, list, dict)) + + if isinstance(pins, str): + pins = pins.split() + if isinstance(pins, list): + pins = dict(enumerate(pins)) + + resources = [] + for number, pin in pins.items(): + ios = [Pins(pin, dir=dir, invert=invert, conn=conn)] + if attrs is not None: + ios.append(attrs) + resources.append(Resource.family(*args, number, default_name=default_name, ios=ios)) + return resources + + +def LEDResources(*args, **kwargs): + return _SplitResources(*args, **kwargs, default_name="led", dir="o") + + +def RGBLEDResource(*args, r, g, b, invert=False, conn=None, attrs=None): + ios = [] + ios.append(Subsignal("r", Pins(r, dir="o", invert=invert, conn=conn, assert_width=1))) + ios.append(Subsignal("g", Pins(g, dir="o", invert=invert, conn=conn, assert_width=1))) + ios.append(Subsignal("b", Pins(b, dir="o", invert=invert, conn=conn, assert_width=1))) + if attrs is not None: + ios.append(attrs) + return Resource.family(*args, default_name="rgb_led", ios=ios) + + +def ButtonResources(*args, **kwargs): + return _SplitResources(*args, **kwargs, default_name="button", dir="i") + + +def SwitchResources(*args, **kwargs): + return _SplitResources(*args, **kwargs, default_name="switch", dir="i") diff --git a/re-bba/amaranth_boards/rz_easyfpga_a2_2.py b/re-bba/amaranth_boards/rz_easyfpga_a2_2.py new file mode 100644 index 0000000..8c313ef --- /dev/null +++ b/re-bba/amaranth_boards/rz_easyfpga_a2_2.py @@ -0,0 +1,126 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.intel import * +from .resources import * + + +__all__ = ["RZEasyFPGAA2_2Platform"] + + +class RZEasyFPGAA2_2Platform(IntelPlatform): + device = "EP4CE6" # Cyclone IV 6K LEs + package = "E22" # EQFP 144 pins + speed = "C8" + default_clk = "clk50" # 50MHz builtin clock + default_rst = "rst" + resources = [ + # Clock + Resource("clk50", 0, Pins("23", dir="i"), + Clock(50e6), Attrs(io_standard="3.3-V LVTTL")), + + # Reset switch, located on the lower left of the board. + Resource("rst", 0, PinsN("25", dir="i"), Attrs(io_standard="3.3-V LVTTL")), + + # LEDs, located on the bottom of the board. + *LEDResources( + pins="87 86 85 84", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # Buttons, located on the bottom of the board, right of the LEDs. + *ButtonResources( + pins="88 89 90 91", invert=True, + attrs=Attrs(io_standard="3.3-V LVTTL")), + + # Connections to the SKHynix RAM chip on board. + SDRAMResource(0, + clk="43", cs_n="72", we_n="69", ras_n="71", cas_n="70", + ba="73 74", a="76 77 80 83 68 67 66 65 64 60 75 59", + dq="28 30 31 32 33 34 38 39 54 53 52 51 50 49 46 44", + dqm="42 55", attrs=Attrs(io_standard="3.3-V LVCMOS")), + + # VGA connector, located on the right of the board. + VGAResource(0, + r="106", g="105", b="104", + hs="101", vs="103"), + + # 4 digit 7 segment display, located on top of the board. + Display7SegResource(0, + a="128", b="121", c="125", d="129", e="132", f="126", g="124", dp="127", + invert=True), + Resource("display_7seg_ctrl", 0, + Subsignal("en", Pins("133 135 136 137", dir="o", invert=True)), + ), + + # PS2 port, located on upper right of the board. + PS2Resource(0, clk="119", dat="120"), + + # LM75 temperature sensor + I2CResource(0, scl="112", sda="113"), + + # AT24C08 EEPROM + I2CResource(1, scl="99" , sda="98" ), + + # Buzzer + Resource("buzzer", 0, PinsN("110", dir="o")), + + # Serial port, located above the VGA port. + UARTResource(0, tx="114", rx="115"), + + # LCD connector, located above the 7 segment display. + Resource("lcd_hd44780", 0, + Subsignal("rs", Pins("141", dir="o")), + Subsignal("rw", Pins("138", dir="o")), + Subsignal("e" , Pins("143", dir="o")), + Subsignal("d" , Pins("142 1 144 3 2 10 7 11", dir="io")), + ), + + # IR receiver, located right of the buttons. + Resource("cir", 0, + Subsignal("rx", Pins("100", dir="i")) + ), + ] + + connectors = [ + # Located above the chip. + Connector("gpio", 0, + "- - 11 7 2 144 142 138 136 133 129 127 125 121 119 114 112 110 - " + "- - 24 10 3 1 143 141 137 135 132 128 126 124 120 115 113 111 - "), + + # Located right of the chip. + Connector("gpio", 1, + "- - " + "106 105" + "104 103" + "101 100" + "99 98 " + "91 90 " + "89 88 " + "87 86 " + "85 84 " + "- - "), + + # Located below the chip. + Connector("gpio", 2, + "30 32 34 39 43 46 50 52 54 58 60 65 67 71 73 75 77 83 - - - " + "28 31 33 38 42 44 51 53 55 59 64 66 68 70 72 74 76 80 - - - "), + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = { + "add_settings": + '''set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"''' + } + return super().toolchain_prepare(fragment, name, **overrides, **kwargs) + + def toolchain_program(self, products, name): + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") + with products.extract("{}.sof".format(name)) as bitstream_filename: + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", + "--operation", "P;" + bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import Blinky + RZEasyFPGAA2_2Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/sk_xc6slx9.py b/re-bba/amaranth_boards/sk_xc6slx9.py new file mode 100644 index 0000000..7e77314 --- /dev/null +++ b/re-bba/amaranth_boards/sk_xc6slx9.py @@ -0,0 +1,55 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.xilinx_spartan_3_6 import * +from .resources import * + + +__all__ = ["SK_XC6SLX9Platform"] + + +class SK_XC6SLX9Platform(XilinxSpartan6Platform): + device = "xc6slx9" + package = "tqg144" + speed = "2" + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("P134", dir="i"), + Clock(50e6), Attrs(IOSTANDARD="LVCMOS33") + ), + + *SPIFlashResources(0, + cs_n="P38", clk="P70", copi="P64", cipo="65", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + + SRAMResource(0, + cs_n="P97", oe_n="P45", we_n="P51", + a="P39 P40 P41 P43 P44 P55 P56 P57 P58 P59 P82 P81 P80 P79 P78 P66 P62 P61 P60", + d="P46 P47 P48 P50 P75 P74 P69 P67", + attrs=Attrs(IOSTANDARD="LVCMOS33") + ), + ] + connectors = [ + Connector("x", 7, + "- - P34 - P33 P32 P30 P29 P27 P26 " + "P24 P23 P22 P21 P17 P16 P15 P14 P12 P11 " + "P10 P9 P8 P7 P6 P5 P2 P1 P143 P144 " + "P141 P142 P139 P140 P137 P138 P132 P133 P127 P131 " + ), + Connector("x", 9, + "- - P93 - P92 P88 P87 P85 P84 P83 " + "P74 P75 P78 P79 P81 P80 P69 P82 P66 P67 " + "P61 P62 P59 P60 P58 P57 P55 P56 P50 P51 " + "P47 P48 P44 P46 P45 P43 P40 P41 P35 P39 " + ), + Connector("x", 8, + "- - P126 - P123 P124 P120 P121 P118 P119 " + "P116 P117 P114 P115 P111 P112 P104 P105 P101 P102 " + "P99 P100 P97 P98 P94 P95 - - - - " + "- - - - - - - - - - " + ), + ] + + # This board doesn't have an integrated programmer. diff --git a/re-bba/amaranth_boards/supercon19badge.py b/re-bba/amaranth_boards/supercon19badge.py new file mode 100644 index 0000000..c6aab63 --- /dev/null +++ b/re-bba/amaranth_boards/supercon19badge.py @@ -0,0 +1,167 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ecp5 import * +from .resources import * + + +__all__ = ["Supercon19BadgePlatform"] + + +class Supercon19BadgePlatform(LatticeECP5Platform): + device = "LFE5U-45F" + package = "BG381" + speed = "8" + default_clk = "clk8" + + # The badge's LEDs are wired in a non-straightforward way. Here, the + # LEDResources represent each of the common anodes of a collection of RGB LEDs. + # A single one of their cathodes defaults to connected via a FET; the other + # cathodes are normally-off. Accordingly, they act as normal single-color LEDs + # unless the cathode signals are explicitly driven. + # + # The LEDs on the badge were meant to be a puzzle; so each cathode signal + # corresponds to a different color on each LED. This means there's no + # straightforward way of creating pin definitions; you'll need to use the + # following mapping to find the cathode pin number below. + led_cathode_mappings = [ + {'r': 0, 'g': 1, 'b': 2}, # LED1: by default, red + {'r': 2, 'g': 1, 'b': 0}, # LED2: by default, blue + {'r': 0, 'g': 1, 'b': 2}, # LED3: by default, red + {'r': 2, 'g': 1, 'b': 0}, # LED4: by default, blue + {'r': 0, 'g': 1, 'b': 2}, # LED5: by default, red + {'r': 2, 'g': 1, 'b': 0}, # LED6: by default, blue + {'r': 2, 'g': 0, 'b': 1}, # LED7: by default, green + {'r': 0, 'g': 1, 'b': 2}, # LED8: by default, red + {'r': 0, 'g': 1, 'b': 2}, # LED9: by default, red + # Note: [LED10 is disconnected by default; bridge R60 to make things work] + {'r': 2, 'g': 1, 'b': 0}, # LED10: by default, blue + {'r': 1, 'g': 0, 'b': 2}, # LED11: by default, green + ] + + resources = [ + Resource("clk8", 0, Pins("U18"), Clock(8e6), Attrs(IO_TYPE="LVCMOS33")), + + # Used to trigger FPGA reconfiguration. + Resource("program", 0, PinsN("R1"), Attrs(IO_TYPE="LVCMOS33")), + + # See note above for LED anode/cathode information. + # Short version is: these work as normal LEDs until you touch their cathodes. + *LEDResources(pins="E3 D3 C3 C4 C2 B1 B20 B19 A18 K20 K19", + attrs=Attrs(IO_TYPE="LVCMOS33")), + Resource("led_cathodes", 0, Pins("P19 L18 K18"), Attrs(IO_TYPE="LVCMOS33")), + + UARTResource(0, rx="U2", tx="U1", attrs=Attrs(IO_TYPE="LVCMOS33")), + + DirectUSBResource(0, d_p="F3", d_n="G3", pullup="E4", vbus_valid="F4", + attrs=Attrs(IO_TYPE="LVCMOS33")), + + # Buttons, with semantic aliases. + *ButtonResources(pins="G2 F2 F1 C1 E1 D2 D1 E2", + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") + ), + Resource("keypad", 0, + Subsignal("left", Pins("G2", dir="i")), + Subsignal("right", Pins("F2", dir="i")), + Subsignal("up", Pins("F1", dir="i")), + Subsignal("down", Pins("C1", dir="i")), + Subsignal("start", Pins("E1", dir="i")), + Subsignal("select",Pins("D2", dir="i")), + Subsignal("a", Pins("D1", dir="i")), + Subsignal("b", Pins("E2", dir="i")), + Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") + ), + + # Direct HDMI on the bottom of the board. + Resource("hdmi", 0, + Subsignal("clk", DiffPairsN("P20", "R20"), Attrs(IO_TYPE="TMDS_33")), + Subsignal("d", DiffPairs("N19 L20 L16", "N20 M20 L17"), Attrs(IO_TYPE="TMDS_33")), + Subsignal("hpd", PinsN("R18"), Attrs(IO_TYPE="LVCMOS33")),# Also called HDMI_HEAC_n + Subsignal("hdmi_heac_p", PinsN("T19"), Attrs(IO_TYPE="LVCMOS33")), + Attrs(DRIVE="4"), + ), + + Resource("lcd", 0, + Subsignal("db", + Pins("J3 H1 K4 J1 K3 K2 L4 K1 L3 L2 M4 L1 M3 M1 N4 N2 N3 N1"), + ), + Subsignal("rd", Pins("P2")), + Subsignal("wr", Pins("P4")), + Subsignal("rs", Pins("P1")), + Subsignal("cs", Pins("P3")), + Subsignal("id", Pins("J4")), + Subsignal("rst", Pins("H2")), + Subsignal("fmark", Pins("G1")), + Subsignal("blen", Pins("P5")), + Attrs(IO_TYPE="LVCMOS33") + ), + + Resource("spi_flash", 0, # clock needs to be accessed through USRMCLK + Subsignal("cs", PinsN("R2")), + Subsignal("copi", Pins("W2")), + Subsignal("cipo", Pins("V2")), + Subsignal("wp", Pins("Y2")), + Subsignal("hold", Pins("W1")), + Attrs(IO_TYPE="LVCMOS33") + ), + Resource("spi_flash_4x", 0, # clock needs to be accessed through USRMCLK + Subsignal("cs", PinsN("R2")), + Subsignal("dq", Pins("W2 V2 Y2 W1")), + Attrs(IO_TYPE="LVCMOS33") + ), + + # SPI-connected PSRAM. + Resource("spi_psram_4x", 0, + Subsignal("cs", PinsN("D20")), + Subsignal("clk", Pins("E20")), + Subsignal("dq", Pins("E19 D19 C20 F19"), Attrs(PULLMODE="UP")), + Attrs(IO_TYPE="LVCMOS33", SLEWRATE="SLOW") + ), + Resource("spi_psram_4x", 1, + Subsignal("cs", PinsN("F20")), + Subsignal("clk", Pins("J19")), + Subsignal("dq", Pins("J20 G19 G20 H20"), Attrs(PULLMODE="UP")), + Attrs(IO_TYPE="LVCMOS33", SLEWRATE="SLOW") + ), + + SDRAMResource(0, clk="D11", cke="C11", cs_n="C7", we_n="B6", ras_n="D6", cas_n="A6", + ba="A7 C8", a="A8 D9 C9 B9 C14 E17 A12 B12 H17 G18 B8 A11 B11", + dq="C5 B5 A5 C6 B10 C10 D10 A9", dqm="A10", + attrs=Attrs(IO_TYPE="LVCMOS33", SLEWRATE="FAST") + ) + ] + + connectors = [ + Connector("pmod", 0, "A15 C16 A14 D16 B15 C15 A13 B13"), + Connector("cartridge", 0, + "- - - - - - - - C5 B5 A5 C6 B6 A6 D6 C7 A7 C8 B8 A8 D9 C9 B9 A9" # continued: + " D10 C10 B10 A10 D11 C11 B11 A11 G18 H17 B12 A12 E17 C14" + ), + + # SAO connectors names are compliant with the, erm, SAO 1.69 X-TREME standard. + # See: https://hackaday.com/2019/03/20/introducing-the-shitty-add-on-v1-69bis-standard/ + Connector("sao", 0, { + "sda": "B3", "scl": "B2", "gpio0": "A2", + "gpio1": "A3", "gpio2": "B4", "gpio3": "A4" + }), + Connector("sao", 1, { + "sda": "A16", "scl": "B17", "gpio0": "B18", + "gpio1": "A17", "gpio2": "B16", "gpio3": "C17" + }) + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = dict(ecppack_opts="--compress --freq 38.8") + overrides.update(kwargs) + return super().toolchain_prepare(fragment, name, **overrides, **kwargs) + + def toolchain_program(self, products, name): + dfu_util = os.environ.get("DFU_UTIL", "dfu-util") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.check_call([dfu_util, "-d", "1d50:614b", "-a", "0", "-D", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + Supercon19BadgePlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/te0714_03_50_2I.py b/re-bba/amaranth_boards/te0714_03_50_2I.py new file mode 100644 index 0000000..c7c015c --- /dev/null +++ b/re-bba/amaranth_boards/te0714_03_50_2I.py @@ -0,0 +1,132 @@ +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * +from .resources import * + + +__all__ = ["TE0714_03_50_2IPlatform"] + + +class TE0714_03_50_2IPlatform(Xilinx7SeriesPlatform): + device = "xc7a50t" + package = "csg325" + speed = "2" + default_clk = "clk25" + resources = [ + Resource("clk25", 0, Pins("T14", dir="i"), Clock(25e6), Attrs(IOSTANDARD="LVCMOS18")), + *LEDResources(pins="K18", attrs=Attrs(IOSTANDARD="LVCMOS18")), + *SPIFlashResources(0, + cs_n="L15", clk="E8", copi="K16", cipo="K17", wp_n="J15", hold_n="J16", + attrs=Attrs(IOSTANDARD="LVCMOS18") + ) + ] + connectors = [ + Connector("JM1", 0, + "G4 D6 " + "G3 D5 " + "- - " + "C4 B2 " + "C3 B1 " + "- - " + "A4 D2 " + "A3 D1 " + "- - " + "E4 F2 " + "E3 F1 " + "- - " + "K10 H2 " + "L9 H1 " + "- - " + "J5 L5 " + "J4 M5 " + "K6 M2 " + "K5 M1 " + "K3 K2 " + "L2 K1 " + "L4 N1 " + "L3 P1 " + "- - " + "M4 M6 " + "N4 N6 " + "N2 R2 " + "N3 R1 " + "P3 R3 " + "P4 T2 " + "L6 U1 " + "T3 U2 " + "T4 - " + "R5 V2 " + "T5 V3 " + "P5 U4 " + "P6 V4 " + "T7 U5 " + "R7 U6 " + "V6 V7 " + "U7 V8 " + "- - " + "V9 T9 " + "U9 T8 " + "V11 F8 " + "U11 R8 " + "V12 - " + "V13 F12 " + "- - " + "- - " + ), + Connector("JM2", 0, + "A12 B9 " + "B12 A9 " + "A13 B10 " + "A14 A10 " + "B14 B11 " + "A15 C11 " + "C14 C8 " + "B15 D8 " + "- E11 " + "A17 C9 " + "B16 D9 " + "B17 D11 " + "C16 C12 " + "C18 D13 " + "C17 C13 " + "D18 E13 " + "E17 D14 " + "- - " + "E18 D15 " + "F17 E15 " + "F18 D16 " + "G17 E16 " + "F15 F14 " + "G15 G14 " + "H17 G16 " + "H18 H16 " + "- A16 " + "K17 J14 " + "L18 K15 " + "M17 M14 " + "M16 N14 " + "R18 N16 " + "T18 N17 " + "E8 K16 " + "L15 J16 " + "L17 - " + "J15 P16 " + "N18 P15 " + "P18 R17 " + "T17 R16 " + "U17 P14 " + "- R15 " + "V17 T15 " + "V16 T14 " + "U16 - " + "U15 R13 " + "U14 T13 " + "V14 U12 " + "U10 T12 " + "L14 R12 " + ) + ] + + +if __name__ == "__main__": + from .test.blinky import Blinky + TE0714_03_50_2IPlatform().build(Blinky(), do_program=False) diff --git a/re-bba/amaranth_boards/test/__init__.py b/re-bba/amaranth_boards/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/re-bba/amaranth_boards/test/blinky.py b/re-bba/amaranth_boards/test/blinky.py new file mode 100644 index 0000000..9999246 --- /dev/null +++ b/re-bba/amaranth_boards/test/blinky.py @@ -0,0 +1,48 @@ +import itertools + +from amaranth import * +from amaranth.build import ResourceError + + +__all__ = ["Blinky"] + + +class Blinky(Elaboratable): + def elaborate(self, platform): + m = Module() + + def get_all_resources(name): + resources = [] + for number in itertools.count(): + try: + resources.append(platform.request(name, number)) + except ResourceError: + break + return resources + + rgb_leds = [res for res in get_all_resources("rgb_led")] + leds = [res.o for res in get_all_resources("led")] + leds.extend([led.r.o for led in rgb_leds]) + leds.extend([led.g.o for led in rgb_leds]) + leds.extend([led.b.o for led in rgb_leds]) + buttons = [res.i for res in get_all_resources("button")] + switches = [res.i for res in get_all_resources("switch")] + + inverts = [0 for _ in leds] + for index, button in zip(itertools.cycle(range(len(inverts))), buttons): + inverts[index] ^= button + for index, switch in zip(itertools.cycle(range(len(inverts))), switches): + inverts[index] ^= switch + + clk_freq = platform.default_clk_frequency + timer = Signal(range(int(clk_freq//2)), reset=int(clk_freq//2) - 1) + flops = Signal(len(leds)) + + m.d.comb += Cat(leds).eq(flops ^ Cat(inverts)) + with m.If(timer == 0): + m.d.sync += timer.eq(timer.reset) + m.d.sync += flops.eq(~flops) + with m.Else(): + m.d.sync += timer.eq(timer - 1) + + return m diff --git a/re-bba/amaranth_boards/tinyfpga_ax1.py b/re-bba/amaranth_boards/tinyfpga_ax1.py new file mode 100644 index 0000000..7c76768 --- /dev/null +++ b/re-bba/amaranth_boards/tinyfpga_ax1.py @@ -0,0 +1,24 @@ +from amaranth.build import * +from amaranth.vendor.lattice_machxo2 import * +from .resources import * + + +__all__ = ["TinyFPGAAX1Platform"] + + +class TinyFPGAAX1Platform(LatticeMachXO2Platform): + device = "LCMXO2-256HC" + package = "SG32" + speed = "4" + connectors = [ + Connector("gpio", 0, + # Left side of the board + # 1 2 3 4 5 6 7 8 9 10 11 + "13 14 16 17 20 21 23 25 26 27 28 " + # Right side of the board + # 12 13 14 15 16 17 18 19 20 21 22 + "- - - - 4 5 8 9 10 11 12 " + ), + ] + resources = [] + # This board doesn't have an integrated programmer. diff --git a/re-bba/amaranth_boards/tinyfpga_ax2.py b/re-bba/amaranth_boards/tinyfpga_ax2.py new file mode 100644 index 0000000..3e9e989 --- /dev/null +++ b/re-bba/amaranth_boards/tinyfpga_ax2.py @@ -0,0 +1,24 @@ +from amaranth.build import * +from amaranth.vendor.lattice_machxo2 import * +from .resources import * + + +__all__ = ["TinyFPGAAX2Platform"] + + +class TinyFPGAAX2Platform(LatticeMachXO2Platform): + device = "LCMXO2-1200HC" + package = "SG32" + speed = "4" + connectors = [ + Connector("gpio", 0, + # Left side of the board + # 1 2 3 4 5 6 7 8 9 10 11 + "13 14 16 17 20 21 23 25 26 27 28 " + # Right side of the board + # 12 13 14 15 16 17 18 19 20 21 22 + "- - - - 4 5 8 9 10 11 12 " + ), + ] + resources = [] + # This board doesn't have an integrated programmer. diff --git a/re-bba/amaranth_boards/tinyfpga_bx.py b/re-bba/amaranth_boards/tinyfpga_bx.py new file mode 100644 index 0000000..b8ce12f --- /dev/null +++ b/re-bba/amaranth_boards/tinyfpga_bx.py @@ -0,0 +1,53 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["TinyFPGABXPlatform"] + + +class TinyFPGABXPlatform(LatticeICE40Platform): + device = "iCE40LP8K" + package = "CM81" + default_clk = "clk16" + resources = [ + Resource("clk16", 0, Pins("B2", dir="i"), + Clock(16e6), Attrs(IO_STANDARD="SB_LVCMOS")), + + *LEDResources(pins="B3", attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + + DirectUSBResource(0, d_p="B4", d_n="A4", pullup="A3", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + + *SPIFlashResources(0, + cs_n="F7", clk="G7", copi="G6", cipo="H7", wp_n="H4", hold_n="J8", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + ] + connectors = [ + Connector("gpio", 0, + # Left side of the board + # 1 2 3 4 5 6 7 8 9 10 11 12 13 + " A2 A1 B1 C2 C1 D2 D1 E2 E1 G2 H1 J1 H2 " + # Right side of the board + # 14 15 16 17 18 19 20 21 22 23 24 + " H9 D9 D8 C9 A9 B8 A8 B7 A7 B6 A6 " + # Bottom of the board + # 25 26 27 28 29 30 31 + "G1 J3 J4 G9 J9 E8 J2" + ), + ] + + def toolchain_program(self, products, name): + tinyprog = os.environ.get("TINYPROG", "tinyprog") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([tinyprog, "-p", bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + TinyFPGABXPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/ulx3s.py b/re-bba/amaranth_boards/ulx3s.py new file mode 100644 index 0000000..cb34171 --- /dev/null +++ b/re-bba/amaranth_boards/ulx3s.py @@ -0,0 +1,197 @@ +import os +import argparse +import subprocess +import shutil + +from amaranth.build import * +from amaranth.vendor.lattice_ecp5 import * +from .resources import * + + +__all__ = [ + "ULX3S_12F_Platform", "ULX3S_25F_Platform", + "ULX3S_45F_Platform", "ULX3S_85F_Platform" +] + + +class _ULX3SPlatform(LatticeECP5Platform): + package = "BG381" + speed = "6" + default_clk = "clk25" + + resources = [ + Resource("clk25", 0, Pins("G2", dir="i"), Clock(25e6), Attrs(IO_TYPE="LVCMOS33")), + + # Used to reload FPGA configuration. + Resource("program", 0, PinsN("M4", dir="o"), Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP")), + + *LEDResources(pins="B2 C2 C1 D2 D1 E2 E1 H3", + attrs=Attrs(IO_TYPE="LVCMOS33", DRIVE="4")), + *ButtonResources(pins="R1 T1 R18 V1 U1 H16", + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="DOWN") + ), + *ButtonResources("switch", pins="E8 D8 D7 E7", + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="DOWN") + ), + + # Semantic aliases by button label. + Resource("button_pwr", 0, PinsN("D6", dir="i"), Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP")), + Resource("button_fire", 0, Pins("R1", dir="i"), Attrs(IO_TYPE="LVCMOS33", PULLMODE="DOWN")), + Resource("button_fire", 1, Pins("T1", dir="i"), Attrs(IO_TYPE="LVCMOS33", PULLMODE="DOWN")), + Resource("button_up", 0, Pins("R18", dir="i"), Attrs(IO_TYPE="LVCMOS33", PULLMODE="DOWN")), + Resource("button_down", 0, Pins("V1", dir="i"), Attrs(IO_TYPE="LVCMOS33", PULLMODE="DOWN")), + Resource("button_left", 0, Pins("U1", dir="i"), Attrs(IO_TYPE="LVCMOS33", PULLMODE="DOWN")), + Resource("button_right", 0, Pins("H16", dir="i"), Attrs(IO_TYPE="LVCMOS33", PULLMODE="DOWN")), + + # FTDI connection. + UARTResource(0, + rx="M1", tx="L4", rts="M3", dtr="N1", role="dce", + attrs=Attrs(IO_TYPE="LVCMOS33") + ), + Resource("uart_tx_enable", 0, Pins("L3", dir="o"), Attrs(IO_TYPE="LVCMOS33")), + + *SDCardResources(0, + clk="J1", cmd="J3", dat0="K2", dat1="K1", dat2="H2", dat3="H1", + attrs=Attrs(IO_TYPE="LVCMOS33", SLEW="FAST") + ), + + # SPI Flash clock is accessed via USR_MCLK instance. + Resource("spi_flash", 0, + Subsignal("cs", PinsN("R2", dir="o")), + Subsignal("copi", Pins("W2", dir="o")), + Subsignal("cipo", Pins("V2", dir="i")), + Subsignal("hold", PinsN("W1", dir="o")), + Subsignal("wp", PinsN("Y2", dir="o")), + Attrs(PULLMODE="NONE", DRIVE="4", IO_TYPE="LVCMOS33") + ), + + SDRAMResource(0, + clk="F19", cke="F20", cs_n="P20", we_n="T20", cas_n="T19", ras_n="R20", dqm="U19 E20", + ba="P19 N20", a="M20 M19 L20 L19 K20 K19 K18 J20 J19 H20 N19 G20 G19", + dq="J16 L18 M18 N18 P18 T18 T17 U20 E19 D20 D19 C20 E18 F18 J18 J17", + attrs=Attrs(PULLMODE="NONE", DRIVE="4", SLEWRATE="FAST", IO_TYPE="LVCMOS33") + ), + + # SPI bus for ADC. + SPIResource("adc", 0, cs_n="R17", copi="R16", cipo="U16", clk="P17", + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP")), + + # TRRS audio jack + Resource("audio", 0, + Subsignal("l", Pins("E4 D3 C3 B3", dir="o")), + Subsignal("r", Pins("A3 B5 D5 C5", dir="o")), + Subsignal("ring2", Pins("H5 F2 F5 E5", dir="o")), # extra ring out for video adapters + ), + + # ESP-32 connections + Resource("esp32", 0, + Subsignal("en", Pins("F1", dir="o"), Attrs(PULLMODE="UP")), + Subsignal("tx", Pins("K3", dir="o"), Attrs(PULLMODE="UP")), + Subsignal("rx", Pins("K4", dir="i"), Attrs(PULLMODE="UP")), + Subsignal("gpio0", Pins("L2"), Attrs(PULLMODE="UP")), + Subsignal("gpio5", Pins("N4")), + Subsignal("gpio16", Pins("L1"), Attrs(PULLMODE="UP")), + Subsignal("gpio17", Pins("N3"), Attrs(PULLMODE="UP")), + Attrs(IO_TYPE="LVCMOS33", DRIVE="4") + ), + + # PCB antenna, tuned to 433MHz + Resource("ant", 0, Pins("G1", dir="o"), Attrs(IO_TYPE="LVCMOS33")), + + # Differential versions of our connector I/O. + Resource("diff_gpio", 0, DiffPairs("B11", "C11"), Attrs(IO_TYPE="LVCMOS33")), + Resource("diff_gpio", 1, DiffPairs("A10", "A11"), Attrs(IO_TYPE="LVCMOS33")), + Resource("diff_gpio", 2, DiffPairs("A9", "B10"), Attrs(IO_TYPE="LVCMOS33")), + Resource("diff_gpio", 3, DiffPairs("B9", "C10"), Attrs(IO_TYPE="LVCMOS33")), + + # HDMI (only TX, due to the top bank of ECP5 only supporting diff. outputs) + Resource("hdmi", 0, + Subsignal("cec", Pins("A18", dir="io"), + Attrs(IO_TYPE="LVCMOS33", DRIVE="4", PULLMODE="UP")), + Subsignal("clk", DiffPairs("A17", "B18", dir="o"), + Attrs(IO_TYPE="LVCMOS33D", DRIVE="4")), + Subsignal("d", DiffPairs("A16 A14 A12", "B16 C14 A13", dir="o"), + Attrs(IO_TYPE="LVCMOS33D", DRIVE="4")), + Subsignal("eth", DiffPairs("A19", "B20", dir="o"), + Attrs(IO_TYPE="LVCMOS33D", DRIVE="4")), + Subsignal("scl", Pins("E12", dir="io"), + Attrs(IO_TYPE="LVCMOS33", DRIVE="4", PULLMODE="UP")), + Subsignal("sda", Pins("B19", dir="io"), + Attrs(IO_TYPE="LVCMOS33", DRIVE="4", PULLMODE="UP"))), + + DirectUSBResource(0, + d_p="D15", d_n="E15", pullup="B12", + attrs=Attrs(IO_TYPE="LVCMOS33") + ) + ] + + connectors = [ + Connector("gpio", 0, { + "0+": "B11", "0-": "C11", "1+": "A10", "1-": "A11", + "2+": "A9", "2-": "B10", "3+": "B9", "3-": "C10", + "4+": "A7", "4-": "A8", "5+": "C8", "5-": "B8", + "6+": "C6", "6-": "C7", "7+": "A6", "7-": "B6", + "8+": "A4", "8-": "A5", "9+": "A2", "9-": "B1", + "10+": "C4", "10-": "B4", "11+": "F4", "11-": "E3", + "12+": "G3", "12-": "F3", "13+": "H4", "13-": "G5", + "14+": "U18", "14-": "U17", "15+": "N17", "15-": "P16", + "16+": "N16", "16-": "M17", "17+": "L16", "17-": "L17", + "18+": "H18", "18-": "H17", "19+": "F17", "19-": "G18", + "20+": "D18", "20-": "E17", "21+": "C18", "21-": "D17", + "22+": "B15", "22-": "C15", "23+": "B17", "23-": "C17", + "24+": "C16", "24-": "D16", "25+": "D14", "25-": "E14", + "26+": "B13", "26-": "C13", "27+": "D13", "27-": "E13", + }) + ] + + @property + def required_tools(self): + return super().required_tools + [ + "openFPGALoader" + ] + + def toolchain_prepare(self, fragment, name, **kwargs): + overrides = dict(ecppack_opts="--compress") + overrides.update(kwargs) + return super().toolchain_prepare(fragment, name, **overrides) + + def toolchain_program(self, products, name): + tool = os.environ.get("OPENFPGALOADER", "openFPGALoader") + with products.extract("{}.bit".format(name)) as bitstream_filename: + subprocess.check_call([tool, "-b", "ulx3s", '-m', bitstream_filename]) + + +class ULX3S_12F_Platform(_ULX3SPlatform): + device = "LFE5U-12F" + + +class ULX3S_25F_Platform(_ULX3SPlatform): + device = "LFE5U-25F" + + +class ULX3S_45F_Platform(_ULX3SPlatform): + device = "LFE5U-45F" + + +class ULX3S_85F_Platform(_ULX3SPlatform): + device = "LFE5U-85F" + + +if __name__ == "__main__": + from .test.blinky import * + + variants = { + '12F': ULX3S_12F_Platform, + '25F': ULX3S_25F_Platform, + '45F': ULX3S_45F_Platform, + '85F': ULX3S_85F_Platform + } + + # Figure out which FPGA variant we want to target... + parser = argparse.ArgumentParser() + parser.add_argument('variant', choices=variants.keys()) + args = parser.parse_args() + + # ... and run Blinky on it. + platform = variants[args.variant] + platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/upduino_v1.py b/re-bba/amaranth_boards/upduino_v1.py new file mode 100644 index 0000000..3089e78 --- /dev/null +++ b/re-bba/amaranth_boards/upduino_v1.py @@ -0,0 +1,36 @@ +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * + + +__all__ = ["UpduinoV1Platform"] + + +class UpduinoV1Platform(LatticeICE40Platform): + device = "iCE40UP5K" + package = "SG48" + default_clk = "SB_HFOSC" + hfosc_div = 0 + resources = [ + *LEDResources(pins="39 40 41", invert=True, + attrs=Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_g", 0, PinsN("39", dir="o"), + Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_b", 0, PinsN("40", dir="o"), + Attrs(IO_STANDARD="SB_LVCMOS")), + Resource("led_r", 0, PinsN("41", dir="o"), + Attrs(IO_STANDARD="SB_LVCMOS")), + + *SPIFlashResources(0, + cs_n="16", clk="15", cipo="17", copi="14", + attrs=Attrs(IO_STANDARD="SB_LVCMOS") + ), + ] + connectors = [ + # "Left" row of header pins (JP5 on the schematic) + Connector("j", 0, "- - 23 25 26 27 32 35 31 37 34 43 36 42 38 28"), + # "Right" row of header pins (JP6 on the schematic) + Connector("j", 1, "12 21 13 19 18 11 9 6 44 4 3 48 45 47 46 2") + ] + + # This board doesn't have an integrated programmer. diff --git a/re-bba/amaranth_boards/upduino_v2.py b/re-bba/amaranth_boards/upduino_v2.py new file mode 100644 index 0000000..b6be916 --- /dev/null +++ b/re-bba/amaranth_boards/upduino_v2.py @@ -0,0 +1,30 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ice40 import * +from .resources import * +from .upduino_v1 import UpduinoV1Platform + + +__all__ = ["UpduinoV2Platform"] + + +class UpduinoV2Platform(UpduinoV1Platform): + # Mostly identical to the V1 board, but it has an integrated + # programmer and a 12MHz oscillator which is NC by default. + resources = UpduinoV1Platform.resources + [ + # Solder pin 12 to the adjacent 'J8' osc_out pin to enable. + Resource("clk12", 0, Pins("12", dir="i"), + Clock(12e6), Attrs(IO_STANDARD="SB_LVCMOS")), + ] + + def toolchain_program(self, products, name): + iceprog = os.environ.get("ICEPROG", "iceprog") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([iceprog, bitstream_filename]) + + +if __name__ == "__main__": + from .test.blinky import * + UpduinoV2Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/versa_ecp5.py b/re-bba/amaranth_boards/versa_ecp5.py new file mode 100644 index 0000000..9001a8e --- /dev/null +++ b/re-bba/amaranth_boards/versa_ecp5.py @@ -0,0 +1,176 @@ +import os +import subprocess + +from amaranth.build import * +from amaranth.vendor.lattice_ecp5 import * +from .resources import * + + +__all__ = ["VersaECP5Platform"] + + +class VersaECP5Platform(LatticeECP5Platform): + device = "LFE5UM-45F" + package = "BG381" + speed = "8" + default_clk = "clk100" + default_rst = "rst" + resources = [ + Resource("rst", 0, PinsN("T1", dir="i"), Attrs(IO_TYPE="LVCMOS33")), + Resource("clk100", 0, DiffPairs("P3", "P4", dir="i"), + Clock(100e6), Attrs(IO_TYPE="LVDS")), + Resource("pclk", 0, DiffPairs("A4", "A5", dir="i"), + Attrs(IO_TYPE="LVDS")), + + *LEDResources(pins="E16 D17 D18 E18 F17 F18 E17 F16", + attrs=Attrs(IO_TYPE="LVCMOS25")), + + Resource("alnum_led", 0, + Subsignal("a", PinsN("M20", dir="o")), + Subsignal("b", PinsN("L18", dir="o")), + Subsignal("c", PinsN("M19", dir="o")), + Subsignal("d", PinsN("L16", dir="o")), + Subsignal("e", PinsN("L17", dir="o")), + Subsignal("f", PinsN("M18", dir="o")), + Subsignal("g", PinsN("N16", dir="o")), + Subsignal("h", PinsN("M17", dir="o")), + Subsignal("j", PinsN("N18", dir="o")), + Subsignal("k", PinsN("P17", dir="o")), + Subsignal("l", PinsN("N17", dir="o")), + Subsignal("m", PinsN("P16", dir="o")), + Subsignal("n", PinsN("R16", dir="o")), + Subsignal("p", PinsN("R17", dir="o")), + Subsignal("dp", PinsN("U1", dir="o")), + Attrs(IO_TYPE="LVCMOS25") + ), + + *SwitchResources(pins={0: "H2", 1: "K3", 2: "G3", 3: "F2" }, + attrs=Attrs(IO_TYPE="LVCMOS15")), + *SwitchResources(pins={4: "J18", 5: "K18", 6: "K19", 7: "K20"}, + attrs=Attrs(IO_TYPE="LVCMOS25")), + + UARTResource(0, + rx="C11", tx="A11", + attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") + ), + + *SPIFlashResources(0, + cs_n="R2", clk="U3", cipo="W2", copi="V2", wp_n="Y2", hold_n="W1", + attrs=Attrs(IO_TYPE="LVCMOS33") + ), + + Resource("eth_clk125", 0, Pins("L19", dir="i"), + Clock(125e6), Attrs(IO_TYPE="LVCMOS25")), + Resource("eth_clk125_pll", 0, Pins("U16", dir="i"), + Clock(125e6), Attrs(IO_TYPE="LVCMOS25")), # NC by default + Resource("eth_rgmii", 0, + Subsignal("rst", PinsN("U17", dir="o")), + Subsignal("mdc", Pins("T18", dir="o")), + Subsignal("mdio", Pins("U18", dir="io")), + Subsignal("tx_clk", Pins("P19", dir="o")), + Subsignal("tx_ctl", Pins("R20", dir="o")), + Subsignal("tx_data", Pins("N19 N20 P18 P20", dir="o")), + Subsignal("rx_clk", Pins("L20", dir="i")), + Subsignal("rx_ctl", Pins("U19", dir="i")), + Subsignal("rx_data", Pins("T20 U20 T19 R18", dir="i")), + Attrs(IO_TYPE="LVCMOS25") + ), + Resource("eth_sgmii", 0, + Subsignal("rst", PinsN("U17", dir="o"), Attrs(IO_TYPE="LVCMOS25")), + Subsignal("mdc", Pins("T18", dir="o"), Attrs(IO_TYPE="LVCMOS25")), + Subsignal("mdio", Pins("U18", dir="io"), Attrs(IO_TYPE="LVCMOS25")), + Subsignal("tx", DiffPairs("W13", "W14", dir="o")), + Subsignal("rx", DiffPairs("Y14", "Y15", dir="i")), + ), + + Resource("eth_clk125", 1, Pins("J20", dir="i"), + Clock(125e6), Attrs(IO_TYPE="LVCMOS25")), + Resource("eth_clk125_pll", 1, Pins("C18", dir="i"), + Clock(125e6), Attrs(IO_TYPE="LVCMOS25")), # NC by default + Resource("eth_rgmii", 1, + Subsignal("rst", PinsN("F20", dir="o")), + Subsignal("mdc", Pins("G19", dir="o")), + Subsignal("mdio", Pins("H20", dir="io")), + Subsignal("tx_clk", Pins("C20", dir="o")), + Subsignal("tx_ctrl", Pins("E19", dir="o")), + Subsignal("tx_data", Pins("J17 J16 D19 D20", dir="o")), + Subsignal("rx_clk", Pins("J19", dir="i")), + Subsignal("rx_ctrl", Pins("F19", dir="i")), + Subsignal("rx_data", Pins("G18 G16 H18 H17", dir="i")), + Attrs(IO_TYPE="LVCMOS25") + ), + Resource("eth_sgmii", 1, + Subsignal("rst", PinsN("F20", dir="o"), Attrs(IO_TYPE="LVCMOS25")), + Subsignal("mdc", Pins("G19", dir="o"), Attrs(IO_TYPE="LVCMOS25")), + Subsignal("mdio", Pins("H20", dir="io"), Attrs(IO_TYPE="LVCMOS25")), + Subsignal("tx", DiffPairs("W17", "W18", dir="o")), + Subsignal("rx", DiffPairs("Y16", "Y17", dir="i")), + ), + + Resource("ddr3", 0, + Subsignal("rst", PinsN("N4", dir="o")), + Subsignal("clk", DiffPairs("M4", "N5", dir="o"), Attrs(IO_TYPE="SSTL135D_I")), + Subsignal("clk_en", Pins("N2", dir="o")), + Subsignal("cs", PinsN("K1", dir="o")), + Subsignal("we", PinsN("M1", dir="o")), + Subsignal("ras", PinsN("P1", dir="o")), + Subsignal("cas", PinsN("L1", dir="o")), + Subsignal("a", Pins("P2 C4 E5 F5 B3 F4 B5 E4 C5 E3 D5 B4 C3", dir="o")), + Subsignal("ba", Pins("P5 N3 M3", dir="o")), + Subsignal("dqs", DiffPairs("K2 H4", "J1 G5", dir="io"), Attrs(IO_TYPE="SSTL135D_I", DIFFRESISTOR="100", TERMINATION="OFF")), + Subsignal("dq", Pins("L5 F1 K4 G1 L4 H1 G2 J3 D1 C1 E2 C2 F3 A2 E1 B1", + dir="io")), Attrs(TERMINATION="75"), + Subsignal("dm", Pins("J4 H5", dir="o")), + Subsignal("odt", Pins("L2", dir="o")), + Attrs(IO_TYPE="SSTL135_I", SLEWRATE="FAST") + ) + ] + connectors = [ + Connector("expcon", 1, """ + - - - B19 B12 B9 E6 D6 E7 D7 B11 B6 E9 D9 B8 C8 D8 E8 C7 C6 + - - - - - - - - - - - - - - - - - - - - + """), # X3 + Connector("expcon", 2, """ + A8 - A12 A13 B13 C13 D13 E13 A14 C14 D14 E14 D11 C10 A9 B10 D12 E12 - - + B15 - C15 - D15 - E15 A16 B16 - C16 D16 B17 - C17 A17 B18 A7 A18 - + """), # X4 + ] + + @property + def file_templates(self): + return { + **super().file_templates, + "{{name}}-openocd.cfg": r""" + interface ftdi + {# FTDI descriptors is identical between non-5G and 5G recent Versa boards #} + ftdi_device_desc "Lattice ECP5_5G VERSA Board" + ftdi_vid_pid 0x0403 0x6010 + ftdi_channel 0 + ftdi_layout_init 0xfff8 0xfffb + reset_config none + adapter_khz 25000 + + # ispCLOCK device (unusable with openocd and must be bypassed) + #jtag newtap ispclock tap -irlen 8 -expected-id 0x00191043 + # ECP5 device + {% if "5G" in platform.device -%} + jtag newtap ecp5 tap -irlen 8 -expected-id 0x81112043 ; # LFE5UM5G-45F + {% else -%} + jtag newtap ecp5 tap -irlen 8 -expected-id 0x01112043 ; # LFE5UM-45F + {% endif %} + """ + } + + def toolchain_program(self, products, name): + openocd = os.environ.get("OPENOCD", "openocd") + with products.extract("{}-openocd.cfg".format(name), "{}.svf".format(name)) \ + as (config_filename, vector_filename): + subprocess.check_call([openocd, + "-f", config_filename, + "-c", "transport select jtag; init; svf -quiet {}; exit".format(vector_filename) + ]) + + +if __name__ == "__main__": + from .test.blinky import * + VersaECP5Platform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/versa_ecp5_5g.py b/re-bba/amaranth_boards/versa_ecp5_5g.py new file mode 100644 index 0000000..36e6997 --- /dev/null +++ b/re-bba/amaranth_boards/versa_ecp5_5g.py @@ -0,0 +1,14 @@ +from .versa_ecp5 import VersaECP5Platform + + +__all__ = ["VersaECP55GPlatform"] + + +class VersaECP55GPlatform(VersaECP5Platform): + device = "LFE5UM5G-45F" + # Everything else is identical between 3G and 5G Versa boards. + + +if __name__ == "__main__": + from .test.blinky import * + VersaECP55GPlatform().build(Blinky(), do_program=True) diff --git a/re-bba/amaranth_boards/zturn_lite_z007s.py b/re-bba/amaranth_boards/zturn_lite_z007s.py new file mode 100644 index 0000000..f732f9f --- /dev/null +++ b/re-bba/amaranth_boards/zturn_lite_z007s.py @@ -0,0 +1,76 @@ +from amaranth.build import * +from amaranth.vendor.xilinx_7series import * + + +__all__ = ["ZTurnLiteZ007SPlatform"] + + +class ZTurnLiteZ007SPlatform(Xilinx7SeriesPlatform): + device = "xc7z007s" + package = "clg400" + speed = "1" + resources = [] + connectors = [ + Connector("expansion", 0, + "- - " + "B19 E17 " + "A20 D18 " + "- - " + "E18 D19 " + "E19 D20 " + "G17 F16 " + "G18 F17 " + "- - " + "- - " + "J18 J20 " + "H18 H20 " + "C20 K17 " + "B20 K18 " + "- - " + "G19 K19 " + "G20 J19 " + "F19 H15 " + "F20 G15 " + "- - " + "L16 K14 " + "L17 J14 " + "L19 H16 " + "L20 H17 " + "- - " + "K16 L14 " + "J16 L15 " + "M17 M14 " + "M18 M15 " + "- - " + "N17 P15 " + "P18 P16 " + "M19 N15 " + "M20 N16 " + "- - " + "N18 - " + "P19 R16 " + "N20 R17 " + "P20 T20 " + "- U20 " + "- - " + "T16 V20 " + "U17 W20 " + "U18 T17 " + "U19 R18 " + "- - " + "W18 V17 " + "W19 V18 " + "U14 V16 " + "U15 W16 " + "- - " + "V15 Y18 " + "W15 Y19 " + "Y16 W14 " + "Y17 Y14 " + "- - " + "- - " + "- - " + "- - " + "- - " + ), + ] diff --git a/re-bba/amaranth_boards/zturn_lite_z010.py b/re-bba/amaranth_boards/zturn_lite_z010.py new file mode 100644 index 0000000..d73de1a --- /dev/null +++ b/re-bba/amaranth_boards/zturn_lite_z010.py @@ -0,0 +1,8 @@ +from .zturn_lite_z007s import ZTurnLiteZ007SPlatform + + +__all__ = ["ZTurnLiteZ010Platform"] + + +class ZTurnLiteZ010Platform(ZTurnLiteZ007SPlatform): + device = "xc7z010" diff --git a/re-bba/counter.py b/re-bba/counter.py new file mode 100644 index 0000000..e0b5d57 --- /dev/null +++ b/re-bba/counter.py @@ -0,0 +1,74 @@ +from amaranth import * + +class UpCounter(Elaboratable): + """ + A 16-bit up counter with a fixed limit. + + Parameters + ---------- + limit : int + The value at which the counter overflows. + + Attributes + ---------- + en : Signal, in + The counter is incremented if ``en`` is asserted, and retains + its value otherwise. + ovf : Signal, out + ``ovf`` is asserted when the counter reaches its limit. + """ + def __init__(self, limit): + self.limit = limit + + # Ports + self.en = Signal() + self.ovf = Signal() + + # State + self.count = Signal(16) + + def elaborate(self, platform): + m = Module() + + m.d.comb += self.ovf.eq(self.count == self.limit) + + with m.If(self.en): + with m.If(self.ovf): + m.d.sync += self.count.eq(0) + with m.Else(): + m.d.sync += self.count.eq(self.count + 1) + + return m + +from amaranth.sim import Simulator + +dut = UpCounter(25) +def bench(): + # Disabled counter should not overflow. + yield dut.en.eq(0) + for _ in range(30): + yield + assert not (yield dut.ovf) + + # Once enabled, the counter should overflow in 25 cycles. + yield dut.en.eq(1) + for _ in range(25): + yield + assert not (yield dut.ovf) + yield + assert (yield dut.ovf) + + # The overflow should clear in one cycle. + yield + assert not (yield dut.ovf) + + +sim = Simulator(dut) +sim.add_clock(1e-6) # 1 MHz +sim.add_sync_process(bench) +with sim.write_vcd("up_counter.vcd"): + sim.run() + +from amaranth_boards.icebreaker import * + +ICEBreakerPlatform().build(UpCounter(25), do_program=True) \ No newline at end of file diff --git a/re-bba/shift_register.py b/re-bba/shift_register.py new file mode 100644 index 0000000..e544cff --- /dev/null +++ b/re-bba/shift_register.py @@ -0,0 +1,159 @@ + +import sys +import os +from amaranth import * +from amaranth_boards.icebreaker import * +from amaranth.back import verilog +from amaranth.sim import Simulator + +##### +# Hardware Description. +##### + +class ShiftRegister(Elaboratable): + def __init__(self, width): + self.width = width + + # Ports + self.nen = Signal() + self.inb = Signal() + self.exiClk = Signal() + + # Defines + self.LOW = 0 + self.FALLING = 1 + self.HIGH = 2 + self.RISING = 3 + + # State + self.data = Signal(self.width) + self.prevExiClkValid = Signal() + self.prevExiClk = Signal() + self.prevExiClkState = Signal(2) + self.exiClkState = Signal(2) + + def elaborate(self, platform): + m = Module() + + with m.If(~self.nen): + with m.If(self.prevExiClkValid): + m.d.sync += self.prevExiClkState.eq(self.exiClkState) + with m.If(self.prevExiClk ^ self.exiClk): + m.d.sync += self.exiClkState.eq(Cat(self.exiClk, 1)) + with m.Else(): + m.d.sync += self.exiClkState.eq(Cat(self.exiClk, 0)) + + with m.If((self.exiClkState == self.FALLING).bool() & (self.exiClkState != self.prevExiClkState).bool()): + m.d.sync += self.data.eq(self.data.shift_left(1) | self.inb ) + + m.d.sync += self.prevExiClkValid.eq(1) + m.d.sync += self.prevExiClk.eq(self.exiClk) + with m.Else(): + m.d.sync += self.prevExiClkValid.eq(0) + + return m + +##### +# TestBench +##### +class TestBench: + def __init__(self): + pass + + def simExiClock(self, dut): + yield dut.exiClk.eq(~dut.exiClk) + + def enabled_test(self): + dut = self.dut + + # Disabled ShiftRegister should not Change. + yield dut.nen.eq(1) + for _ in range(10): + yield dut.inb.eq(~dut.inb) + yield from self.simExiClock(dut) + yield from self.simExiClock(dut) + assert not (yield dut.data) + yield + yield + yield + yield from self.simExiClock(dut) + yield from self.simExiClock(dut) + assert not (yield dut.data) + yield + yield + yield + + def normal_operation(self): + dut = self.dut + + def oracle(i): + if i == 0: return 0x01 + if i == 1: return 0x02 + if i == 2: return 0x05 + if i == 3: return 0x0A + if i == 4: return 0x15 + if i == 5: return 0x2A + if i == 6: return 0x55 + if i == 7: return 0xAA + if i == 8: return 0x55 + if i == 9: return 0xAA + + yield dut.nen.eq(0) + for i in range(10): + yield dut.inb.eq(~dut.inb) + yield from self.simExiClock(dut) + yield + yield + yield from self.simExiClock(dut) + yield + yield + assert (yield dut.data) == oracle(i) + + def simulate(self): + self.dut = ShiftRegister(8) + + sim = Simulator(self.dut) + sim.add_clock(1e-6) # 1 MHz + sim.add_sync_process(self.enabled_test) + + with sim.write_vcd(os.path.dirname(os.path.abspath(__file__)) + "/ShiftRegister_enable.vcd"): + sim.run() + + self.dut = ShiftRegister(8) + + sim = Simulator(self.dut) + sim.add_clock(1e-6) # 1 MHz + sim.add_sync_process(self.normal_operation) + + with sim.write_vcd(os.path.dirname(os.path.abspath(__file__)) + "/ShiftRegister_shift.vcd"): + sim.run() + +def main(): + if(len(sys.argv) == 2): + + if sys.argv[1] == "s": + bench = TestBench() + bench.simulate() + + if sys.argv[1] == "v": + mod = ShiftRegister(8) + with open(os.path.dirname(os.path.abspath(__file__)) + "/shift_register.v", "w") as f: + f.write(verilog.convert(mod, ports=[mod.exiClk, mod.inb, mod.data])) + + if sys.argv[1] == "p": + ICEBreakerPlatform().build(ShiftRegister(8), do_program=True) + + else: + bench = TestBench() + bench.simulate() + + +##### +# Main portion +##### + +if __name__ == "__main__": + main() + + +