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?

More than 3 years have passed since last update.

俺cpuAdvent Calendar 2020

Day 2

vistaでquartus その7

Last updated at Posted at 2020-06-20

#概要

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

#環境

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

#写真

image

#サンプルコード





`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



以上。

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?