ilasmでstack machine その46

# 概要
ilasmでstack machineやってみた。
練習問題やってみた。

# 練習問題
ilasmをFPGA化せよ。
数９を四個使って、１から１５まで求めよ。

# サンプルコード

```




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[199:0];
	reg [7:0] ram[2:0];
	reg [7:0] str[3:0];
	reg jpflg;
	reg [1:0] po1;
	reg [1:0] po2;
	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
//1
rom[0] = 12'h109;
rom[1] = 12'h109;
rom[2] = 12'hf03;
rom[3] = 12'h109;
rom[4] = 12'h109;
rom[5] = 12'hf05;
rom[6] = 12'hf02;
rom[7] = 12'h400;
//2
rom[8] = 12'h109;
rom[9] = 12'h109;
rom[10] = 12'hf05;
rom[11] = 12'h109;
rom[12] = 12'h109;
rom[13] = 12'hf05;
rom[14] = 12'hf02;
rom[15] = 12'h400;
//3

rom[16] = 12'h109;
rom[17] = 12'h109;
rom[18] = 12'hf02;
rom[19] = 12'h109;
rom[20] = 12'hf02;
rom[21] = 12'h109;
rom[22] = 12'hf05;
rom[23] = 12'h400;
//4
rom[24] = 12'h109;
rom[25] = 12'h109;
rom[26] = 12'hf02;//add
rom[27] = 12'h109;
rom[28] = 12'hf05;//div
rom[29] = 12'h109;
rom[30] = 12'hf01;//pop
rom[31] = 12'hf00;//dup
rom[32] = 12'hf02;//add
rom[33] = 12'h400;
//5
rom[34] = 12'h109;
rom[35] = 12'h109;
rom[36] = 12'h109;
rom[37] = 12'hf02;
rom[38] = 12'h109;
rom[39] = 12'hf05;
rom[40] = 12'hf00;
rom[41] = 12'hf02;
rom[42] = 12'hf03;
rom[43] = 12'h400;
//6
rom[44] = 12'h109;
rom[45] = 12'hf00;
rom[46] = 12'h109;
rom[47] = 12'hf02;
rom[48] = 12'h109;
rom[49] = 12'hf02;
rom[50] = 12'h109;
rom[51] = 12'hf05;
rom[52] = 12'hf03;
rom[53] = 12'h400;
//7
rom[54] = 12'h109;
rom[55] = 12'h109;
rom[56] = 12'h109;
rom[57] = 12'hf02;
rom[58] = 12'h109;
rom[59] = 12'hf05;
rom[60] = 12'hf03;
rom[61] = 12'h400;
//8
rom[62] = 12'h109;
rom[63] = 12'h109;
rom[64] = 12'h109;
rom[65] = 12'hf05;
rom[66] = 12'hf03;
rom[67] = 12'h109;
rom[68] = 12'hf01;
rom[69] = 12'h400;
//9
rom[70] = 12'h109;
rom[71] = 12'h109;
rom[72] = 12'hf03;
rom[73] = 12'h109;
rom[74] = 12'hf04;
rom[75] = 12'h109;
rom[76] = 12'hf02;
rom[77] = 12'h400;
//10
rom[78] = 12'h109;
rom[79] = 12'h109;
rom[80] = 12'hf05;
rom[81] = 12'h109;
rom[82] = 12'hf02;
rom[83] = 12'h109;
rom[84] = 12'hf01;
rom[85] = 12'h400;
//11
rom[86] = 12'h109;
rom[87] = 12'h109;
rom[88] = 12'h109;
rom[89] = 12'hf02;
rom[90] = 12'h109;
rom[91] = 12'hf05;
rom[92] = 12'hf02;
rom[93] = 12'h400;
//12
rom[94] = 12'h109;
rom[95] = 12'hf00;
rom[96] = 12'h109;
rom[97] = 12'h109;
rom[98] = 12'hf02;
rom[99] = 12'hf02;
rom[100] = 12'h109;
rom[101] = 12'hf05;
rom[102] = 12'hf02;
rom[103] = 12'h400;
//13
rom[104] = 12'h109;
rom[105] = 12'h109;
rom[106] = 12'h109;
rom[107] = 12'hf02;
rom[108] = 12'h109;
rom[109] = 12'hf05;
rom[110] = 12'hf00;
rom[111] = 12'hf02;
rom[112] = 12'hf02;
rom[113] = 12'h400;
//14
rom[114] = 12'h109;
rom[115] = 12'hf00;
rom[116] = 12'h109;
rom[117] = 12'h109;
rom[118] = 12'hf02;
rom[119] = 12'h109;
rom[120] = 12'hf05;
rom[121] = 12'hf00;
rom[122] = 12'hf02;
rom[123] = 12'hf03;
rom[124] = 12'hf02;
rom[125] = 12'h400;
//15
rom[126] = 12'h109;
rom[127] = 12'hf00;
rom[128] = 12'hf00;
rom[129] = 12'h109;
rom[130] = 12'hf02;
rom[131] = 12'h109;
rom[132] = 12'hf02;
rom[133] = 12'h109;
rom[134] = 12'hf05;
rom[135] = 12'hf03;
rom[136] = 12'hf02;
rom[137] = 12'h400;
rom[138] = 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;
			po1 <= 0;
			po2 <= 0;
			str[0] <= 0;
			str[1] <= 0;
			str[2] <= 0;
			str[3] <= 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'h2://ldstr
			begin
				case (opland)
				8'h00:
				begin
					po2 <= 0;
				end
				8'h01:
				begin
					po2 <= 0;
				end
				default:
				begin
					str[po2] <= opland;
					po2 <= po2 + 1;
				end
				endcase
			end
			4'h4://out
			begin
				case (po1)
				2'h0:
				begin
					out <= ((q[0] / 10) % 10) + 48;
					jpflg = 1;
					po1 <= po1 + 1;
				end
				2'h1:
				begin
					out <= (q[0] % 10) + 48;
					pop;
					po1 <= 0;
				end
				endcase
			end
			4'h5://out
			begin
				case (po2)
				2'h0:
				begin
					out <= str[po2];
					jpflg = 1;
					po2 <= po2 + 1;
				end
				2'h1:
				begin
					out <= str[po2];
					jpflg = 1;
					po2 <= po2 + 1;
				end
				2'h2:
				begin
					out <= str[po2];
					jpflg = 1;
					po2 <= po2 + 1;
				end
				2'h3:
				begin
					out <= str[po2];
					po2 <= po2 + 1;
				end
				endcase
			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] == 0)
				begin
					jpflg = 1;
					pc <= opland;
				end
				pop;
			end
			4'hb://brfalse
			begin
				if (q[0] == 1)
				begin
					jpflg = 1;
					pc <= opland;
				end
				pop;
			end
			4'hf:
			begin
				case (opland)
				8'h00://dup
				begin
					push;
				end
				8'h01://pop
				begin
					q[0] <= q[1];
					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,   str,  out");
		//$monitor("   %d   %d    %d    %d    %d    %s", pc, qtop, jpflg, ram[0], str[0], out);
	end
endmodule
 
module test;
	reg clk,
		rst;
	wire [7:0] outport;
	cpu12 u(.clk(clk), .rst(rst), .outport(outport));
	initial
	begin
		$monitor("   %s", outport);
		clk = 0;
		rst = 0;
		#2
			rst = 1;
		#2
			rst = 0;
		#1000
			$finish;
	end
	always
		#1
			clk = ~clk;
endmodule





```

# 実行結果

```
>vvp a.out

   0
   1
   0
   2
   0
   3
   0
   4
   0
   5
   0
   6
   0
   7
   0
   8
   0
   9
   1
   0
   1
   2
   1
   3
   1
   4
   1
   5
il2.v:445: $finish called at 1004 (1s)

```

以上。