高位合成言語Polyphony (windowsでiverilog その13）

#概要

windowsでiverilogやってみた。
polyphony、やってみた。
mipsやってみた。

#サンプルコード


```
from polyphony import testbench
from polyphony import module, is_worker_running
from polyphony import rule
from polyphony.typing import int32, int64
from polyphony.io import Port, Queue
from polyphony import unroll

R = 0
ADDU = 33
SUBU = 35
MULT = 24
MULTU = 25
MFHI = 16
MFLO = 18
AND = 36
OR = 37
XOR = 38
SLL = 0
SRL = 2
SLLV = 4
SRLV = 6
SLT = 42
SLTU = 43
JR = 8
J = 2
JAL = 3
ADDIU = 9
ANDI = 12
ORI = 13
XORI = 14
LW = 35
SW = 43
LUI = 15
BEQ = 4
BNE = 5
BGEZ = 1
SLTI = 10
SLTIU = 11

imem = [
	0x3402000a,
	# ori $2, $0, 10
	0x0000000c,
	# syscall 10 (exit)
]

@module
class MIPS:
	def __init__(self):
		self.run = Port(bool, 'in', protocol='ready_valid')
		self.result = Port(int, 'out', protocol='ready_valid')
		self.din = Queue(int32, 'in')
		self.dout = Queue(int32, 'out')
		self.append_worker(self.mips_main)
	def IADDR(self, x):
		return ((x & 0x000000ff) >> 2)
	def DADDR(self, x):
		return ((x & 0x000000ff) >> 2)
	def mips_main(self):
		inputs = [0] * 8
		for i in range(len(inputs)):
			inputs[i] = self.din()
		dmem = [0] * 64
		for i in range(8):
			dmem[i] = inputs[i]
		hilo:int64 = 0
		Hi = 0
		Lo = 0
		n_inst = 0
		reg = [0] * 32
		reg[29] = 0x7fffeffc
		pc = 0x00400000
		self.run()
		while is_worker_running():
			with rule(scheduling='pipeline'):
				while pc != 0:
					iaddr = self.IADDR(pc)
					ins = imem[iaddr]
					pc = pc + 4
					print(pc)
					op = (ins >> 26) & 0x3f
					if op == R:
						funct = ins & 0x3f
						shamt = (ins >> 6) & 0x1f
						rd = (ins >> 11) & 0x1f
						rt = (ins >> 16) & 0x1f
						rs = (ins >> 21) & 0x1f
						if funct == ADDU:
							reg[rd] = reg[rs] + reg[rt]
						elif funct == SUBU:
							reg[rd] = reg[rs] - reg[rt]
						elif funct == MULT:
							hilo = reg[rs] * reg[rt]
							Lo = hilo & 0x00000000ffffffff
							Hi = (hilo >> 32) & 0xffffffff
						elif funct == MULTU:
							hilo = reg[rs] * reg[rt]
							Lo = hilo & 0x00000000ffffffff
							Hi = (hilo >> 32) & 0xffffffff
						elif funct == MFHI:
							reg[rd] = Hi
						elif funct == MFLO:
							reg[rd] = Lo
						elif funct == AND:
							reg[rd] = reg[rs] & reg[rt]
						elif funct == OR:
							reg[rd] = reg[rs] | reg[rt]
						elif funct == XOR:
							reg[rd] = reg[rs] ^ reg[rt]
						elif funct == SLL:
							reg[rd] = reg[rt] << shamt
						elif funct == SRL:
							reg[rd] = reg[rt] >> shamt
						elif funct == SLLV:
							reg[rd] = reg[rt] << reg[rs]
						elif funct == SRLV:
							reg[rd] = reg[rt] >> reg[rs]
						elif funct == SLT:
							reg[rd] = reg[rs] < reg[rt]
						elif funct == SLTU:
							reg[rd] = reg[rs] < reg[rt]
						elif funct == JR:
							pc = reg[rs]
						else:
							pc = 0
					elif op == J:
						tgtadr = ins & 0x3ffffff
						pc = tgtadr << 2
					elif op == JAL:
						tgtadr = ins & 0x3ffffff
						reg[31] = pc
						pc = tgtadr << 2
					else:
						address = ins & 0xffff
						rt = (ins >> 16) & 0x1f
						rs = (ins >> 21) & 0x1f
						if op == ADDIU:
							reg[rt] = reg[rs] + address
						elif op == ANDI:
							reg[rt] = reg[rs] & address
						elif op == ORI:
							reg[rt] = reg[rs] | address
						elif op == XORI:
							reg[rt] = reg[rs] ^ address
						elif op == LW:
							reg[rt] = dmem[self.DADDR(reg[rs] + address)]
						elif op == SW:
							dmem[self.DADDR(reg[rs] + address)] = reg[rt]
						elif op == LUI:
							reg[rt] = address << 16
						elif op == BEQ:
							if reg[rs] == reg[rt]:
								pc = pc - 4 + (address << 2)
						elif op == BNE:
							if reg[rs] != reg[rt]:
								pc = pc - 4 + (address << 2)
						elif op == BGEZ:
							if reg[rs] >= 0:
								pc = pc - 4 + (address << 2)
						elif op == SLTI:
							reg[rt] = reg[rs] < address
						elif op == SLTIU:
							reg[rt] = reg[rs] < address
						else:
							pc = 0
					reg[0] = 0
					n_inst = n_inst + 1
			self.result(n_inst)
			for i in range(len(dmem)):
				self.dout(dmem[i])
			self.run()

@testbench
def test(m):
	inputs = [8, 7, 6, 5, 4, 3, 2, 1]
	for d in inputs:
		m.din(d)
	m.run(True)
	m.result()
	for j in range(8):
		d = m.dout()
		print(d)

m = MIPS()

test(m)




```

#python実行結果


```
4194308
4194312
8
7
6
5
4
3
2
1

```

#iverilog実行結果


```

4194308
4194312
8
7
6
5
4
3
2
1
 5680:finish


```

以上。