概要
windowsでiverilogやってみた。
cpu見つけたので、勝手にマシン語、作ってみた。
アセンブラ書いてみた。
サンプルコード
var src = document.getElementById('src');
var out = document.getElementById('out');
var la = [];
function opcode4(a) {
var res;
switch (a)
{
case "0000":
res = "0";
break;
case "0001":
res = "1";
break;
case "0010":
res = "2";
break;
case "0011":
res = "3";
break;
case "0100":
res = "4";
break;
case "0101":
res = "5";
break;
case "0110":
res = "6";
break;
case "0111":
res = "7";
break;
case "1000":
res = "8";
break;
case "1001":
res = "9";
break;
case "1010":
res = "A";
break;
case "1011":
res = "B";
break;
case "1100":
res = "C";
break;
case "1101":
res = "D";
break;
case "1110":
res = "E";
break;
case "1111":
res = "F";
break;
}
return res;
};
function opcode(s) {
var res;
res = opcode4(s.substring(0, 4)) + opcode4(s.substring(4, 8));
return res;
}
function reg(a) {
//alert(a);
var res;
switch (a)
{
case "pc":
res = "000";
break;
case "ar":
res = "001";
break;
case "dr":
res = "010";
break;
case "cr":
res = "011";
break;
case "ba":
res = "100";
break;
case "sp":
res = "101";
break;
case "va":
res = "110";
break;
}
//alert(res);
return res;
};
function parsef64(num) {
const view = new DataView(new ArrayBuffer(8));
view.setFloat64(0, num, true);
const bin = view.getBigInt64(0, true) & ((1n << 64n) - 1n);
const sign = bin >> 63n;
const exp = (bin >> 52n) & 0x7ffn;
const man = bin & 0xfffffffffffffn;
const xman = (exp ? (1n << 52n) : 0n) | man;
return {num, bin, sign, exp, man, xman}
}
function toString(number, width, base) {
return ('0'.repeat(width) + number.toString(base)).slice(-width);
}
function oprand(num) {
var res = "";
var f64i = parsef64(num);
//res = f64i.num;
const hex = toString(f64i.bin, 16, 16);
res = hex;
return res;
}
function lfind(label) {
//alert(label);
var res = "";
var i = la[label];
var f64i = parsef64(i);
//res = f64i.bin;
const hex = toString(f64i.bin, 16, 16);
res = hex;
//alert(res);
return res;
}
function run() {
var str = src.value;
var codes = str.split("\n");
var len = codes.length - 1;
for (var i = 0; i < len; i++)
{
var cm = codes[i].split(" ");
if (cm[0] != "")
{
la[cm[0]] = i;
}
}
for (var i = 0; i < len; i++)
{
out.value += "// " + codes[i] + "\n";
var cm = codes[i].split(" ");
switch (cm[1])
{
case "psh":
if (cm[2] == "cr")
out.value += "\trom[" + i + "] <= 72'" + opcode("11011" + "000") + "0000000000000000\n";
else
out.value += "\trom[" + i + "] <= 72'" + opcode("11001" + "000") + oprand(cm[2]) + "\n";
break;
case "pop":
out.value += "\trom[" + i + "] <= 72'" + opcode("11011" + reg(cm[2])) + "0000000000000000\n";
break;
case "mov":
if (cm[2] == "sp")
out.value += "\trom[" + i + "] <= 72'" + opcode("01001" + reg(cm[2])) + "0000000000000000\n";
else
out.value += "\trom[" + i + "] <= 72'" + opcode("00001" + reg(cm[2])) + oprand(cm[3]) + "\n";
break;
case "add":
out.value += "\trom[" + i + "] <= 72'" + opcode("00000" + reg(cm[2])) + "0000000000000000\n";
break;
case "sta":
out.value += "\trom[" + i + "] <= 72'" + opcode("11000" + reg(cm[2])) + "0000000000000000\n";
break;
case "nor":
out.value += "\trom[" + i + "] <= 72'" + opcode("01000" + reg(cm[2])) + "0000000000000000\n";
break;
case "jmp":
if (cm[2] == "1")
out.value += "\trom[" + i + "] <= 72'" + opcode("11001" + "001") + lfind(cm[3]) + "\n";
else
out.value += "\trom[" + i + "] <= 72'" + opcode("11001" + "011") + lfind(cm[3]) + "\n";
break;
case "cal":
out.value += "\trom[" + i + "] <= 72'" + opcode("10001" + "000") + lfind(cm[2]) + "\n";
break;
case "hlt":
out.value += "\trom[" + i + "] <= 72'" + "00" + "0000000000000000\n";
break;
case "ret":
out.value += "\trom[" + i + "] <= 72'" + "00" + "0000000000000000\n";
break;
}
}
}
投入したソース
main psh 5
psh 8
psh 2
cal sum
pop ar
mov ba 8
sta ba ar
mov va ar
hlt
sum mov ar 0
loop_start mov cr sp
nor cr cr
jmp cr loop_end
loop_body pop dr
add ar dr
jmp 1 loop_start
loop_end psh ar
ret
生成したマシン語
// main psh 5
rom[0] <= 72'C84014000000000000
// psh 8
rom[1] <= 72'C84020000000000000
// psh 2
rom[2] <= 72'C84000000000000000
// cal sum
rom[3] <= 72'884022000000000000
// pop ar
rom[4] <= 72'D90000000000000000
// mov ba 8
rom[5] <= 72'0C4020000000000000
// sta ba ar
rom[6] <= 72'C40000000000000000
// mov va ar
rom[7] <= 72'0E7ff8000000000000
// hlt
rom[8] <= 72'000000000000000000
// sum mov ar 0
rom[9] <= 72'090000000000000000
// loop_start mov cr sp
rom[10] <= 72'0B7ff8000000000000
// nor cr cr
rom[11] <= 72'430000000000000000
// jmp cr loop_end
rom[12] <= 72'CB4030000000000000
// loop_body pop dr
rom[13] <= 72'DA0000000000000000
// add ar dr
rom[14] <= 72'010000000000000000
// jmp 1 loop_start
rom[15] <= 72'C94024000000000000
// loop_end psh ar
rom[16] <= 72'C87ff8000000000000
// ret
rom[17] <= 72'000000000000000000
成果物
以上。