概要
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
""")
成果物
以上。