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

📄 nios_0.v

📁 和NIOS功能一样的CPU
💻 V
📖 第 1 页 / 共 5 页
字号:
		4'b1010: skip_condition = status [2];	//V
		4'b1011: skip_condition = ~status [2];	//~V
		4'b1100: skip_condition = status [0] | status [1];	//C or Z
		4'b1101: skip_condition = ~(status [0] | status [1]);	//~ (C or Z)
		default: skip_condition = 1'bx;
		endcase
	end

	
	// Mealy-type FSM - combinational part
	// The following signals are controlled directly by an FSM:
	//	d_read				- d_read signal that is fed to the Avalon bus
	//	d_write				- d_write signal that is fed to the Avalon bus
	//	decrement_cwp		- signals that CWP should be decremented because of SAVE or TRAP
	//	disable_interrupts	- sinnals that interrupts should be disabled because an interrupt
	//						  is just being accepted
	//	flush_fifo			- signals that the prefetch FIFO buffer should be flushed
	//						  because of a control-flow instruction
	//	force_interrupt		- signals that a TRAP instruction with number d_irqnumber
	//						  should be pushed inte the pipeline
	//	force_trap_1		- signals that TRAP 1 should be pushed into pipeline
	//	force_trap_2		- signals that TRAP 2 should be pushed into pipeline
	//	increment_cwp		- signals that CWP should be incremented because of RESTORE
	//	read_next			- signals that the instruction currently in the execute stage
	//						  has finished execution, and the next instruction can be read
	//	reg_write			- write-enable signal for the register file
	//	skip				- signals that the instruction currently in the execute stage
	//						  is being skipped
	always @ (*)
	begin
		case (state)
		// State READ_AND_EXECUTE is a central state where most of the instructions are handled
		READ_AND_EXECUTE:
		begin
			// If there is an interrupt request, handle it
			// Notice that interrupts are only handled in READ_AND_EXECUTE stage
			if (interrupt_reg == 1)
			begin
				d_read = 0;
				d_write = 0;
				decrement_cwp = 0;	// It will be done when TRAP gets into the pipeline
				disable_interrupts = 1;
				flush_fifo = 0;
				force_interrupt = 1;
				force_trap_1 = 0;
				force_trap_2 = 0;
				increment_cwp = 0;
	 			read_next = 1;
				reg_write = 0;
				skip = 0;
				next_state = READ_AND_EXECUTE;
			end
			// If the instruction is not available, wait for it
			else 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 = 0;
				next_state = READ_AND_EXECUTE;
			end
			else
			begin
				// Perform the operations appropriate for a given instruction type
				// Many signals are set to 0 here, but are overridden later in the code
				// (by Verilog semantics, only the last assignment is valid)
				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;
				// Register write needs to be enabled only for instructions that write the value
				// to the register (this information is encoded in the two lowest bits of the
				// decoded instruction (see instruction decoder signals for further explanation)
				reg_write = (decoded_instr[1] | decoded_instr[0]);
				// If the instruction is a skip check the condition
				if (skprnz) // SKPRNZ
				begin
					read_next = 1;
					if (RA != 32'b0)
					begin
						flush_fifo = 0;
						skip = 1;
						next_state = CHECK_PFX;
					end
					else	// If the skip condition is not satisfied, continue with execution
					begin
						// FIFO has to be flushed if the instruction in the operand stage is
						// a control-flow instruction
						flush_fifo = next_is_ctrl_flow_instr;
						skip = 0;
						next_state = READ_AND_EXECUTE;
					end
				end
				else if (skprz)	// SKPRZ
				begin
					read_next = 1;
					if (RA == 32'b0)
					begin
						flush_fifo = 0;
						skip = 1;
						next_state = CHECK_PFX;
					end
					else	// If the skip condition is not satisfied, continue with execution
					begin
						flush_fifo = next_is_ctrl_flow_instr;
						skip = 0;
						next_state = READ_AND_EXECUTE;
					end
				end
				else if (skp1) // SKP1
				begin
					read_next = 1;
					// Condition for SKP1 is RA[imm5]==1
					if (RA[ir[9:5]] == 1)
					begin
						flush_fifo = 0;
						skip = 1;
						next_state = CHECK_PFX;
					end
					else // If the skip condition is not satisfied, continue with execution
					begin
						flush_fifo = next_is_ctrl_flow_instr;
						skip = 0;
						next_state = READ_AND_EXECUTE;
					end
				end
				else if (skp0)	// SKP0
				begin
					read_next = 1;
					// Condition for SKP0 is RA[imm5]==0
					if (RA[ir[9:5]] == 0)
					begin
						flush_fifo = 0;
						skip = 1;
						next_state = CHECK_PFX;
					end
					else // If the skip condition is not satisfied, continue with execution
					begin
						flush_fifo = next_is_ctrl_flow_instr;
						skip = 0;
						next_state = READ_AND_EXECUTE;
					end
				end
				else if (skps)	// SKPS
				begin
					read_next = 1;
					// Skip is performed or not, based on the encoded condition
					// If the skip condition is satisfied, the next instruction is skipped
					if (skip_condition == 1)
					begin
						flush_fifo = 0;
						skip = 1;
						next_state = CHECK_PFX;
					end
					else	// If the skip condition is not satisfied, continue with execution
					begin
						flush_fifo = next_is_ctrl_flow_instr;
						skip = 0;
						next_state = READ_AND_EXECUTE;
					end
				end
				else if (save)
				begin
					// SAVE instruction
					d_read = 0;
					d_write = 0;
					increment_cwp = 0;
					read_next = 1;
					skip = 0;
					// If cwp == lo_limit, we need to call TRAP #1
					if (cwp_is_lo_limit)
					begin
						// But only if the underflow should be handled (interrupts are enabled, and
						// IPRI is greater than 1)
						if (handle_underflow)
						begin
							decrement_cwp = 0; // It will be done when TRAP gets to pipeline
							disable_interrupts = 1;
							flush_fifo = 0; // If SAVE causes trap, possible branch after it shouldn't be executed
							force_trap_1 = 1;
							read_next = 1; // We read the instruction being pushed into the pipeline
							next_state = READ_AND_EXECUTE;
						end
						else // Otherwise the underflow is not handled, and the execution resumes normally
						begin
							decrement_cwp = 1;
							disable_interrupts = 0;
							flush_fifo = next_is_ctrl_flow_instr;
							force_trap_1 = 0;
							read_next = 1;
							next_state = READ_AND_EXECUTE;
						end
					end
					else // Otherwise there is no underflow to handle, and the execution resumes normally
					begin
						decrement_cwp = 1;
						disable_interrupts = 0;
						flush_fifo = next_is_ctrl_flow_instr;
						force_trap_1 = 0;
						read_next = 1;
						next_state = READ_AND_EXECUTE;
					end
				end
				else if (restore)
				begin
					// RESTORE instruction
					d_read = 0;
					d_write = 0;
					decrement_cwp = 0;
					skip = 0;
					// If cwp == hi_limit, we need to call TRAP #2
					if (cwp_is_hi_limit)
					begin
						// But only if overflows should be handled (interrupts are enabled, and
						// IPRI is greater than 2)
						if (handle_overflow)
						begin
							disable_interrupts = 1;
							flush_fifo = 0; // If RESTORE causes trap, possible branch after it shouldn't be executed
							force_trap_2 = 1;
							increment_cwp = 1; // It will be decreased when TRAP gets to pipeline
							read_next = 1; // So we read the instruction being pushed into pipeline
							next_state = READ_AND_EXECUTE;
						end
						else // Otherwise the overflow is not handled, and the execution resumes normally
						begin
							disable_interrupts = 0;
							flush_fifo = next_is_ctrl_flow_instr;
							force_trap_2 = 0;
							increment_cwp = 1;
							read_next = 1;
							next_state = READ_AND_EXECUTE;
						end
					end
					else // Otherwise there is no overflow to handle, and the execution resumes normally
					begin
						disable_interrupts = 0;
						flush_fifo = next_is_ctrl_flow_instr;
						force_trap_2 = 0;
						increment_cwp = 1;
						read_next = 1;
						next_state = READ_AND_EXECUTE;
					end
					
				end
				else if (trap)
				begin
					//TRAP instruction
					d_read = 1;
					d_write = 0;
					decrement_cwp = 1;
					disable_interrupts = 1;
					flush_fifo = 0;
					increment_cwp = 0;
					read_next = 0;
					skip = 0;
					next_state = TRAP;
				end
				else if (tret)
				begin
					//TRET instruction
					d_read = 0;
					d_write = 0;
					decrement_cwp = 0;
					flush_fifo = 0;
					increment_cwp = 0;
					read_next = 1;
					skip = 0;
					next_state = READ_AND_EXECUTE;					
				end
				else if (ld)
				begin
					//One of the LD instructions
`ifdef ZERO_LATENCY
					d_read = 0;
					flush_fifo = 0;
					skip = 0;
					if (d_wait == 1)
					begin
						read_next = 0;
						reg_write = 0;
						next_state = LOAD;
					end
					else
					begin
						if (next_is_ctrl_flow_instr) flush_fifo = 1;
						read_next = 1;
						// Write the value from memory into the register file
						reg_write = 1;
						next_state = READ_AND_EXECUTE;
					end
`else
					d_read = 1;
					flush_fifo = 0;
					read_next = 0;
					skip = 0;
					next_state = LOAD;
`endif
				end
				else if (st)
				begin
					//One of the ST instructions
`ifdef ZERO_LATENCY
					d_write = 1;
					flush_fifo = next_is_ctrl_flow_instr;
					skip = 0;
					if (d_wait == 1)
					begin
						read_next = 0;
						next_state = STORE;
					end
					else
					begin
						read_next = 1;
						next_state = READ_AND_EXECUTE;
					end
`else
					d_write = 1;
					flush_fifo = next_is_ctrl_flow_instr;
					read_next = 0;
					skip = 0;
					next_state = STORE;
`endif
				end
				else
				begin
					// All other instructions are handled with the same signal values
					d_read = 0;
					d_write = 0;
					decrement_cwp = 0;
					flush_fifo = next_is_ctrl_flow_instr;
					increment_cwp = 0;
					read_next = 1;
					skip = 0;
					next_state = READ_AND_EXECUTE;
				end
			end
		end

⌨️ 快捷键说明

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