LoginSignup
0
0

More than 1 year has passed since last update.

windowsでiverilog その136

Last updated at Posted at 2023-03-02

概要 

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




以上。

0
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
0
0