3
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でelixirやってみた。
FPGAの高位合成書いてみた。
俺言語書いてみた。

高位合成て何

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

10 a=1
20 b=1
30 ?=a*b
60 a=a+1
70 #=a<10*30
90 b=b+1
100 a=1
110 #=b<10*30
120 #=120
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 <= 1;
            pc <= 20;
            end
            20:
            begin
            b <= 1;
            pc <= 30;
            end
            30:
            begin
            out <= a*b;
            pc <= 60;
            end
            60:
            begin
            a <= a+1;
            pc <= 70;
            end
            70:
            begin
            if (a<10)
            pc <= 30;
            else
            pc <= 90;
            end
            90:
            begin
            b <= b+1;
            pc <= 100;
            end
            100:
            begin
            a <= 1;
            pc <= 110;
            end
            110:
            begin
            if (b<10)
            pc <= 30;
            else
            pc <= 120;
            end
            120:
            begin
            pc <= 120;
      end
            endcase
        end
    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;
        $monitor("%d", out);
        #2
        rst = 0;
        #2
        rst = 1;
        #2500
        $finish;
    end
    always
    #1
        clk = ~clk;
endmodule

シミュレーション結果

>iverilog kuku.v

>vvp a.out
  x
  1
  2
  3
  4
  5
  6
  7
  8
  9
  2
  4
  6
  8
 10
 12
 14
 16
 18
  3
  6
  9
 12
 15
 18
 21
 24
 27
  4
  8
 12
 16
 20
 24
 28
 32
 36
  5
 10
 15
 20
 25
 30
 35
 40
 45
  6
 12
 18
 24
 30
 36
 42
 48
 54
  7
 14
 21
 28
 35
 42
 49
 56
 63
  8
 16
 24
 32
 40
 48
 56
 64
 72
  9
 18
 27
 36
 45
 54
 63
 72
 81



サンプルコード

defmodule Asm do
	def start_link do
		Agent.start_link(fn ->
			%{u: ""}
		end, name: __MODULE__)
	end
    def print(a, b) do
		Agent.update(__MODULE__, fn v ->
            str = "            pc <= " <> a <>";\n            end\n            " <> a <> ":\n            begin\n            out <= " <> b <> ";\n"
		    %{v | u: v.u <> str}
		end)
    end
    def jmp(a, b) do
		Agent.update(__MODULE__, fn v ->
		    if String.match?(b, ~r/\*/) do
		        s = String.split(b, "*")
			    str = "            pc <= " <> a <>";\n            end\n            " <> a <> ":\n            begin\n            if (" <> Enum.at(s, 0) <> ")\n            pc <= " <> Enum.at(s, 1) <> ";\n            else\n"
			    %{v | u: v.u <> str}
		    else
		        str = "            pc <= " <> a <>";\n            end\n            " <> a <> ":\n            begin\n            pc <= " <> b <> ";\n      end\n"
		        %{v | u: v.u <> str}
		    end
		end)
    end
    def a(a, b) do
		Agent.update(__MODULE__, fn v ->
			if a == "10" do 
			    str = "            " <> a <> ":\n            begin\n            a <= " <> b <> ";\n"
			    %{v | u: v.u <> str}
		    else
		        str = "            pc <= " <> a <>";\n            end\n            " <> a <> ":\n            begin\n            a <= " <> b <> ";\n"
		        %{v | u: v.u <> str}
		    end
		end)
    end
    def b(a, b) do
		Agent.update(__MODULE__, fn v ->
			if a == "10" do 
			    str = "            " <> a <> ":\n            begin\n            b <= " <> b <> ";\n"
			    %{v | u: v.u <> str}
		    else
		        str = "            pc <= " <> a <>";\n            end\n            " <> a <> ":\n            begin\n            b <= " <> b <> ";\n"
		        %{v | u: v.u <> str}
		    end
		end)
    end
    def echo() 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" <>
		    "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" <>
		    "        $monitor(\"%d\", out);\n" <>
		    "        #2\n" <>
			"        rst = 0;\n" <>
		    "        #2\n" <>
			"        rst = 1;\n" <>
		    "        #2500\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.jmp(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.echo
	end
end

Asm.start_link

Main.run("""
10 a=1
20 b=1
30 ?=a*b
60 a=a+1
70 #=a<10*30
90 b=b+1
100 a=1
110 #=b<10*30
120 #=120
""")

成果物

以上。

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