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