Created
October 20, 2023 09:32
-
-
Save Alikberov/8fa3d04ab4851cd83ff1b72a662d2f98 to your computer and use it in GitHub Desktop.
Chip Designer (for Logisim)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Logisim Part Design Generator</title> | |
<script> | |
var hDesigner; | |
var hDesign; | |
var hModel; | |
function draw() { | |
const ctx = hDesign; | |
const dsg = hDesigner.value.split(/\r?\n/); | |
// | |
var model = []; | |
// | |
let fnt = { | |
PIDS :"9px Serif", | |
PINS :"7px Serif" | |
}; | |
let part = ""; | |
let mode; | |
let i; | |
let y = 0; | |
let maxy = 0; | |
let space; | |
let measure; | |
// | |
function setPin(font, anchor, x, y, text, circle) { | |
model.push(' <text font-family="' + font.split(" ")[1] + '" font-size="' + parseInt(font) + '" text-anchor="' + anchor + '" x="' + x + '" y="' + y + '">' + text + '</text>'); | |
if(circle < 0 || circle > 0) { | |
model.push(' <ellipse cx="' + x + '" cy="' + (y - 3) + '" fill="none" rx="3.0" ry="3.0" stroke="#000000" stroke-width="2"/>'); | |
model.push(' <polyline fill="none" points="' + x + ',' + (y - 8) + ',' + (x + 24 * circle) + ',' + (y - 8) +'" stroke="#000000" stroke-width="1"/>'); | |
} | |
} | |
// | |
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); | |
for(const str of dsg) { | |
const rex = /([-.]|(\d+)([:;]\d+)*(_?)([A-Z]+)?(\d+)?(:(\d+))?(["']?))/ig; | |
const rxp = /[-.]|(\d+)(([:;]\d+)+)?(_?)([A-Z]+)((\d+)?(:\d+)?)(["']?)/i; | |
const dsc = (/(\w+)?\t*(.+)?/i).exec(str); | |
var data; | |
var last; | |
var order; | |
var names; | |
var pin; | |
if(dsc[1] != "") | |
mode = dsc[1], | |
y = 20; | |
if(mode in fnt) | |
fnt[mode] = dsc[2]; | |
else | |
if(dsc[2]) { | |
for(const pin of dsc[2].match(rex)) { | |
if(pin) { | |
if(pin == "-") { | |
y += 10; | |
ctx.beginPath(); | |
switch(mode) { | |
case "PINPUT": | |
ctx.moveTo(19, y); | |
ctx.lineTo(49, y); | |
model.push(``); | |
break; | |
case "PINOUT": | |
ctx.moveTo(122, y); | |
ctx.lineTo(92, y); | |
break; | |
} | |
ctx.stroke(); | |
} else | |
if(pin != ".") { | |
data = pin.match(rxp); | |
if(data) { | |
last = parseInt(data[1]); | |
order = [last]; | |
if(data[2]) { | |
for(const col of data[2].match(/[:;]\d+/g)) { | |
const next = parseInt(col.substr(1)); | |
if(col.charAt(0) == ";") | |
order.push(last = next); | |
else | |
if(last < next) | |
while(last < next) | |
order.push(++ last); | |
else | |
while(last > next) | |
order.push(-- last); | |
} | |
} | |
last = parseInt(data[6]); | |
names = [last]; | |
if(data[8]) { | |
for(const col of data[8].match(/[:;]\d+/g)) { | |
const next = parseInt(col.substr(1)); | |
if(col.charAt(0) == ";") | |
names.push(last = next); | |
else | |
if(last < next) | |
while(last < next) | |
names.push(++ last); | |
else | |
while(last > next) | |
names.push(-- last); | |
} | |
} else | |
names = [data[6]]; | |
} | |
if(data) | |
space = data[9] == '"' ? 30 : data[9] == "'" ? 20 : 10; | |
else | |
space = 10; | |
switch(mode) { | |
case "PART": | |
part = dsc[2].split(/\t+|\s+/); | |
break; | |
case "PINPUT": | |
ctx.beginPath(); | |
i = 0; | |
ctx.font = fnt.PINS; | |
ctx.textAlign = "right"; | |
for(const id of order) { | |
setPin(fnt.PINS, "end", 19 ,y + space * i + 8, id); | |
ctx.strokeText(id, 19, y + space * i ++ + 8); | |
} | |
i = 0; | |
ctx.font = fnt.PIDS; | |
ctx.textAlign = "left"; | |
for(const id of names) { | |
if(data[4] == "_") { | |
ctx.ellipse(19, y + space * i + 10, 2, 2, 0, 0, 2 * Math.PI, true); | |
measure = ctx.measureText(data[5] + id); | |
ctx.moveTo(22, y + space * i + 5); | |
ctx.lineTo(22 + measure.width, y + space * i + 5); | |
} | |
setPin(fnt.PIDS, "start", 22, y + space * i + 13, data[5] + id, data[4] ? +1 : 0); | |
ctx.strokeText(data[5] + id, 22, y + space * i + 13); | |
++ i; | |
} | |
ctx.stroke(); | |
y += space * (i - 1) + 10; | |
break; | |
case "PINOUT": | |
data = pin.match(rxp); | |
ctx.beginPath(); | |
i = 0; | |
ctx.font = fnt.PINS; | |
ctx.textAlign = "left"; | |
for(const id of order) { | |
setPin(fnt.PINS, "start", 122 ,y + space * i + 8, id); | |
ctx.strokeText(id, 122, y + space * i ++ + 8); | |
} | |
i = 0; | |
ctx.font = fnt.PIDS; | |
ctx.textAlign = "right"; | |
for(const id of names) { | |
if(data[4] == "_") { | |
ctx.ellipse(122, y + space * i + 10, 2, 2, 0, 0, 2 * Math.PI, true); | |
measure = ctx.measureText(data[5] + id); | |
ctx.moveTo(122, y + space * i + 5); | |
ctx.lineTo(122 - measure.width, y + space * i + 5); | |
} | |
setPin(fnt.PIDS, "end", 119, y + space * i + 13, data[5] + id, data[4] ? -1 : 0); | |
ctx.strokeText(data[5] + id, 119, y + space * i ++ + 13); | |
} | |
ctx.stroke(); | |
y += space * (i - 1) + 10; | |
break; | |
} | |
} else | |
y += 10; | |
} else | |
y += 10; | |
} | |
} | |
maxy = Math.max(maxy, y); | |
} | |
ctx.beginPath(); | |
ctx.rect(19, 10, 103, maxy); | |
ctx.moveTo(49, 10); | |
ctx.lineTo(49, 10 + maxy); | |
ctx.moveTo(92, 10); | |
ctx.lineTo(92, 10 + maxy); | |
ctx.textAlign = "center"; | |
ctx.strokeText(part[1], 70, 20); | |
ctx.strokeText(part[2], 70, maxy); | |
ctx.stroke(); | |
setPin(fnt.PIDS, "center", 70, 20, part[1]); | |
setPin(fnt.PIDS, "center", 70, maxy, part[2]); | |
hModel.value = model.join("\r\n"); | |
} | |
function main() { | |
hModel = document.getElementById("Model"); | |
hDesigner = document.getElementById("Designer"); | |
hDesigner.addEventListener("keyup", draw); | |
hDesign = document.getElementById("Design").getContext("2d"); | |
draw(); | |
} | |
</script> | |
<style> | |
body { | |
background-color:silver; | |
} | |
</style> | |
</head> | |
<body> | |
<textarea id=Designer rows=6 cols=120 onkeyup='draw()'> | |
PINS 7px Serif | |
PIDS 9px Serif | |
PART I8257 DMA ВТ57 | |
PINPUT 7HLDA..-.12CLK.-.6RDY.-.13RES..-19:16DRQ0:3'-.11_CS | |
PINOUT 10HRQ-4_MEMR 2_IOWR 1_IORD-32:35;37:40A0:7-30:26;23:21D0:7-8STB 9AEN-14_DAC2 | |
</textarea><br /> | |
<canvas id=Design width=300 height=400></canvas><br> | |
<textarea id=Model rows=6 cols=120></textarea> | |
<script>main();</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment