⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nios_0.v

📁 和NIOS功能一样的CPU
💻 V
📖 第 1 页 / 共 5 页
字号:
		// State CHECK_PFX skips (does not commit) any PFX instructions and an instruction
		// following the PFX
		CHECK_PFX:
		begin
			// If the instruction is not available wait for it
			if (ctrl_en == 0)
			begin
				d_read = 0;
				d_write = 0;
				decrement_cwp = 0;
				disable_interrupts = 0;
				flush_fifo = 0;
				force_interrupt = 0;
				force_trap_1 = 0;
				force_trap_2 = 0;
				increment_cwp = 0;
				read_next = 1;
				reg_write = 0;
				skip = 1;
				next_state = CHECK_PFX;
			end
			else
			begin
				d_read = 0;
				d_write = 0;
				decrement_cwp = 0;
				disable_interrupts = 0;
				force_interrupt = 0;
				force_trap_1 = 0;
				force_trap_2 = 0;
				increment_cwp = 0;
				read_next = 1;
				reg_write = 0;
				skip = 1;
				// If the instruction is PFX, skip one more instruction
				if (pfx)
				begin
					flush_fifo = 0;
					next_state = CHECK_PFX;
				end
				else
				begin
					// Else do not commit this instruction, and continue execution with the next one
					if (next_is_ctrl_flow_instr) flush_fifo = 1;
					else flush_fifo = 0;
					next_state = READ_AND_EXECUTE;
				end
			end
		end
		// LOAD state waits for the data to become available from memory, and sets signal to write
		// it to the register file
		LOAD:
		begin
			d_write = 0;
			decrement_cwp = 0;
			disable_interrupts = 0;
			flush_fifo = 0;
			force_interrupt = 0;
			force_trap_1 = 0;
			force_trap_2 = 0;
			increment_cwp = 0;
			skip = 0;
			d_read = 1;
			// If d_wait signal is set, the data is not ready from memory
			if (d_wait == 1)
			begin
				read_next = 0;
				reg_write = 0;
				next_state = LOAD;
			end
			else // Otherwise the data is ready, and needs to be captured by the register file
			begin
				read_next = 1;
				reg_write = 1;
				next_state = READ_AND_EXECUTE;
				if (next_is_ctrl_flow_instr) flush_fifo = 1;
			end
		end
		// STORE state waits for the data to be written to memory
		STORE:
		begin
			d_read = 0;
			d_write = 1;
			decrement_cwp = 0;
			disable_interrupts = 0;
			flush_fifo = 0;
			force_interrupt = 0;
			force_trap_1 = 0;
			force_trap_2 = 0;
			increment_cwp = 0;
			reg_write = 0;
			skip = 0;
			// If d_wait signal is set, the data has not yet been written to memory
			if (d_wait == 1)
			begin
				read_next = 0;
				next_state = STORE;
			end
			else
			begin
				read_next = 1;
				next_state = READ_AND_EXECUTE;
			end
		end
		// TRAP state waits for the target address to be fetced from the vector table in memory
		TRAP:
		begin
			//Handling the TRAP instruction
			d_read = 1;
			d_write = 0;
			decrement_cwp = 0;
			disable_interrupts = 0;
			force_interrupt = 0;
			force_trap_1 = 0;
			force_trap_2 = 0;
			increment_cwp = 0;
			reg_write = 0;
			skip = 0;
			// If d_wait signal is set, the data is not ready from memory
			if (d_wait == 1)
			begin
				flush_fifo = 0;
				read_next = 0;
				next_state = TRAP;
			end
			// Otherwise, the data is available, and prefetch unit can start fetching from the
			// target address
			else
			begin
				flush_fifo = 1;
				read_next = 1;
				next_state = READ_AND_EXECUTE;
			end
		end
		// Default section prevents the latch to be inferred
		default:
		begin
			d_read = 1'bx;
			d_write = 1'bx;
			decrement_cwp = 1'bx;
			disable_interrupts = 1'bx;
			flush_fifo = 1'bx;
			force_interrupt = 1'bx;
			force_trap_1 = 1'bx;
			force_trap_2 = 1'bx;
			increment_cwp = 1'bx;
			read_next = 1'bx;
			reg_write = 1'bx;
			skip = 1'bx;
			next_state = STATE_X;
		end 
		endcase
	end

	// Mealy-type FSM - sequential part
	always @ (posedge clk or negedge reset_n)
	begin
		if (reset_n == 0)
		begin
			state <= READ_AND_EXECUTE;
		end
		else
		begin
			state <= next_state;
		end
	end
	
endmodule
//control_unit***************************************************************

//***************************************************************************
//	datapath
//
//	Module datapath instantaites all the modules of the datapath
//	(pipeline stages and pipeline registers)
//
module datapath (
	// inputs
	clk,
	current_reg_write_en,
	d_irqnumber,
	d_readdata,
	decrement_cwp,
	disable_interrupts,
	flush_pipeline,
	flush_fifo,
	force_interrupt,
	force_read,
	force_trap_1,
	force_trap_2,
	i_datavalid,
	i_readdata,
	i_wait,
	increment_cwp,
	interrupt,
	keep_pc,
	load_nops,
	pending_interrupt,
	read_next,
	reset_n,
	save_status,
	skip,

	// outputs
	ctrl_en,
	cwp_is_hi_limit,
	cwp_is_lo_limit,
	d_address,
	d_byteenable,
	d_writedata,
	decoded_instr,
	i_address,
	i_flush,
	i_read,
	ir,
	ld,
	next_is_ctrl_flow_instr,
	next_is_restore,
	next_is_save,
	next_is_wrctl,
	pfx,
	RA,
	restore,
	save,
	skp0,
	skp1,
	skprnz,
	skprz,
	skps,
	st,
	status_reg,
	trap,
	tret
	);
	parameter LOG_REGISTER_FILE_SIZE = 9;
	parameter START_ADDRESS = 32'h8000;
	parameter VECTOR_TABLE_ADDRESS = 32'h7780;
	parameter FIFO_SIZE = 2;

	input 			clk;
	input 			current_reg_write_en;
	input [5:0] 	d_irqnumber;
	input [31:0]	d_readdata;
	input 			decrement_cwp;
	input 			disable_interrupts;
	input 			flush_pipeline;
	input 			flush_fifo;
	input 			force_interrupt;
	input 			force_read;
	input 			force_trap_1;
	input 			force_trap_2;
	input 			i_datavalid;
	input [15:0]	i_readdata;
	input 			i_wait;
	input 			increment_cwp;
	input 			interrupt;
	input 			keep_pc;
	input 			load_nops;
	input 			pending_interrupt;
	input 			read_next;
	input 			reset_n;
	input 			save_status;
	input			skip;

	output			ctrl_en;
	output			cwp_is_hi_limit;
	output			cwp_is_lo_limit;
	output [31:0] 	d_address;
	output [3:0]	d_byteenable;
	output [31:0] 	d_writedata;
	output [23:0]	decoded_instr;
	output [31:0] 	i_address;
	output 			i_flush;
	output 			i_read;
	output [15:0]	ir;
	output 			ld;
	output 			next_is_ctrl_flow_instr;
	output 			next_is_restore;
	output 			next_is_save;
	output 			next_is_wrctl;
	output 			pfx;
	output [31:0]	RA;
	output 			restore;
	output 			save;
	output 			skp0;
	output 			skp1;
	output 			skprnz;
	output 			skprz;
	output 			skps;
	output 			st;
	output [17:0]	status_reg;
	output 			trap;
	output 			tret;

	wire [31:0]							branch_logic_pc;
	wire 								cpu_continue_running;
	wire [31:0]							current_reg_data_in;
	wire [`LOG_REGISTER_FILE_SIZE-1:0]	current_reg_write_address_in;
	wire [4:0]							cwp;
	wire [4:0]							cwp_for_check;
	wire [4:0]							cwp_minus_1;
	wire 								fifo_datavalid;
	wire 								flush_o_x;
	wire [15:0]							i_from_fifo;
	wire [10:0]							K;
	wire 								next_is_trap;
	wire								next_is_tret;
	wire 								s2_ctrl_flow_instr;
	wire [23:0] 						s2_decoded_instr;
	wire [15:0] 						s2_ir;
	wire [`LOG_REGISTER_FILE_SIZE-1:0]  s2_reg_a_address;
	wire [31:0] 						s2_reg_a_data_out;
	wire [`LOG_REGISTER_FILE_SIZE-1:0]  s2_reg_b_address;
	wire [31:0] 						s2_reg_b_data_out;
	wire [`LOG_REGISTER_FILE_SIZE-1:0]  s2_reg_write_address_out;
	wire								s3_ctrl_flow_instr;
	wire [3:0]  						s3_ctrl_reg_address;
	wire [23:0] 						s3_decoded_instr;
	wire [15:0] 						s3_ir;
	wire [31:0] 						s3_mux_a_data_out;
	wire [31:0] 						s3_mux_b_data_out;
	wire [31:0] 						s3_npc;
	wire [31:0]							s3_pc;
	wire [31:0] 						s3_pc_plus_4;
	wire [`LOG_REGISTER_FILE_SIZE-1:0]  s3_reg_a_address;
	wire [`LOG_REGISTER_FILE_SIZE-1:0]  s3_reg_b_address;
	wire [31:0] 						s3_reg_a_data_out;
	wire [31:0] 						s3_reg_b_data_out;
	wire [`LOG_REGISTER_FILE_SIZE-1:0]  s3_reg_write_address_out;
	wire [3:0]  						s4_ctrl_reg_address;
	wire [23:0] 						s4_decoded_instr;
	wire [15:0] 						s4_ir;
	wire [31:0] 						s4_mux_a_data_out;
	wire [31:0] 						s4_mux_b_data_out;
	wire [31:0] 						s4_npc;
	wire [31:0] 						s4_pc;
	wire [31:0] 						s4_pc_plus_4;
	wire [31:0] 						s4_reg_a_data_out;
	wire [31:0] 						s4_reg_b_data_out;
	wire [`LOG_REGISTER_FILE_SIZE-1:0]  s4_reg_write_address_out;
	wire 								s4_trap;
	wire								s4_tret;
	wire [9:0] 							wvalid_for_check;


	// cpu_continue_running is the opposite of stall signal (which does not really exist)
	// The execution continues normally, as long as the control unit confirms that the current
	// instruction has been executed, and the new one should be read (read_next), new instruction
	// is actually available from the fifo (fifo_datavalid), and the fifo is not being flushed
	// by the control-flow instruction
	assign cpu_continue_running	= read_next & fifo_datavalid & ~flush_fifo;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -