概要
windowsでiverilogやってみた。
4bitCPUで、何ができる。
5個の数値をソートできる。
4bit CPUの仕様
stackマシーン
stackは、4bitで5個搭載
命令は、8bit
ROMは、16個
RAMは、5個
退避レジスタ 4bit 1個
プログラムカウンタ(pc) 4bit
命令一覧
ジャンプ命令->無し
RAMアクセス->無し
フラグ->無し
| ニーモニック | 動作 | 機械語 |
|---|---|---|
| end | 停止 | 00 |
| sort5 | スタックに5個積んで、昇順にソートする。 | 10 |
| push x | スタックにxを積む。 | 2x |
| out | スタックTOPを出力。 | 50 |
| dup | スタックTOPを複写。 | 80 |
| drop | スタックTOPを廃棄。 | 90 |
| + | スタックTOPをNEXTで加算。 | F0 |
| - | スタックTOPをNEXTで減算。 | F1 |
| * | スタックTOPをNEXTで乗算。 | F2 |
| / | スタックTOPをNEXTで除算。 | F3 |
サンプルコード
module cpu4(input clk, input rst, output [3:0] outport);
integer i,
j;
reg [3:0] q[0:5];
reg [7:0] rom[0:15];
reg [3:0] ram[0:4];
reg [3:0] temp;
reg jpflg;
reg [3:0] pc;
reg [3:0] out;
wire [7:0] code;
wire [3:0] op;
wire [3:0] opland;
wire [3:0] qtop;
wire [3:0] qnext;
assign code = rom[pc];
assign op = code[7:4];
assign opland = code[3:0];
assign outport = out;
assign qtop = q[0];
assign qnext = q[1];
task push;
begin
for (i = 1; i < 6; i = i + 1)
q[i] <= q[i - 1];
end
endtask
task pop;
begin
for (i = 0; i < 5; i = i + 1)
q[i] <= q[i + 1];
end
endtask
initial
begin
$monitor(" pc: %d top: %d next: %d out: %d", pc, qtop, qnext, out);
end
always @(posedge clk)
begin
if (rst)
begin
rom[0] <= 8'h2_4;
rom[1] <= 8'h2_5;
rom[2] <= 8'h2_1;
rom[3] <= 8'h2_2;
rom[4] <= 8'h2_3;
rom[5] <= 8'h1_0;
rom[6] <= 8'h5_0;
rom[7] <= 8'h5_0;
rom[8] <= 8'h5_0;
rom[9] <= 8'h5_0;
rom[10] <= 8'h5_0;
rom[11] <= 8'h0_0;
for (i = 0; i < 6; i = i + 1)
q[i] <= 0;
jpflg <= 0;
out <= 0;
pc <= 0;
ram[0] <= 0;
ram[1] <= 0;
ram[2] <= 0;
ram[3] <= 0;
ram[4] <= 0;
end
else
begin
case (op)
4'h0://end
begin
jpflg = 1;
end
4'h1://sort5
begin
for (i = 0; i < 4; i = i + 1)
begin
for (j = 0; j < 4 - i; j = j + 1)
begin
if (q[j] > q[j + 1])
begin
temp = q[j];
q[j] = q[j + 1];
q[j + 1] = temp;
end
end
end
end
4'h2://push
begin
push;
q[0] <= opland;
end
4'h5://out
begin
out <= q[0];
pop;
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
endcase
end
endcase
if (jpflg == 0)
pc <= pc + 1;
else
jpflg <= 0;
end
end
endmodule
テストベンチ
module test;
reg clk,
rst;
wire [3:0] outport;
cpu4 u(.clk(clk), .rst(rst), .outport(outport));
initial
begin
//$monitor(" %d", outport);
clk = 0;
rst = 0;
#2
rst = 1;
#2
rst = 0;
#280
$finish;
end
always
#1
clk = ~clk;
endmodule
投入したソースコード
push 4
push 5
push 1
push 2
push 3
sort5
out
out
out
out
out
実行結果
>vvp a.out
pc: x top: x next: x out: x
pc: 0 top: 0 next: 0 out: 0
pc: 1 top: 4 next: 0 out: 0
pc: 2 top: 5 next: 4 out: 0
pc: 3 top: 1 next: 5 out: 0
pc: 4 top: 2 next: 1 out: 0
pc: 5 top: 3 next: 2 out: 0
pc: 6 top: 1 next: 2 out: 0
pc: 7 top: 2 next: 3 out: 1
pc: 8 top: 3 next: 4 out: 2
pc: 9 top: 4 next: 5 out: 3
pc: 10 top: 5 next: 0 out: 4
pc: 11 top: 0 next: 0 out: 5
stack5.v:172: $finish called at 284 (1s)
以上。