1
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?

paiza.ioでelixirAdvent Calendar 2022

Day 17

paiza.ioでelixir その117

Last updated at Posted at 2022-12-04

概要

paiza.ioでelixirやってみた。
FPGAの高位合成書いてみた。
練習問題やってみた。

練習問題

zundokoを書け。

サンプルコード

10 a=0
20 b=234
30 b=b*5
40 b=b+1
50 #=b<120*100
60 ?="zun"
70 a=a+1
80 #=a>3*130
90 #=30
100 ?="doko"
110 a=0
120 #=30
130 ?="doko" 
140 ?="kiyosi!!"
150 #=150

実行結果

module ore(input clk, input rst, output reg [7:0] out);
    reg [7:0] a;
    reg [7:0] b;
    reg [7:0] pc;
    always @(posedge clk)
    begin
        if (!rst)
        begin
            a <= 0;
            b <= 0;
            pc <= 10;
        end
        else
        begin
            case(pc)
            10:
            begin
                a <= 0;
                pc <= 20;
            end
            20:
            begin
                b <= 234;
                pc <= 30;
            end
            30:
            begin
                b <= b*5;
                pc <= 40;
            end
            40:
            begin
                b <= b+1;
                pc <= 50;
            end
            50:
            begin
                if (b<120)
                    pc <= 100;
                else
                    pc <= 60;
            end
            60:
            begin
                out <= "z";
                pc <= 61;
            end
            61:
            begin
                out <= "u";
                pc <= 62;
            end
            62:
            begin
                out <= "n";
                pc <= 63;
            end
            63:
            begin
                out <= " ";
                pc <= 70;
            end
            70:
            begin
                a <= a+1;
                pc <= 80;
            end
            80:
            begin
                if (a>3)
                    pc <= 130;
                else
                    pc <= 90;
            end
            90:
            begin
                pc <= 30;
            end
            100:
            begin
                out <= "d";
                pc <= 101;
            end
            101:
            begin
                out <= "o";
                pc <= 102;
            end
            102:
            begin
                out <= "k";
                pc <= 103;
            end
            103:
            begin
                out <= "o";
                pc <= 104;
            end
            104:
            begin
                out <= " ";
                pc <= 110;
            end
            110:
            begin
                a <= 0;
                pc <= 120;
            end
            120:
            begin
                pc <= 30;
            end
            130:
            begin
                out <= "d";
                pc <= 131;
            end
            131:
            begin
                out <= "o";
                pc <= 132;
            end
            132:
            begin
                out <= "k";
                pc <= 133;
            end
            133:
            begin
                out <= "o";
                pc <= 134;
            end
            134:
            begin
                out <= " ";
                pc <= 140;
            end
            140:
            begin
                out <= "k";
                pc <= 141;
            end
            141:
            begin
                out <= "i";
                pc <= 142;
            end
            142:
            begin
                out <= "y";
                pc <= 143;
            end
            143:
            begin
                out <= "o";
                pc <= 144;
            end
            144:
            begin
                out <= "s";
                pc <= 145;
            end
            145:
            begin
                out <= "i";
                pc <= 146;
            end
            146:
            begin
                out <= "!";
                pc <= 147;
            end
            147:
            begin
                out <= "!";
                pc <= 148;
            end
            148:
            begin
                out <= " ";
                pc <= 150;
            end
            150:
            begin
                pc <= 150;
            end
            endcase
        end
    end
    initial
    begin
        $monitor(" %d  %s", pc, out);
    end
endmodule

module test;
    reg clk,
        rst;
    wire [7:0] out;
    ore u(.clk(clk), .rst(rst), .out(out));
    initial
    begin
        clk = 0;
        rst = 1;
    #2
        rst = 0;
    #2
        rst = 1;
    #2700
        $finish;
    end
    always
    #1
        clk = ~clk;
endmodule

シミュレーション結果

>vvp a.out
   x
  10
  20
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
 100
 101  d
 102  o
 103  k
 104  o
 110
 120
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
  90
  30
  40
  50
  60
  61  z
  62  u
  63  n
  70
  80
 130
 131  d
 132  o
 133  k
 134  o
 140
 141  k
 142  i
 143  y
 144  o
 145  s
 146  i
 147  !
 148  !
 150

サンプルコード


defmodule Asm do
	def start_link do
		Agent.start_link(fn ->
			%{u: ""}
		end, name: __MODULE__)
	end
    def a(a, b) do
		Agent.update(__MODULE__, fn v ->
		    c = String.to_integer(a) + 10
			str = "            " <> a <> ":\n" <>
			    "            begin\n" <>
			    "                a <= " <> b <> ";\n" <>
			    "                pc <= #{c};\n" <>
			    "            end\n"
			%{v | u: v.u <> str}
		end)
    end
    def b(a, b) do
		Agent.update(__MODULE__, fn v ->
		    c = String.to_integer(a) + 10
			str = "            " <> a <> ":\n" <>
			    "            begin\n" <>
			    "                b <= " <> b <> ";\n" <>
			    "                pc <= #{c};\n" <>
			    "            end\n"
			%{v | u: v.u <> str}
		end)
    end
    def print(a, b) do
		Agent.update(__MODULE__, fn v ->
            c = String.to_integer(a)
			if String.match?(b, ~r/\"/) do
			    b = String.replace(b, "\"", "")
		        s = String.split(b, "", trim: true)
                l = String.length(b)
			    str = Enum.reduce(s, ["", c], fn x, y ->
			        pc = Enum.at(y, 1)
			        str = Enum.at(y, 0) <> 
			            "            #{pc}:\n" <>
			            "            begin\n" <>
                        "                out <= \"#{x}\";\n" <>
                        "                pc <= #{pc + 1};\n" <>
                        "            end\n"
                    pc = pc + 1
                    [str, pc]
			    end)
			    str = Enum.at(str, 0) <>
    			    "            #{c + l}:\n" <>
		            "            begin\n" <>
                    "                out <= \" \";\n" <>
                    "                pc <= #{c + 10};\n" <>
                    "            end\n"
			    %{v | u: v.u <> str}
			else
			    str = "            #{c}:\n" <>
			    "            begin\n" <>
                "                out <= a / 10 + 48;\n" <>
                "                pc <= #{c + 1};\n" <>
                "            end\n" <>
                "            #{c + 1}:\n" <>
                "            begin\n" <>
                "                out <= a % 10 + 48;\n" <>
                "                pc <= #{c + 2};\n" <>
                "            end\n" <>
                "            #{c + 2}:\n" <>
                "            begin\n" <>
                "                out <= 32;\n" <>
                "                pc <= #{c + 10};\n" <>
                "            end\n"
                %{v | u: v.u <> str}
			end
		end)
    end
    def loop(a, b) do
		Agent.update(__MODULE__, fn v ->
		    c = String.to_integer(a) + 10
			if String.match?(b, ~r/\*/) do
			    b = String.replace(b, "@", "==")
		        s = String.split(b, "*")
			    str = "            " <> a <> ":\n" <>
			    "            begin\n" <>
			    "                if (" <> Enum.at(s, 0) <> ")\n" <>
			    "                    pc <= " <> Enum.at(s, 1) <> ";\n" <>
			    "                else\n" <>
                "                    pc <= #{c};\n" <>
			    "            end\n"
			    %{v | u: v.u <> str}
		    else
		        str = "            " <> a <> ":\n" <>
		        "            begin\n" <>
		        "                pc <= " <> b <> ";\n" <>
		        "            end\n"
		        %{v | u: v.u <> str}
		    end
		end)
    end
    def make() do
		Agent.get(__MODULE__, fn v ->
            IO.puts "module ore(input clk, input rst, output reg [7:0] out);\n" <>
	        "    reg [7:0] a;\n" <>
	        "    reg [7:0] b;\n" <>
	        "    reg [7:0] pc;\n" <>
	        "    always @(posedge clk)\n" <>
	        "    begin\n" <>
		    "        if (!rst)\n" <>
		    "        begin\n" <>
			"            a <= 0;\n" <>
			"            b <= 0;\n" <>
			"            pc <= 10;\n" <>
		    "        end\n" <>
		    "        else\n" <>
	        "        begin\n" <>
		    "            case(pc)\n" <>
		    v.u <>
		    "            endcase\n" <>
	        "        end\n" <>
	        "    end\n" <>
	        "    initial\n" <>
	        "    begin\n" <>
		    "        $monitor(\" %d  %s\", pc, out);\n" <>
	        "    end\n" <>
		    "endmodule\n\n" <>
            "module test;\n" <>
	        "    reg clk,\n" <>
		    "        rst;\n" <>
	        "    wire [7:0] out;\n" <>
	        "    ore u(.clk(clk), .rst(rst), .out(out));\n" <>
	        "    initial\n" <>
	        "    begin\n" <>
		    "        clk = 0;\n" <>
		    "        rst = 1;\n" <>	
		    "    #2\n" <>
			"        rst = 0;\n" <>
		    "    #2\n" <>
		    "        rst = 1;\n" <>
		    "    #2700\n" <>
			"        $finish;\n" <>
	        "    end\n" <>
	        "    always\n" <>
		    "    #1\n" <>
			"        clk = ~clk;\n" <>
            "endmodule\n"
		end)
	end
end

defmodule Main do
	def run(str) do
	    str = String.replace(str, "=", " ")
    	Enum.map(String.split(str, "\n"), fn l ->
		    s = String.split(l, " ")
		    cond do
			Enum.at(s, 1) == "?" ->
				Asm.print(Enum.at(s, 0), Enum.at(s, 2))
			Enum.at(s, 1) == "#" ->
				Asm.loop(Enum.at(s, 0), Enum.at(s, 2))
			Enum.at(s, 1) == "a" ->
				Asm.a(Enum.at(s, 0), Enum.at(s, 2))
			Enum.at(s, 1) == "b" ->
				Asm.b(Enum.at(s, 0), Enum.at(s, 2))
			true ->
				IO.puts ""
			end
	    end)
	    Asm.make
	end
end

Asm.start_link

Main.run("""
10 a=0
20 b=234
30 b=b*5
40 b=b+1
50 #=b<120*100
60 ?="zun"
70 a=a+1
80 #=a>3*130
90 #=30
100 ?="doko"
110 a=0
120 #=30
130 ?="doko" 
140 ?="kiyosi!!"
150 #=150
""")




成果物

以上。

1
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
1
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?