windowsでiverilog その168

# 概要　
windowsでiverilogやってみた。
自作cpu、見つけたので、調査してみた。
練習問題やってみた。

# 練習問題
elixirでzktcのアセンブラが動くインタープリタを書け。
1から9まで数えよ。

# サンプルコード

```

defmodule Va do
	use Agent
	def start_link() do
		Agent.start_link(fn ->
			0
		end, name: __MODULE__)
	end
	def get() do
		Agent.get(__MODULE__, fn v ->
			v
		end)
	end
	def set(x) do
		Agent.update(__MODULE__, fn v ->
			x
		end)
	end
end

defmodule Src do
	use Agent
	def start_link() do
		Agent.start_link(fn -> 
            ""
		end, name: __MODULE__)
	end
	def set(x) do
		Agent.update(__MODULE__, fn v ->
	        x
		end)
	end
	def get() do
		Agent.get(__MODULE__, fn v ->
			v
		end)
	end
	def getn(n) do
		Agent.get(__MODULE__, fn v ->
	    	Enum.at(String.split(v, "\n", trim: true), n - 1)
	    end)
    end
    def getl("end") do
        0
    end
	def getl(a) do
		Agent.get(__MODULE__, fn v ->
            Enum.reduce(String.split(v, "\n", trim: true), 1, fn l, n ->
	    	    if String.starts_with?(l, a) do
	    	        Va.set(n)
	    	    end
	    	    n = n + 1
	        end)
	        Va.get
	    end)
    end
end

defmodule Sim do
	def start_link do
		Agent.start_link(fn ->
			[x1: 0, x2: 0, x3: 0, x7: 0, pc: 1, stack: [], g: ""]
		end, name: __MODULE__)
	end
    def lil(xd, d) do
		Agent.update(__MODULE__, fn v ->
    		cond do
		    xd == "x1" ->
			    v = List.keyreplace(v, :x1, 0, {:x1, String.to_integer(d)})
    		    pc = v[:pc] + 1
	    	    List.keyreplace(v, :pc, 0, {:pc, pc})
	    	xd == "x2" ->
			    v = List.keyreplace(v, :x2, 0, {:x2, String.to_integer(d)})
    		    pc = v[:pc] + 1
	    	    List.keyreplace(v, :pc, 0, {:pc, pc})
		    xd == "x3" ->
			    v = List.keyreplace(v, :x3, 0, {:x3, String.to_integer(d)})
    		    pc = v[:pc] + 1
	    	    List.keyreplace(v, :pc, 0, {:pc, pc})
		    xd == "x7" ->
			    IO.write(<<String.to_integer(d)>>)    		   
    		    v = List.keyreplace(v, :x7, 0, {:x7, String.to_integer(d)})
    		    pc = v[:pc] + 1
	    	    List.keyreplace(v, :pc, 0, {:pc, pc})
            end
		end)
    end
    def add(xd, xs) do
		Agent.update(__MODULE__, fn v ->
    		cond do
		    xd == "x3" && xs == "x1" ->
    		    vd = v[:x3] + v[:x1]
			    v = List.keyreplace(v, :x3, 0, {:x3, vd})
    		    pc = v[:pc] + 1
	    	    List.keyreplace(v, :pc, 0, {:pc, pc})
	    	end
		end)
    end
    def mov(xd, xs) do
		Agent.update(__MODULE__, fn v ->
    		cond do
		    xd == "x7" && xs == "x3" ->
		        vd = v[:x7]
                vs = v[:x3]
                vd = vs
			    v = List.keyreplace(v, :x7, 0, {:x7, vd})
			    IO.write(<<vd>>)    		   
			    pc = v[:pc] + 1
	    	    List.keyreplace(v, :pc, 0, {:pc, pc})
            end
		end)
    end
    def jal(xd, l) do
		Agent.update(__MODULE__, fn v ->
    		pc = Src.getl(l)
	    	List.keyreplace(v, :pc, 0, {:pc, pc})
		end)
    end
    def addi(xd, xs, i) do
		Agent.update(__MODULE__, fn v ->
    		cond do
	    	xd == "x1" && xs == "x1" ->
                vs = v[:x1]
                vd = vs + String.to_integer(i)
			    v = List.keyreplace(v, :x1, 0, {:x1, vd})
    		    pc = v[:pc] + 1
	    	    List.keyreplace(v, :pc, 0, {:pc, pc})
	    	end
		end)
    end
    def blt(xd, xs, l) do
		Agent.update(__MODULE__, fn v ->
   		    cond do
	    	xd == "x1" && xs == "x2" ->
    		    vd = v[:x1]
                vs = v[:x2]
    	        if (vd > vs) do
    	        	pc = Src.getl(l)
	             	List.keyreplace(v, :pc, 0, {:pc, pc})
    	        else
	        		pc = v[:pc] + 1
    	         	List.keyreplace(v, :pc, 0, {:pc, pc})
	          	end
		    end
		end)
    end
	def pc() do
		Agent.get(__MODULE__, fn v ->
            v[:pc]
        end)
    end
    def test() do
		Agent.get(__MODULE__, fn v ->
            v
        end)
    end
    def up() do
		Agent.update(__MODULE__, fn v ->
			pc = v[:pc] + 1
    		List.keyreplace(v, :pc, 0, {:pc, pc})
		end)
	end 
    def ret() do
		Agent.update(__MODULE__, fn v ->
			pc = 0
    		List.keyreplace(v, :pc, 0, {:pc, pc})
		end)
	end
end

defmodule Main do
    def run(0) do
        IO.puts("ok")
    end
    def run(pc) do
        m = Src.getn(pc)
        #IO.puts(m)
        s = String.split(m, "  ")
        #IO.inspect(s)
        cond do
	    Enum.at(s, 1) == "lil" ->
		    Sim.lil(Enum.at(s, 2), Enum.at(s, 3))
	    Enum.at(s, 1) == "addi" ->
		    Sim.addi(Enum.at(s, 2), Enum.at(s, 3), Enum.at(s, 4))
	    Enum.at(s, 1) == "add" ->
		    Sim.add(Enum.at(s, 2), Enum.at(s, 3))
	    Enum.at(s, 1) == "mov" ->
		    Sim.mov(Enum.at(s, 2), Enum.at(s, 3))
	    Enum.at(s, 1) == "blt" ->
		    Sim.blt(Enum.at(s, 2), Enum.at(s, 3), Enum.at(s, 4))
	    Enum.at(s, 1) == "jal" ->
		    Sim.jal(Enum.at(s, 2), Enum.at(s, 3))
	    Enum.at(s, 1) == "ret" ->
		    Sim.ret()
	    true ->
		    Sim.up
		    #IO.puts(Enum.at(s, 1))
	    end
	    #IO.inspect Sim.test
        run(Sim.pc)
	end
	def start(str) do
	    Src.set(str)
	    run(1)
	end
end

Va.start_link
Sim.start_link
Src.start_link

str = """
  lil  x1  0
  lil  x2  8
loop:
  addi  x1  x1  1
  lil  x3  48
  add  x3  x1
  mov  x7  x3
  lil  x7  10
  blt  x1  x2  bye
  jal  x0  loop
bye:
  ret   
"""

Main.start(str)






```
# 投入したソース

```
  lil  x1  0
  lil  x2  8
loop:
  addi  x1  x1  1
  lil  x3  48
  add  x3  x1
  mov  x7  x3
  lil  x7  10
  blt  x1  x2  bye
  jal  x0  loop
bye:
  ret   

```

# 実行結果

```
1
2
3
4
5
6
7
8
9
ok
```

# 成果物

https://paiza.io/projects/0g_eovCIPRrCHlOfx7kzJA

以上。