0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

概要 

windowsでiverilogやってみた。
8bit CPU、書いてみた。

8bitCPUで、何ができる。

1-100まで、数えることができる。

8bit CPUの仕様

stackマシーン (registerマシーンではない)
stackは、8bitで5個搭載
命令は、12bit
ROMは、32個
RAMは、0個
アドレスレジスタ 8bit 1個
プログラムカウンタ(pc) 5bit

命令一覧

RAMアクセス->無し
フラグ->無し

ニーモニック 動作 機械語
end 停止 00
push x スタックにxを積む。 2xx
adr x アドレスレジスタにxを積む。 300
if1 スタックTOPが1でなければ、jmp 400
out スタックTOPを出力。 500
dup スタックTOPを複写。 800
drop スタックTOPを廃棄。 900
+ スタックTOPをNEXTで加算。 F00
- スタックTOPをNEXTで減算。 F01
== スタックTOPをNEXTで同じなら1 F0F

サンプルコード

module cpu8(input clk, input rst, output [7:0] outport);
	integer i;
	reg [7:0] q[0:5];
	reg [11:0] rom[0:15];
	reg [4:0] pc;
	reg [7:0] adr,
		out;
	wire [11:0] code = rom[pc];
	wire [3:0] op = code[11:8];
	wire [7:0] opland = code[7:0];
	assign outport = out;
	task push;
		begin
			for (i = 1; i < 6; i = i + 1)
				q[i] <= q[i - 1];
		end
	endtask
	task pop;
		begin
			for (i = 1; i < 5; i = i + 1)
				q[i] <= q[i + 1];
		end
	endtask
	initial
	begin
		//$monitor(" pc: %d op: %h top: %d next: %d thd: %d adr: %d", pc, op, q[0], q[1], q[2], adr);
	end
	always @(posedge clk)
	begin
		if (rst)
		begin
			rom[0] <= 12'h2_00; // PUSH 0  (カウンター初期値)
			rom[1] <= 12'h3_02; // ADR  2  (戻るadrを積む)
			rom[2] <= 12'h2_01; // PUSH 1
			rom[3] <= 12'hF_00; // ADD	   (+
			rom[4] <= 12'h8_00; // DUP	   (カウンターを複製)
			rom[5] <= 12'h8_00; // DUP	   (カウンターを複製)
			rom[6] <= 12'h5_00; // OUT	   (現在のカウントを出力、1つ消費)
			rom[7] <= 12'h2_64; // PUSH 100
			rom[8] <= 12'hF_0F; // EQ	   (== 100)
			rom[9] <= 12'h4_00; // JEQ    (if top != 1 then adr)
			rom[10] <= 12'h0_00; // END
			rom[11] <= 12'h0_00; // 
			rom[12] <= 12'h0_00; // 
			rom[13] <= 12'h0_00; // 
			rom[14] <= 12'h0_00; // 
			rom[15] <= 12'h0_00; // 
			for (i = 0; i < 6; i = i + 1)
				q[i] <= 0;
			adr <= 0;
			out <= 0;
			pc <= 0;
		end
		else
		begin
			case (op)
			4'h0: // HALT
				pc <= pc;
			4'h2: // PUSH (下8bit)
			begin
				push;
				q[0] <= opland;
				pc <= pc + 1;
			end
			4'h3: // ADR (下8bit)
			begin
				adr <= opland;
				pc <= pc + 1;
			end
			4'h4: // IF1 (topが1でなければ、adrの値をPCにする)
			begin
				if (q[0] != 8'd1)
					pc <= adr;
				else
					pc <= pc + 1;
				q[0] <= q[1];
				pop;
			end
			4'h5: // OUT
			begin
				out <= q[0];
				pop;
				pc <= pc + 1;
			end
			4'h8: // DUP
			begin
				push;
				pc <= pc + 1;
			end
			4'h9: // DROP
			begin
				q[0] <= q[1];
				pop;
				pc <= pc + 1;
			end
			4'hf: // 演算
			begin
				case (opland)
				8'h00: // ADD
				begin
					q[0] <= q[1] + q[0];
					pop;
				end
				8'h01: // SUB
				begin
					q[0] <= q[1] - q[0];
					pop;
				end
				8'h0f: // EQ
				begin
					if (q[0] == q[1])
						q[0] <= 8'd1;
					else
						q[0] <= 8'd0;
					pop;
				end
				endcase
				pc <= pc + 1;
			end
			default:
				pc <= pc + 1;
			endcase
		end
	end
endmodule

テストベンチ


`timescale 1ns / 1ps

module test;
	reg clk,
		rst;
	wire [7:0] outport;
	cpu8 u(.clk(clk), .rst(rst), .outport(outport));
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
		$monitor("   %d", outport);
		clk = 0;
		rst = 0;
		#2
			rst = 1;
		#2
			rst = 0;
		#2000
			$finish;
	end
	always
		#1
			clk = ~clk;
endmodule




投入したソースコード

    PUSH 0  (カウンター初期値)
    ADR  2  (戻るアドレスを積む)
    PUSH 1 (カウントアップ用)
    ADD	   (+ 1)
    DUP	   (カウンターを複製)
    DUP	   (カウンターを複製)
    OUT	   (現在のカウントを出力、1つ消費)
    PUSH 100
    EQ	   (== 100)
    IF1    (if top != 1 then adr)
    END

実行結果


>vvp a.out
VCD info: dumpfile test.vcd opened for output.
     x
     0
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
   100
stack7.v:161: $finish called at 2004000 (1ps)

以上。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?