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 その176

Last updated at Posted at 2025-01-04

概要 

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

cpu仕様

レジスタマシン

  • レジスタ
    4bitレジスタj,k
    プログラムカウンタpc,4bit
    alu,74181
  • メモリ
    8bit、16個
  • 命令
    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

1から10まで数えよ

			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)

以上。

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?