windowsでiverilog その161

# 概要　
windowsでiverilogやってみた。
cpu見つけたので、勝手にマシン語、作ってみた。
アセンブラ書いてみた。

# 参考にしたページ
https://qiita.com/KajizukaTaichi/items/2da92161db1355466b5c

# サンプルコード

```

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

```

# 成果物

https://plnkr.co/edit/zilWeYBmFJVqJKPG?preview

以上。