0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

windowsでiverilog その168

Posted at

概要 

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

成果物

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?