vistaでquartus その7

#概要

vistaでquartusやってみた。
俺cpuやってみた。

#環境

windows vista 32bit
quartus ii v13.0
ep2c5t144ボード

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1fb2a1c3-c37c-59d5-9e6d-cb49b22b0634.png)

#サンプルコード


```




`define		IDLE	3'b000
`define		FETCHA	3'b001
`define		FETCHB	3'b010
`define		EXECA	3'b011
`define		EXECB	3'b100

`define		ADD		5'b00000
`define		SUB		5'b00001
`define		MUL		5'b00010
`define		SHL		5'b00011
`define		SHR		5'b00100
`define		BAND	5'b00101
`define		BOR		5'b00110
`define		BXOR	5'b00111
`define		AND		5'b01000
`define		OR		5'b01001
`define		EQ		5'b01010
`define		NE		5'b01011
`define		GE		5'b01100
`define		LE		5'b01101
`define		GT		5'b01110
`define		LT		5'b01111
`define		NEG		5'b10000
`define		BNOT	5'b10001
`define		NOT		5'b10010

`define		HALT		4'b0000
`define		PUSHI		4'b0001
`define		PUSH		4'b0010
`define		POP		4'b0011
`define		JMP		4'b0100
`define		JZ			4'b0101
`define		JNZ		4'b0110
`define		IN			4'b1101
`define		OUT		4'b1110
`define		OP			4'b1111

module counter(clk, rst, load, inc, d, q);
	parameter N = 16;
	input clk,
		rst,
		load,
		inc;
	input [N - 1:0] d;
	output [N - 1:0] q;
	reg [N - 1:0] q;
	always @(posedge clk or negedge rst)
		if (!rst)
			q <= 0;
		else if (load)
			q <= d;
		else if (inc)
			q <= q + 1;
endmodule

module stack(clk, rst, load, push, pop, d, qtop, qnext);
	parameter N = 8;
	input clk,
		rst,
		load,
		push,
		pop;
	input [15:0] d;
	output [15:0] qtop,
		qnext;
	reg [15:0] q[0:N - 1];
	assign qtop = q[0];
	assign qnext = q[1];
	always @(posedge clk or negedge rst)
		if (!rst)
			q[0] <= 0;
		else if (load)
			q[0] <= d;
		else if (pop)
			q[0] <= q[1];
	integer i;
	always @(posedge clk or negedge rst)
		for (i = 1; i < N - 1; i = i + 1)
			if (!rst)
				q[i] <= 0;
			else if (push)
				q[i] <= q[i - 1];
			else if (pop)
				q[i] <= q[i + 1];
	always @(posedge clk or negedge rst)
		if (!rst)
			q[N - 1] <= 0;
		else if (push)
			q[N - 1] <= q[N - 2];
endmodule

module ram(clk, load, addr, d, q);
	parameter DWIDTH = 16,
		AWIDTH = 12,
		WORDS = 4096;
	input clk,
		load;
	input [AWIDTH - 1:0] addr;
	input [DWIDTH - 1:0] d;
	output [DWIDTH - 1:0] q;
	reg [DWIDTH - 1:0] q;
	reg [DWIDTH - 1:0] mem[WORDS - 1:0];
	always @(posedge clk)
	begin
		if (load)
			mem[addr] <= d;
		q <= mem[addr];
	end
	initial
	begin
		mem[0] =  16'h1032;//push 9
		mem[1] =  16'h1005;//push 3
		mem[2] =  16'hf000;//+
		mem[3] =  16'he000;//out
		mem[4] =  16'hf000;//+
		mem[5] =  16'h4000;//jp 5
	end
endmodule

module alu(a, b, f, s);
	input [15:0] a,
		b;
	input [4:0] f;
	output [15:0] s;
	reg [15:0] s;
	wire [15:0] x,
		y;
	assign x = a + 16'h8000;
	assign y = b + 16'h8000;
	always @(a or b or x or y or f)
		case (f)
		`ADD:
			s = b + a;
		`SUB:
			s = b - a;
		`MUL:
			s = b * a;
		`SHL:
			s = b << a;
		`SHR:
			s = b >> a;
		`BAND:
			s = b & a;
		`BOR:
			s = b | a;
		`BXOR:
			s = b ^ a;
		`AND:
			s = b && a;
		`OR:
			s = b || a;
		`EQ:
			s = b == a;
		`NE:
			s = b != a;
		`GE:
			s = y >= x;
		`LE:
			s = y <= x;
		`GT:
			s = y > x;
		`LT:
			s = y < x;
		`NEG:
			s = -a;
		`BNOT:
			s = ~a;
		`NOT:
			s = !a;
		default:
			s = 16'hxxxx;
		endcase
endmodule

module state(clk, rst, ed, cont, halt, cs);
	input clk,
		rst,
		ed,
		cont,
		halt;
	output [2:0] cs;
	reg [2:0] cs;
	always @(posedge clk or negedge rst)
		if (!rst)
			cs <= `IDLE;
		else if (!ed)
			cs <= `IDLE;
		else
			case (cs)
			`IDLE:
				cs <= `FETCHA;
			`FETCHA:
				cs <= `FETCHB;
			`FETCHB:
				cs <= `EXECA;
			`EXECA:
				if (halt)
					cs <= `IDLE;
				else if (cont)
					cs <= `EXECB;
				else
					cs <= `FETCHA;
			`EXECB:
				cs <= `FETCHA;
			default:
				cs <= 3'bxxxx;
			endcase
endmodule

module test2(input clk, input rst, output tx, output [11:0] pcout, output reg led2 = 0);
	reg [15:0] in;
	wire [2:0] cs;
	wire [15:0] irout,
		qtop,
		dbus;
	wire [15:0] qnext,
		ramout,
		aluout;
	reg [11:0] abus;
	reg halt,
		cont,
		pcinc,
		push,
		pop,
		abus2pc,
		dbus2ir,
		dbus2qtop,
		dbus2ram,
		dbus2obuf,
		pc2abus,
		ir2abus,
		ir2dbus,
		qtop2dbus,
		alu2dbus,
		ram2dbus,
		in2dbus;
	reg send = 0;
	counter #(12) pcb0(.clk(clk), .rst(rst), .load(abus2pc), .inc(pcinc), .d(abus), .q(pcout));
	counter #(16) outb0(.clk(clk), .rst(rst), .load(dbus2obuf), .inc(0), .d(dbus), .q(out));
	counter #(16) irb0(.clk(clk), .rst(rst), .load(dbus2ir), .inc(0), .d(dbus), .q(irout));
	state irq0(.clk(clk), .rst(rst), .ed(ed), .cont(cont), .halt(halt), .cs(cs));
	stack stack0(.clk(clk), .rst(rst), .load(dbus2qtop), .push(push), .pop(pop), .d(dbus), .qtop(qtop), .qnext(qnext));
	alu alu0(.a(qtop), .b(qnext), .f(irout[4:0]), .s(aluout));
	ram ram0(.clk(clk), .load(dbus2ram), .addr(abus[11:0]), .d(dbus), .q(ramout));
	tx1 tx1(.clk(clk), .rst(rst), .send(dbus2obuf), .data(dbus), .tx(tx), .ed(ed));
	assign dbus = ir2dbus ? {{4{irout[11]}}, irout[11:0]} : 16'hzzzz;
	assign dbus = qtop2dbus ? qtop : 16'hzzzz;
	assign dbus = alu2dbus ? aluout : 16'hzzzz;
	assign dbus = ram2dbus ? ramout : 16'hzzzz;
	assign dbus = in2dbus ? in : 16'hzzzz;
	always @(pc2abus or ir2abus or pcout or irout)
		if (pc2abus)
			abus <= pcout;
		else if (ir2abus)
			abus <= irout[11:0];
		else
			abus <= 12'hxxx;
	always @(cs or irout or qtop)
	begin
		halt = 0;
		pcinc = 0;
		push = 0;
		pop = 0;
		cont = 0;
		abus2pc = 0;
		dbus2ir = 0;
		dbus2qtop = 0;
		dbus2ram = 0;
		dbus2obuf = 0;
		pc2abus = 0;
		ir2abus = 0;
		ir2dbus = 0;
		qtop2dbus = 0;
		alu2dbus = 0;
		ram2dbus = 0;
		in2dbus = 0;
		send = 0;
		if (cs == `FETCHA)
		begin
			pcinc = 1;
			pc2abus = 1;
		end
		else if (cs == `FETCHB)
		begin
			ram2dbus = 1;
			dbus2ir = 1;
		end
		else if (cs == `EXECA)
			case (irout[15:12])
			`PUSHI:
			begin
				ir2dbus = 1;
				dbus2qtop = 1;
				push = 1;
			end
			`PUSH:
			begin
				ir2abus = 1;
				cont = 1;
			end
			`POP:
			begin
				ir2abus = 1;
				qtop2dbus = 1;
				dbus2ram = 1;
				pop = 1;
			end
			`JMP:
			begin
				ir2abus = 1;
				abus2pc = 1;
			end
			`JZ:
			begin
				if (qtop == 0)
				begin
					ir2abus = 1;
					abus2pc = 1;
				end
				pop = 1;
			end
			`JNZ:
			begin
				if (qtop != 0)
				begin
					ir2abus = 1;
					abus2pc = 1;
				end
				pop = 1;
			end
			`IN:
			begin
				in2dbus = 1;
				dbus2qtop = 1;
				push = 1;
			end
			`OUT:
			begin
				qtop2dbus = 1;
				dbus2obuf = 1;
				pop = 1;
				send = 1;
			end
			`OP:
			begin
				alu2dbus = 1;
				dbus2qtop = 1;
				if (irout[4] == 0)
					pop = 1;
			end
			default:
				halt = 1;
			endcase
		else if (cs == `EXECB)
			if (irout[15:12] == `PUSH)
			begin
				ram2dbus = 1;
				dbus2qtop = 1;
				push = 1;
			end
		
	end
endmodule



```

以上。