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?

More than 1 year has passed since last update.

paiza.ioでelixirAdvent Calendar 2022

Day 16

paiza.ioでelixir その116

Last updated at Posted at 2022-12-04

概要

paiza.ioでelixirやってみた。
FPGAの高位合成書いてみた。
俺言語で書いたfizzbuzzをコンパイルしてみた。

高位合成て何

FPGAを記述する、HDL言語を生成するコンパイラ
下のコードから下の下のコードを生成する。

10 a=0
20 a=a+1
30 #=a>100*180
40 b=a%15
50 #=b@0*120
60 b=a%5
70 #=b@0*140
80 b=a%3
90 #=b@0*160
100 ?=a
110 #=20
120 ?="fizzbuzz"
130 #=20
140 ?="buzz"
150 #=20
160 ?="fizz"
170 #=20
180 #=180
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
                a <= a+1;
                pc <= 30;
            end
            30:
            begin
                if (a>100)
                    pc <= 180;
                else
                    pc <= 40;
            end
            40:
            begin
                b <= a%15;
                pc <= 50;
            end
            50:
            begin
                if (b==0)
                    pc <= 120;
                else
                    pc <= 60;
            end
            60:
            begin
                b <= a%5;
                pc <= 70;
            end
            70:
            begin
                if (b==0)
                    pc <= 140;
                else
                    pc <= 80;
            end
            80:
            begin
                b <= a%3;
                pc <= 90;
            end
            90:
            begin
                if (b==0)
                    pc <= 160;
                else
                    pc <= 100;
            end
            100:
            begin
                out <= a / 10 + 48;
                pc <= 101;
            end
            101:
            begin
                out <= a % 10 + 48;
                pc <= 102;
            end
            102:
            begin
                out <= 32;
                pc <= 110;
            end
            110:
            begin
                pc <= 20;
            end
            120:
            begin
                out <= "f";
                pc <= 121;
            end
            121:
            begin
                out <= "i";
                pc <= 122;
            end
            122:
            begin
                out <= "z";
                pc <= 123;
            end
            123:
            begin
                out <= "z";
                pc <= 124;
            end
            124:
            begin
                out <= "b";
                pc <= 125;
            end
            125:
            begin
                out <= "u";
                pc <= 126;
            end
            126:
            begin
                out <= "z";
                pc <= 127;
            end
            127:
            begin
                out <= "z";
                pc <= 128;
            end
            128:
            begin
                out <= " ";
                pc <= 130;
            end
            130:
            begin
                pc <= 20;
            end
            140:
            begin
                out <= "b";
                pc <= 141;
            end
            141:
            begin
                out <= "u";
                pc <= 142;
            end
            142:
            begin
                out <= "z";
                pc <= 143;
            end
            143:
            begin
                out <= "z";
                pc <= 144;
            end
            144:
            begin
                out <= " ";
                pc <= 150;
            end
            150:
            begin
                pc <= 20;
            end
            160:
            begin
                out <= "f";
                pc <= 161;
            end
            161:
            begin
                out <= "i";
                pc <= 162;
            end
            162:
            begin
                out <= "z";
                pc <= 163;
            end
            163:
            begin
                out <= "z";
                pc <= 164;
            end
            164:
            begin
                out <= " ";
                pc <= 170;
            end
            170:
            begin
                pc <= 20;
            end
            180:
            begin
                pc <= 180;
            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
  70
  80
  90
 100
 101  0
 102  1
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  0
 102  2
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  0
 102  4
 110
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  0
 102  7
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  0
 102  8
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  1
 102  1
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  1
 102  3
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  1
 102  4
 110
  20
  30
  40
  50
 120
 121  f
 122  i
 123  z
 124  z
 125  b
 126  u
 127  z
 128  z
 130
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  1
 102  6
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  1
 102  7
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  1
 102  9
 110
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  2
 102  2
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  2
 102  3
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  2
 102  6
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  2
 102  8
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  2
 102  9
 110
  20
  30
  40
  50
 120
 121  f
 122  i
 123  z
 124  z
 125  b
 126  u
 127  z
 128  z
 130
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  3
 102  1
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  3
 102  2
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  3
 102  4
 110
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  3
 102  7
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  3
 102  8
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  4
 102  1
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  4
 102  3
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  4
 102  4
 110
  20
  30
  40
  50
 120
 121  f
 122  i
 123  z
 124  z
 125  b
 126  u
 127  z
 128  z
 130
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  4
 102  6
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  4
 102  7
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  4
 102  9
 110
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  5
 102  2
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  5
 102  3
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  5
 102  6
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  5
 102  8
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  5
 102  9
 110
  20
  30
  40
  50
 120
 121  f
 122  i
 123  z
 124  z
 125  b
 126  u
 127  z
 128  z
 130
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  6
 102  1
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  6
 102  2
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  6
 102  4
 110
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  6
 102  7
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  6
 102  8
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  7
 102  1
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  7
 102  3
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  7
 102  4
 110
  20
  30
  40
  50
 120
 121  f
 122  i
 123  z
 124  z
 125  b
 126  u
 127  z
 128  z
 130
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  7
 102  6
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  7
 102  7
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  7
 102  9
 110
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  8
 102  2
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  8
 102  3
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  8
 102  6
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  8
 102  8
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  8
 102  9
 110
  20
  30
  40
  50
 120
 121  f
 122  i
 123  z
 124  z
 125  b
 126  u
 127  z
 128  z
 130
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  9
 102  1
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  9
 102  2
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  9
 102  4
 110
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  9
 102  7
 110
  20
  30
  40
  50
  60
  70
  80
  90
 100
 101  9
 102  8
 110
  20
  30
  40
  50
  60
  70
  80
  90
 160
 161  f
 162  i
 163  z
 164  z
 170
  20
  30
  40
  50
  60
  70
 140
 141  b
 142  u
 143  z
 144  z
 150
  20
  30
 180


サンプルコード


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 a=a+1
30 #=a>100*180
40 b=a%15
50 #=b@0*120
60 b=a%5
70 #=b@0*140
80 b=a%3
90 #=b@0*160
100 ?=a
110 #=20
120 ?="fizzbuzz"
130 #=20
140 ?="buzz"
150 #=20
160 ?="fizz"
170 #=20
180 #=180
""")




成果物

以上。

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?