概要
ilasmでstack machineやってみた。
俺cpuはstack machineなので、ilasmのニーモニックが動くように改造してみる。
verilogで書いてみた。
サンプルコード
module cpu12(input clk, input rst, output [7:0] outport);
parameter N = 6;
integer i;
reg [7:0] q[0:N - 1];
reg [11:0] rom[64:0];
reg [7:0] ram[2:0];
reg jpflg;
reg [7:0] pc;
reg [7:0] out;
reg [7:0] rnd;
wire [11:0] code;
wire [3:0] op;
wire [7:0] opland;
wire [7:0] qtop;
wire [7:0] qnext;
assign code = rom[pc];
assign op = code[11:8];
assign opland = code[7:0];
assign outport = out;
assign qtop = q[0];
assign qnext = q[1];
task push;
begin
for (i = 1; i < N; i = i + 1)
q[i] <= q[i - 1];
end
endtask
task pop;
begin
for (i = 1; i < N - 1; i = i + 1)
q[i] <= q[i + 1];
end
endtask
always @(posedge clk)
begin
if (rst)
begin
rom[0] = 12'h10a;
rom[1] = 12'hf0b;
rom[2] = 12'h101;
rom[3] = 12'hf09;
rom[4] = 12'hf0a;
rom[5] = 12'hf0c;
rom[6] = 12'h72e;
rom[7] = 12'hf0a;
rom[8] = 12'h10f;
rom[9] = 12'hf06;
rom[10] = 12'ha15;
rom[11] = 12'hf0a;
rom[12] = 12'h105;
rom[13] = 12'hf06;
rom[14] = 12'ha1c;
rom[15] = 12'hf0a;
rom[16] = 12'h103;
rom[17] = 12'hf06;
rom[18] = 12'ha23;
rom[19] = 12'hf0a;
rom[20] = 12'h400;
rom[21] = 12'h929;
rom[22] = 12'h201;
rom[23] = 12'h266;
rom[24] = 12'h269;
rom[25] = 12'h262;
rom[26] = 12'h275;
rom[27] = 12'h200;
rom[28] = 12'h929;
rom[29] = 12'h201;
rom[30] = 12'h262;
rom[31] = 12'h275;
rom[32] = 12'h27a;
rom[33] = 12'h27a;
rom[34] = 12'h200;
rom[35] = 12'h929;
rom[36] = 12'h201;
rom[37] = 12'h266;
rom[38] = 12'h269;
rom[39] = 12'h27a;
rom[40] = 12'h27a;
rom[41] = 12'h200;
rom[42] = 12'h500;
rom[43] = 12'hf0a;
rom[44] = 12'h101;
rom[45] = 12'hf02;
rom[46] = 12'hf09;
rom[47] = 12'h904;
rom[48] = 12'h001;
for (i = 0; i < N; i = i + 1)
q[i] <= 0;
jpflg <= 0;
pc <= 0;
ram[0] <= 0;
ram[1] <= 0;
ram[2] <= 0;
rnd <= 234;
end
else
begin
case (op)
4'h0:
begin
case (opland)
8'h00://nop
begin
end
8'h01://ret
begin
jpflg = 1;
end
endcase
end
4'h1://idc.i4
begin
push;
q[0] <= opland;
end
4'h4://out
begin
out <= q[0];
pop;
end
4'h5://out
begin
out <= 8;
end
4'h6://beq
begin
if (q[1] == q[0])
begin
jpflg = 1;
pc <= opland;
end
pop;
pop;
end
4'h7://>bgt
begin
if (q[1] > q[0])
begin
jpflg = 1;
pc <= opland;
end
pop;
pop;
end
4'h8://>blt
begin
if (q[1] < q[0])
begin
jpflg = 1;
pc <= opland;
end
pop;
pop;
end
4'h9://br
begin
jpflg = 1;
pc <= opland;
end
4'ha://brture
begin
if (q[0] == 1)
begin
jpflg = 1;
pc <= opland;
end
pop;
end
4'hb://brfalse
begin
if (q[0] == 0)
begin
jpflg = 1;
pc <= opland;
end
pop;
end
4'hf:
begin
case (opland)
8'h00://dup
begin
push;
end
8'h01://pop
begin
pop;
end
8'h02://add
begin
q[0] <= q[1] + q[0];
pop;
end
8'h03://sub
begin
q[0] <= q[1] - q[0];
pop;
end
8'h04://mul
begin
q[0] <= q[1] * q[0];
pop;
end
8'h05://div
begin
q[0] <= q[1] / q[0];
pop;
end
8'h06://rem
begin
q[0] <= q[1] % q[0];
pop;
end
8'h07://rnd
begin
rnd <= rnd * 5 + 1;
push;
q[0] <= rnd;
end
8'h09://stloc a
begin
ram[0] <= q[0];
pop;
end
8'h0a://ldloc a
begin
push;
q[0] <= ram[0];
end
8'h0b://stloc b
begin
ram[1] <= q[0];
pop;
end
8'h0c://ldloc b
begin
push;
q[0] <= ram[1];
end
endcase
end
endcase
if (jpflg == 0)
pc <= pc + 1;
else
jpflg <= 0;
end
end
initial
begin
$display(" pc, qtop, jpflg, ram[0], rnd, out");
$monitor(" %d %d %d %d %d %h", pc, qtop, jpflg, ram[0], rnd, out);
end
endmodule
module test;
reg clk,
rst;
wire [7:0] outport;
cpu12 u(.clk(clk), .rst(rst), .outport(outport));
initial
begin
//$monitor(" %h", outport);
clk = 0;
rst = 0;
#2
rst = 1;
#2
rst = 0;
#500
$finish;
end
always
#1
clk = ~clk;
endmodule
実行結果
>vvp a.out
pc, qtop, jpflg, ram[0], rnd, out
x x x x x xx
x x 0 x x xx
0 0 0 0 234 xx
1 10 0 0 234 xx
2 10 0 0 234 xx
3 1 0 0 234 xx
4 1 0 1 234 xx
5 1 0 1 234 xx
6 10 0 1 234 xx
7 10 0 1 234 xx
8 1 0 1 234 xx
9 15 0 1 234 xx
10 1 0 1 234 xx
21 1 0 1 234 xx
41 1 0 1 234 xx
42 1 0 1 234 xx
43 1 0 1 234 08
44 1 0 1 234 08
45 1 0 1 234 08
46 2 0 1 234 08
47 2 0 2 234 08
4 2 0 2 234 08
5 2 0 2 234 08
6 10 0 2 234 08
7 10 0 2 234 08
8 2 0 2 234 08
9 15 0 2 234 08
10 2 0 2 234 08
11 2 0 2 234 08
12 2 0 2 234 08
13 5 0 2 234 08
14 2 0 2 234 08
15 2 0 2 234 08
16 2 0 2 234 08
17 3 0 2 234 08
18 2 0 2 234 08
19 2 0 2 234 08
20 2 0 2 234 08
21 2 0 2 234 02
41 2 0 2 234 02
42 2 0 2 234 02
43 2 0 2 234 08
44 2 0 2 234 08
45 1 0 2 234 08
46 3 0 2 234 08
47 3 0 3 234 08
4 3 0 3 234 08
5 3 0 3 234 08
6 10 0 3 234 08
7 10 0 3 234 08
8 3 0 3 234 08
9 15 0 3 234 08
10 3 0 3 234 08
11 3 0 3 234 08
12 3 0 3 234 08
13 5 0 3 234 08
14 3 0 3 234 08
15 3 0 3 234 08
16 3 0 3 234 08
17 3 0 3 234 08
18 0 0 3 234 08
19 0 0 3 234 08
20 3 0 3 234 08
21 3 0 3 234 03
41 3 0 3 234 03
42 3 0 3 234 03
43 3 0 3 234 08
44 3 0 3 234 08
45 1 0 3 234 08
46 4 0 3 234 08
47 4 0 4 234 08
4 4 0 4 234 08
5 4 0 4 234 08
6 10 0 4 234 08
7 10 0 4 234 08
8 4 0 4 234 08
9 15 0 4 234 08
10 4 0 4 234 08
11 4 0 4 234 08
12 4 0 4 234 08
13 5 0 4 234 08
14 4 0 4 234 08
15 4 0 4 234 08
16 4 0 4 234 08
17 3 0 4 234 08
18 1 0 4 234 08
35 1 0 4 234 08
41 1 0 4 234 08
42 1 0 4 234 08
43 1 0 4 234 08
44 4 0 4 234 08
45 1 0 4 234 08
46 5 0 4 234 08
47 5 0 5 234 08
4 5 0 5 234 08
5 5 0 5 234 08
6 10 0 5 234 08
7 10 0 5 234 08
8 5 0 5 234 08
9 15 0 5 234 08
10 5 0 5 234 08
11 5 0 5 234 08
12 5 0 5 234 08
13 5 0 5 234 08
14 0 0 5 234 08
15 0 0 5 234 08
16 5 0 5 234 08
17 3 0 5 234 08
18 2 0 5 234 08
19 2 0 5 234 08
20 5 0 5 234 08
21 5 0 5 234 05
41 5 0 5 234 05
42 5 0 5 234 05
43 5 0 5 234 08
44 5 0 5 234 08
45 1 0 5 234 08
46 6 0 5 234 08
47 6 0 6 234 08
4 6 0 6 234 08
5 6 0 6 234 08
6 10 0 6 234 08
7 10 0 6 234 08
8 6 0 6 234 08
9 15 0 6 234 08
10 6 0 6 234 08
11 6 0 6 234 08
12 6 0 6 234 08
13 5 0 6 234 08
14 1 0 6 234 08
28 1 0 6 234 08
41 1 0 6 234 08
42 1 0 6 234 08
43 1 0 6 234 08
44 6 0 6 234 08
45 1 0 6 234 08
46 7 0 6 234 08
47 7 0 7 234 08
4 7 0 7 234 08
5 7 0 7 234 08
6 10 0 7 234 08
7 10 0 7 234 08
8 7 0 7 234 08
9 15 0 7 234 08
10 7 0 7 234 08
11 7 0 7 234 08
12 7 0 7 234 08
13 5 0 7 234 08
14 2 0 7 234 08
15 2 0 7 234 08
16 7 0 7 234 08
17 3 0 7 234 08
18 1 0 7 234 08
35 1 0 7 234 08
41 1 0 7 234 08
42 1 0 7 234 08
43 1 0 7 234 08
44 7 0 7 234 08
45 1 0 7 234 08
46 8 0 7 234 08
47 8 0 8 234 08
4 8 0 8 234 08
5 8 0 8 234 08
6 10 0 8 234 08
7 10 0 8 234 08
8 8 0 8 234 08
9 15 0 8 234 08
10 8 0 8 234 08
11 8 0 8 234 08
12 8 0 8 234 08
13 5 0 8 234 08
14 3 0 8 234 08
15 3 0 8 234 08
16 8 0 8 234 08
17 3 0 8 234 08
18 2 0 8 234 08
19 2 0 8 234 08
20 8 0 8 234 08
21 8 0 8 234 08
41 8 0 8 234 08
42 8 0 8 234 08
43 8 0 8 234 08
44 8 0 8 234 08
45 1 0 8 234 08
46 9 0 8 234 08
47 9 0 9 234 08
4 9 0 9 234 08
5 9 0 9 234 08
6 10 0 9 234 08
7 10 0 9 234 08
8 9 0 9 234 08
9 15 0 9 234 08
10 9 0 9 234 08
11 9 0 9 234 08
12 9 0 9 234 08
13 5 0 9 234 08
14 4 0 9 234 08
15 4 0 9 234 08
16 9 0 9 234 08
17 3 0 9 234 08
18 0 0 9 234 08
19 0 0 9 234 08
20 9 0 9 234 08
21 9 0 9 234 09
41 9 0 9 234 09
42 9 0 9 234 09
43 9 0 9 234 08
44 9 0 9 234 08
45 1 0 9 234 08
46 10 0 9 234 08
47 10 0 10 234 08
4 10 0 10 234 08
5 10 0 10 234 08
6 10 0 10 234 08
7 10 0 10 234 08
8 10 0 10 234 08
9 15 0 10 234 08
10 10 0 10 234 08
11 10 0 10 234 08
12 10 0 10 234 08
13 5 0 10 234 08
14 0 0 10 234 08
15 0 0 10 234 08
16 10 0 10 234 08
17 3 0 10 234 08
18 1 0 10 234 08
35 1 0 10 234 08
41 1 0 10 234 08
42 1 0 10 234 08
43 1 0 10 234 08
44 10 0 10 234 08
45 1 0 10 234 08
46 11 0 10 234 08
47 11 0 11 234 08
4 11 0 11 234 08
5 11 0 11 234 08
6 10 0 11 234 08
46 10 0 11 234 08
47 10 0 10 234 08
4 10 0 10 234 08
5 10 0 10 234 08
6 10 0 10 234 08
7 10 0 10 234 08
8 10 0 10 234 08
9 15 0 10 234 08
10 10 0 10 234 08
11 10 0 10 234 08
12 10 0 10 234 08
13 5 0 10 234 08
14 0 0 10 234 08
15 0 0 10 234 08
16 10 0 10 234 08
17 3 0 10 234 08
il0.v:273: $finish called at 504 (1s)
残った課題
opコード0x4のintのoutはokだが、opコード0x5のstringのoutはng
改善案
出力は、文字コードとし、intは、2バイト、stringは、4バイト、固定。
バッファとカウンタを準備する。
以上