概要
ilasmでstack machineやってみた。
練習問題やってみた。
練習問題
ilasmをFPGA化せよ。
数9を四個使って、1から15まで求めよ。
サンプルコード
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)
以上。