windowsでiverilog その136

# 概要　
windowsでiverilogやってみた。
練習問題やってみた。

# 練習問題
cpuを実装せよ。
九九を実行せよ。

# サンプルコード

```


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
//  1
rom[0] <= 12'h2_01;
//  set  a
rom[1] <= 12'h4_00;
//  1
rom[2] <= 12'h2_01;
//  set  b
rom[3] <= 12'h4_01;
//loop  get  a
rom[4] <= 12'h3_00;
//  get  b
rom[5] <= 12'h3_01;
//  *
rom[6] <= 12'hf_02;
//  out3
rom[7] <= 12'h5_03;
//  out2
rom[8] <= 12'h5_02;
//  out1
rom[9] <= 12'h5_01;
//  drop
rom[10] <= 12'h9_00;
//  ' '
rom[11] <= 12'h2_20;
//  out
rom[12] <= 12'h5_00;
//  get  a
rom[13] <= 12'h3_00;
//  1
rom[14] <= 12'h2_01;
//  +
rom[15] <= 12'hf_00;
//  set  a
rom[16] <= 12'h4_00;
//  10
rom[17] <= 12'h2_0A;
//  get  a
rom[18] <= 12'h3_00;
//  >
rom[19] <= 12'hf_06;
//  if  loop
rom[20] <= 12'h6_04;
//  10
rom[21] <= 12'h2_0A;
//  out
rom[22] <= 12'h5_00;
//  get  b
rom[23] <= 12'h3_01;
//  1
rom[24] <= 12'h2_01;
//  +
rom[25] <= 12'hf_00;
//  set  b
rom[26] <= 12'h4_01;
//  1
rom[27] <= 12'h2_01;
//  set  a
rom[28] <= 12'h4_00;
//  10
rom[29] <= 12'h2_0A;
//  get  b
rom[30] <= 12'h3_01;
//  >
rom[31] <= 12'hf_06;
//  if  loop
rom[32] <= 12'h6_04;
//lup  jmp  lup
rom[33] <= 12'h1_21;
//
rom[34] <= 12'h2_00;

			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://end
			begin
			end
			4'h1://jmp
			begin
				jpflg = 1;
				pc <= opland;
			end
			4'h2://push
			begin
				push;
				q[0] <= opland;
			end
			4'h3://get
			begin
				push;
				q[0] <= ram[opland];
			end
			4'h4://set
			begin
				ram[opland] <= q[0];
				pop;
			end
			4'h5://out
			begin
				case (opland)
				4'h0://out
				begin
					out <= q[0];
					pop;
				end
				4'h1://out1
				begin
					out <= (q[0] % 10) + 48;
					pop;
				end
				4'h2://out2
				begin
					out <= ((q[0] / 10) % 10) + 48;
					pop;
				end
				4'h3:///out3
				begin
					out <= (q[0] / 100) + 48;
					pop;
				end
				endcase
			end
			4'h6://if
			begin
				if (q[0] == 1)
				begin
					jpflg = 1;
					pc <= opland;
				end
			end
			4'h7://if!
			begin
				if (q[0] == 0)
				begin
					jpflg = 1;
					pc <= opland;
				end
			end
			4'h8://dup
			begin
				push;
			end
			4'h9://drop
			begin
				pop;
			end
			4'hf:
			begin
				case (opland)
				4'h0://+
				begin
					q[0] <= q[1] + q[0];
					pop;
				end
				4'h1://-
				begin
					q[0] <= q[1] - q[0];
					pop;
				end
				4'h2://*
				begin
					q[0] <= q[1] * q[0];
					pop;
				end
				4'h3:///
				begin
					q[0] <= q[1] / q[0];
					pop;
				end
				4'h4://%
				begin
					q[0] <= q[1] % q[0];
					pop;
				end
				4'h5://=
				begin
					if (q[1] == q[0])
						q[0] <= 1;
					else
						q[0] <= 0;
					pop;
				end
				4'h6://>
				begin
					if (q[1] > q[0])
						q[0] <= 1;
					else
						q[0] <= 0;
					pop;
				end
				4'h7://rnd
				begin
					rnd <= rnd * 5 + 1;
					push;
					q[0] <= rnd;
				end
				endcase
			end
			endcase
			if (jpflg == 0)
				pc <= pc + 1;
			else
				jpflg <= 0;
		end
	end
	initial
	begin
		//$display("pc, ram0, out");
		//$monitor("   %d   %d   %d   %d   %d   %s", 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("   %s", outport);
		clk = 0;
		rst = 0;
		#2
			rst = 1;
		#2
			rst = 0;
		#2950
			$finish;
	end
	always
		#1
			clk = ~clk;
endmodule






```

# 実行結果

```
>iverilog cpu16.v

>vvp a.out

   0
   1

   0
   2

   0
   3

   0
   4

   0
   5

   0
   6

   0
   7

   0
   8

   0
   9



   0
   2

   0
   4

   0
   6

   0
   8

   0
   1
   0

   0
   1
   2

   0
   1
   4

   0
   1
   6

   0
   1
   8



   0
   3

   0
   6

   0
   9

   0
   1
   2

   0
   1
   5

   0
   1
   8

   0
   2
   1

   0
   2
   4

   0
   2
   7



   0
   4

   0
   8

   0
   1
   2

   0
   1
   6

   0
   2
   0

   0
   2
   4

   0
   2
   8

   0
   3
   2

   0
   3
   6



   0
   5

   0
   1
   0

   0
   1
   5

   0
   2
   0

   0
   2
   5

   0
   3
   0

   0
   3
   5

   0
   4
   0

   0
   4
   5



   0
   6

   0
   1
   2

   0
   1
   8

   0
   2
   4

   0
   3
   0

   0
   3
   6

   0
   4
   2

   0
   4
   8

   0
   5
   4



   0
   7

   0
   1
   4

   0
   2
   1

   0
   2
   8

   0
   3
   5

   0
   4
   2

   0
   4
   9

   0
   5
   6

   0
   6
   3



   0
   8

   0
   1
   6

   0
   2
   4

   0
   3
   2

   0
   4
   0

   0
   4
   8

   0
   5
   6

   0
   6
   4

   0
   7
   2



   0
   9

   0
   1
   8

   0
   2
   7

   0
   3
   6

   0
   4
   5

   0
   5
   4

   0
   6
   3

   0
   7
   2

   0
   8
   1




```

以上。