windowsでiverilog その167

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

# 練習問題
elixirでzktcのアセンブラが動くインタープリタを書け。

# 方針
- x7レジスタを仮想コンソールとする。


# サンプルコード

```

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 val(s) do
        if String.starts_with?(s, "'") do
            String.at(s, 1)
            |> String.to_charlist
            |> List.first
        else
            String.to_integer(s)
        end
    end
	def start_link do
		Agent.start_link(fn ->
			[x1: 0, x2: 0, x7: 0, pc: 1, stack: [], g: ""]
		end, name: __MODULE__)
	end
	def push(s) do
		Agent.update(__MODULE__, fn v ->
    	    n = val(s)
		    stack = v[:stack]
			stack = Enum.concat(stack, [n])
			v = List.keyreplace(v, :stack, 0, {:stack, stack})
			pc = v[:pc] + 1
			List.keyreplace(v, :pc, 0, {:pc, pc})
		end)
	end
    def set(x, d) do
		Agent.update(__MODULE__, fn v ->
			cond do
			x == "x1" ->
    			v = List.keyreplace(v, :x1, 0, {:x1, d})
	    		pc = v[:pc] + 1
		    	List.keyreplace(v, :pc, 0, {:pc, pc})
			x == "x7" ->
    			v = List.keyreplace(v, :x7, 0, {:x7, d})
    			IO.write(<<String.to_integer(d)>>)
	    		pc = v[:pc] + 1
		    	List.keyreplace(v, :pc, 0, {:pc, pc})
			end
		end)
    end
    def jmp(t) do
		Agent.update(__MODULE__, fn v ->
		    pc = Src.getl(t)
    		List.keyreplace(v, :pc, 0, {:pc, pc})
		end)
	end
    def drop() do
		Agent.update(__MODULE__, fn v ->
		    stack = v[:stack]
		    stack = Enum.drop(stack, -1) 
			v = List.keyreplace(v, :stack, 0, {:stack, stack})
		    pc = v[:pc] + 1
		    List.keyreplace(v, :pc, 0, {:pc, pc})
		end)
    end
    def pushs(s) do
		Agent.update(__MODULE__, fn v ->
		    stack = v[:stack]
		    g = s
            v = List.keyreplace(v, :g, 0, {:g, g})
		    pc = v[:pc] + 1
		    List.keyreplace(v, :pc, 0, {:pc, pc})
		end)
    end
	def print() do
		Agent.update(__MODULE__, fn v ->
            g = v[:g]
            IO.puts g
			pc = v[:pc] + 1
    		List.keyreplace(v, :pc, 0, {:pc, pc})
        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.set(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  x7  104
  lil  x7  101
  lil  x7  108
  lil  x7  108
  lil  x7  111
  lil  x7  32
bye:
  ret   
"""

Main.start(str)





```

# 実行結果

```
hello ok
```

# 投入したソース

```
  lil  x7  104
  lil  x7  101
  lil  x7  108
  lil  x7  108
  lil  x7  111
  lil  x7  32
bye:
  ret   

```

# 成果物

https://paiza.io/projects/vWIUlHzVS1-yYW9qMUhxoA


以上。