windowsでiverilog その176

# 概要　
windowsでiverilogやってみた。
74181なverilog見つけたので、やってみた。
74181使って、4bitCPU書いてみた。

# cpu仕様
レジスタマシン
- レジスタ
４bitレジスタj,k
プログラムカウンタpc,4bit
alu,74181
- メモリ
８bit、１６個
- 命令
			4'h0://nop
			4'h1://if (k > 0) pc = adr
			4'h2://j = v
			4'h3://k = v
			4'h4://j = j + 1
			4'h5://k = k - 1
			4'h6://out
			4'h7://jmp

１から１０まで数えよ

```
			mem[0] <= 8'h2_1; //j = 1
			mem[1] <= 8'h3_A; //k = 10
			mem[2] <= 8'h4_1; //j = j + 1
			mem[3] <= 8'h6_0; //out
			mem[4] <= 8'h5_1; //k = k - 1
			mem[5] <= 8'h1_2; //if (k > 0) pc = 2
			mem[6] <= 8'h7_6; //jmp 6
			mem[7] <= 8'h0_0; //
			mem[8] <= 8'h0_0; //
			mem[9] <= 8'h0_0; //

```

# サンプルコード

```



module alu(output wire f, output wire co_x, input wire a, input wire b, input wire ci_x, input wire [3:0] s, input wire m);
	wire g;
	wire h;
	assign g = !(a | (b & s[0]) | (!b & s[1]));
	assign h = !((!b & s[2] & a) | (a & s[3] & b));
	assign co_x = (g | (h & ci_x));
	assign f = !(!m & ci_x) ^ g ^ h;
endmodule

module alu74181 #(parameter WIDTH = 4) (output wire [WIDTH - 1:0] f, output wire co_x, input wire [WIDTH - 1:0] a, input wire [WIDTH - 1:0] b, input wire ci_x, input wire [3:0] s, input wire m);
	genvar i;
	wire [WIDTH:0] c_x;
	assign c_x[0] = ci_x;
	assign co_x = c_x[WIDTH];
	generate
		for (i = 0; i < WIDTH; i = i + 1)
		begin
			alu lu(.f(f[i]), .co_x(c_x[i + 1]), .a(a[i]), .b(b[i]), .ci_x(c_x[i]), .s(s), .m(m));
		end
	endgenerate
endmodule

module neos(input clk, input rst, output [3:0] outport);
	wire [3:0] f;
	reg [3:0] a;
	reg [3:0] b;
	reg cy;
	reg [3:0] s;
	reg m;
	reg [3:0] j,
		k,
		pc;
	reg w;
	reg [7:0] mem[9:0];
	wire [7:0] code;
	wire [3:0] op;
	wire [3:0] opland;
	assign code = mem[pc];
	assign op = code[7:4];
	assign opland = code[3:0];
	assign outport = j; 
	alu74181 u(.f(f), .a(a), .b(b), .ci_x(cy), .s(s), .m(m));
	always @(posedge clk, negedge rst)
	begin
 		if (!rst)
		begin
			mem[0] <= 8'h2_1; //j = 1
			mem[1] <= 8'h3_A; //k = 10
			mem[2] <= 8'h4_1; //j = j + 1
			mem[3] <= 8'h6_0; //out
			mem[4] <= 8'h5_1; //k = k - 1
			mem[5] <= 8'h1_2; //if (k > 0) pc = 2
			mem[6] <= 8'h7_6; //jmp 6
			mem[7] <= 8'h0_0; //
			mem[8] <= 8'h0_0; //
			mem[9] <= 8'h0_0; //
			j <= 4'h0;
			k <= 4'h0;
			pc <= 4'h0;
			w <= 0;
		end
		else if (w == 1)
		begin
			j <= f;
			w <= 0;
		end
		else
		begin
			case (op)
			4'h0://nop
			begin
			end
			4'h1://if (k > 0) pc = adr
			begin
				if (k > 0)
					pc = opland - 1;
			end
			4'h2://j = v
			begin
				j <= opland;
			end
			4'h3://k = v
			begin
				k <= opland;
			end
			4'h4://j = j + 1
			begin
				a <= j;
				b <= opland;
				cy <= 1;
				s <= 'h9;
				m <= 0;
				//j <= f;
				w <= 1;
				//j <= j + opland;
			end
			4'h5://k = k - 1
			begin
				k <= k - opland;
			end
			4'h6://out
			begin
			end
			4'h7://jmp
			begin
				pc = opland - 1;
			end
			endcase
			pc = pc + 1;
		end
	end
	initial
	begin
		//$monitor("%d %d %d %d %d %d %d", pc, j, k, a, b, f, w);
	end
endmodule

module test;
	reg clk,
		rst;
	wire [3:0] outport;
	neos u(.clk(clk), .rst(rst), .outport(outport));
	initial
	begin
		clk = 0;
		rst = 1;
	#2
		rst = 0;
	#2
		rst = 1;
	#110
		$finish;
	end
	always
	#1
		clk = ~clk;
	initial
	begin
		$monitor("%d", outport);
	end
endmodule






```

# 実行結果

```
>vvp a.out
 x
 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
neos4.v:135: $finish called at 114 (1s)

```

以上。