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

📄 nios_0.v

📁 和NIOS功能一样的CPU
💻 V
📖 第 1 页 / 共 5 页
字号:
	// The address of the register that should be written to is stored in the o_x
	// pipeline registers (s4_reg_write_address_out)
	assign current_reg_write_address_in = s4_reg_write_address_out;
	// Byteenable defines which bytes should be stored to the memory when store instruction
	// commits, depending on the type of the instruction. Byte is stored for ST8S, ST8D, and
	// STS8S instruction, halfword for ST16S, ST16D, and STS16S instruction, and word for
	// all other store instructions. Which byte (or halfword) is read is encoded in the
	// instruction word for ST8S, ST16S, STS8S, and STS16S instruction, and in register A
	// for ST8D and ST16D instruction.
	assign d_byteenable = 
		//ST8S
		(ir[15:7] == 9'b011101100) ? {(ir[6] & ir[5]), (ir[6] & ~ir[5]), (~ir[6] & ir[5]), (~ir[6] & ~ir[5])} :
		//ST16S
		(ir[15:7] == 9'b011101101) ? {ir[6], ir[6], ~ir[6], ~ir[6]} :
		//STS8S
		(ir[15:10] == 6'b011000) ? {(ir[1] & ir[0]), (ir[1] & ~ir[0]), (~ir[1] & ir[0]), (~ir[1] & ~ir[0])} :
		//STS16S
		(ir[15:10] == 6'b011001) ? {ir[1], ir[1], ~ir[1], ~ir[1]} :
		//ST8D
		(ir[15:5] == 11'b01111110000) ? {(RA[1] & RA[0]), (RA[1] & ~RA[0]), (~RA[1] & RA[0]), (~RA[1] & ~RA[0])} :
		//ST16D
		(ir[15:5] == 11'b01111110001) ? {RA[1], RA[1], ~RA[1], ~RA[1]} :
		//any other instruction
		4'b1111;
	// Instructions STS8S, STS16S, ST8S, ST16S, ST8D, ST16D write the contents of the register %r0
	// to memory, which is read as reg_b from the register file. Other instructions write reg_a.
	assign d_writedata = (s4_decoded_instr[3:2] == 2'b11) ? s4_reg_b_data_out : s4_reg_a_data_out;
	assign decoded_instr = s4_decoded_instr;
	assign ir = s4_ir;
	// force_read is equivalent to force_interrupt | force_trap_1 | force_trap_2
	// Therefore, last stage of the pipeline will be flushed when overflow/underflow, or interrupt happens
	// It will also be flushed on TRET instruction, since it doesn't have a delay slot
	assign flush_o_x = force_read | s4_tret | pending_interrupt;
	// Next is ctrl. flow instr. also for the TRET instruction
	assign next_is_ctrl_flow_instr = s3_ctrl_flow_instr | next_is_tret;
	// Refer to the instruction decoder for the explanation of the following set of signals
	assign next_is_restore = s3_decoded_instr[10] & ~s3_decoded_instr[9];
	assign next_is_save = ~s3_decoded_instr[10] & s3_decoded_instr[9];
	assign next_is_trap = ~s3_decoded_instr[14] & ~s3_decoded_instr[13] & s3_decoded_instr[11];
	assign next_is_tret = ~s3_decoded_instr[14] & ~s3_decoded_instr[13] & s3_decoded_instr[12] & ~s3_decoded_instr[11];
	assign next_is_wrctl = (s3_decoded_instr[17:15] == 3'b101);
	assign RA = s4_reg_a_data_out;
	assign s4_trap =  ~s4_decoded_instr[14] & ~s4_decoded_instr[13] & s4_decoded_instr[11];
	assign s4_tret = ~s4_decoded_instr[14] & ~s4_decoded_instr[13] & s4_decoded_instr[12] & ~s4_decoded_instr[11];


	prefetch_unit the_pipeline_stage_1 (
		// inputs
		.clk 							(clk),			
		.cpu_s_read_address				(branch_logic_pc),		
		.cpu_wants_to_read				(read_next),
		.d_irqnumber					(d_irqnumber),
		.data_in_from_memory			(i_readdata),
		.data_is_valid_from_memory		(i_datavalid),
		.flush_fifo						(flush_fifo),
		.flush_pipeline					(flush_pipeline),
		.force_interrupt 				(force_interrupt),
		.force_trap_1					(force_trap_1),
		.force_trap_2					(force_trap_2),
		.load_nops						(load_nops),
		.memory_requests_wait			(i_wait),	
		.reset_n						(reset_n),

		// outputs
		.data_out_to_cpu				(i_from_fifo),
		.flush_memory					(i_flush),
		.memory_address_to_read			(i_address),
		.prefetch_unit_has_valid_data	(fifo_datavalid),
		.read_memory					(i_read)
	);
	defparam the_pipeline_stage_1.START_ADDRESS = START_ADDRESS;
	defparam the_pipeline_stage_1.FIFO_SIZE = FIFO_SIZE;

	pipeline_stage_2 the_pipeline_stage_2(
		// inputs
		.clk					(clk),
		.cpu_continue_running	(cpu_continue_running),
		.cwp					(cwp),
		.cwp_minus_1			(cwp_minus_1),
		.d_irqnumber			(d_irqnumber),
		.fifo_datavalid			(fifo_datavalid),
		.flush_fifo				(flush_fifo),
		.flush_pipeline			(flush_pipeline),
		.force_read				(force_read),
		.i_from_fifo			(i_from_fifo),
		.load_nops				(load_nops),
		.read_next				(read_next),
		.reg_data_in			(current_reg_data_in),
		.reg_write_address_in	(current_reg_write_address_in),
		.reg_write_en			(current_reg_write_en),
		.reset_n				(reset_n),
		.s3_tret				(next_is_tret),

		// outputs
		.ctrl_en				(ctrl_en),
		.ctrl_flow_instr		(s2_ctrl_flow_instr),
		.decoded_instr			(s2_decoded_instr),
		.ir						(s2_ir),
		.reg_a_address			(s2_reg_a_address),
		.reg_a_data_out			(s2_reg_a_data_out),
		.reg_b_address			(s2_reg_b_address),
		.reg_b_data_out			(s2_reg_b_data_out),
		.reg_write_address_out	(s2_reg_write_address_out)
	);
	defparam the_pipeline_stage_2.LOG_REGISTER_FILE_SIZE = LOG_REGISTER_FILE_SIZE;

	d_o_registers the_d_o_registers(
		// inputs
		.clk						(clk),
		.cpu_continue_running		(cpu_continue_running),
		.flush_pipeline				(flush_pipeline),
		.reset_n					(reset_n),
		.s2_ctrl_flow_instr			(s2_ctrl_flow_instr),
		.s2_decoded_instr			(s2_decoded_instr),
		.s2_ir						(s2_ir),
		.s2_reg_a_address			(s2_reg_a_address),
		.s2_reg_b_address			(s2_reg_b_address),
		.s2_reg_write_address_out	(s2_reg_write_address_out),

		// outputs
		.s3_ctrl_flow_instr			(s3_ctrl_flow_instr),
		.s3_decoded_instr			(s3_decoded_instr),
		.s3_ir						(s3_ir),
		.s3_reg_a_address			(s3_reg_a_address),
		.s3_reg_b_address			(s3_reg_b_address),
		.s3_reg_write_address_out	(s3_reg_write_address_out)
	);

	pipeline_stage_3 the_pipeline_stage_3(
		// inputs
		.clk					(clk),
		.cpu_continue_running	(cpu_continue_running),
		.ctrl_en				(ctrl_en),
		.ctrl_flow_instr		(next_is_ctrl_flow_instr),
		.d_readdata				(d_readdata),
		.decoded_instr			(s3_decoded_instr),
		.fifo_datavalid			(fifo_datavalid),
		.flush_fifo				(flush_fifo),
		.ir						(s3_ir),
		.keep_pc				(keep_pc),
		.reg_a_address			(s3_reg_a_address),
		.reg_a_data_out			(s2_reg_a_data_out),
		.reg_b_address			(s3_reg_b_address),
		.reg_b_data_out			(s2_reg_b_data_out),
		.reg_write_address		(current_reg_write_address_in),
		.reg_write_data			(current_reg_data_in),
		.reg_write_en			(current_reg_write_en),
		.reset_n				(reset_n),
		.s4_trap				(s4_trap),
		.tret					(next_is_tret),

		// outputs
		.branch_logic_out		(branch_logic_pc),
		.ctrl_reg_address		(s3_ctrl_reg_address),
		.K						(K),
		.mux_a_data_out			(s3_mux_a_data_out),
		.mux_b_data_out			(s3_mux_b_data_out),
		.npc 					(s3_npc),
		.pc						(s3_pc),
		.pc_plus_4				(s3_pc_plus_4),
		.s3_reg_a_data_out		(s3_reg_a_data_out),
		.s3_reg_b_data_out		(s3_reg_b_data_out)
	);
	defparam the_pipeline_stage_3.VECTOR_TABLE_ADDRESS = VECTOR_TABLE_ADDRESS;
	defparam the_pipeline_stage_3.START_ADDRESS = START_ADDRESS;

	o_x_registers the_o_x_registers(
		// inputs
		.clk						(clk),
		.cpu_continue_running		(cpu_continue_running),
		.cwp						(cwp_for_check),
		.flush_pipeline				(flush_o_x),
		.hi_limit					(wvalid_for_check[9:5]),
		.lo_limit					(wvalid_for_check[4:0]),
		.reset_n					(reset_n),
		.s3_ctrl_reg_address		(s3_ctrl_reg_address),
		.s3_decoded_instr			(s3_decoded_instr),
		.s3_ir						(s3_ir),
		.s3_mux_a_data_out			(s3_mux_a_data_out),
		.s3_mux_b_data_out			(s3_mux_b_data_out),
		.s3_npc 					(s3_npc),
		.s3_pc						(s3_pc),
		.s3_pc_plus_4				(s3_pc_plus_4),
		.s3_reg_a_data_out			(s3_reg_a_data_out),
		.s3_reg_b_data_out			(s3_reg_b_data_out),
		.s3_reg_write_address_out	(s3_reg_write_address_out),

		// outputs
		.s4_ctrl_reg_address		(s4_ctrl_reg_address),
		.s4_cwp_is_hi_limit			(cwp_is_hi_limit),
		.s4_cwp_is_lo_limit			(cwp_is_lo_limit),
		.s4_decoded_instr			(s4_decoded_instr),
		.s4_ir						(s4_ir),
		.s4_ld						(ld),
		.s4_mux_a_data_out			(s4_mux_a_data_out),
		.s4_mux_b_data_out			(s4_mux_b_data_out),
		.s4_npc 					(s4_npc),
		.s4_pc						(s4_pc),
		.s4_pc_plus_4				(s4_pc_plus_4),
		.s4_pfx						(pfx),
		.s4_reg_a_data_out			(s4_reg_a_data_out),
		.s4_reg_b_data_out			(s4_reg_b_data_out),
		.s4_reg_write_address_out	(s4_reg_write_address_out),
		.s4_restore					(restore),
		.s4_save					(save),
		.s4_skp0					(skp0),
		.s4_skp1					(skp1),
		.s4_skprnz					(skprnz),
		.s4_skprz					(skprz),
		.s4_skps					(skps),
		.s4_st						(st),
		.s4_trap					(trap),
		.s4_tret					(tret)
	);

	pipeline_stage_4 the_pipeline_stage_4(
		// inputs
		.clk						(clk),
		.cpu_continue_running		(cpu_continue_running),
		.ctrl_en					(ctrl_en),
		.ctrl_reg_address			(s4_ctrl_reg_address),
		.ctrl_reg_sync_address		(s3_ctrl_reg_address),
		.d_irqnumber				(d_irqnumber),
		.d_readdata					(d_readdata),
		.decoded_instr				(s4_decoded_instr),
		.decrement_cwp				(decrement_cwp),
		.disable_interrupts			(disable_interrupts),
		.force_interrupt			(force_interrupt),
		.in_to_ctrl_regs			(s4_reg_a_data_out),
		.increment_cwp				(increment_cwp),
		.interrupt					(interrupt),
		.ir							(s4_ir),
		.mux_a_data_out				(s4_mux_a_data_out),
		.mux_b_data_out				(s4_mux_b_data_out),
		.next_is_restore			(next_is_restore),
		.next_is_save				(next_is_save),
		.next_is_trap				(next_is_trap),
		.npc 						(s4_npc),
		.pc							(s4_pc),
		.pc_plus_4					(s4_pc_plus_4),
		.reset_n					(reset_n),
		.restore					(restore),
		.s4_trap					(trap),
		.s4_tret					(tret),
		.save						(save),
		.save_status				(save_status),
		.skip						(skip),

		// outputs
		.cwp						(cwp),
		.cwp_for_check				(cwp_for_check),
		.cwp_minus_1				(cwp_minus_1),
		.d_address					(d_address),
		.reg_data_in				(current_reg_data_in),
		.status_reg					(status_reg),
		.wvalid_for_check			(wvalid_for_check)
 	);
	defparam the_pipeline_stage_4.LOG_REGISTER_FILE_SIZE = LOG_REGISTER_FILE_SIZE;
endmodule
//datapath*******************************************************************

//***************************************************************************
// Stage 1 (Fetch) Modules
//***************************************************************************
//***************************************************************************
//	prefetch_unit
//
//	Module prefetch_unit implements the prefetch unit
//
module prefetch_unit (
	// inputs
	clk,
	cpu_s_read_address,
	cpu_wants_to_read,
	d_irqnumber,
	data_in_from_memory,
	data_is_valid_from_memory,
	flush_fifo,
	flush_pipeline,
	force_interrupt,
	force_trap_1,
	force_trap_2,
	load_nops,
	memory_requests_wait,
	reset_n,

	// outputs
	data_out_to_cpu,
	flush_memory,
	memory_address_to_read,
	prefetch_unit_has_valid_data,
	read_memory
	);
	parameter START_ADDRESS = 32'b0;
	parameter FIFO_SIZE = 2;
	
	input			clk;
	input [31:0] 	cpu_s_read_address;
	input			cpu_wants_to_read;
	input [5:0]		d_irqnumber;
	input [15:0]	data_in_from_memory;
	input			data_is_valid_from_memory;
	input			flush_fifo;
	input			flush_pipeline;
	input			force_interrupt;
	input			force_trap_1;
	input			force_trap_2;
	input			load_nops;
	input			memory_requests_wait;
	input			reset_n;

	output [15:0]	data_out_to_cpu;
	output			flush_memory;
	output [31:0]	memory_address_to_read;
	output			prefetch_unit_has_valid_data;
	output			read_memory;

	wire [15:0]	data_from_fifo;
	wire		flush_memory;
	wire [15:0]	instruction;
	wire		is_empty;
	wire		is_almost_full;
	wire		is_full;
	wire		read_fifo;
	wire		write_fifo;

	reg		[31:0]	prefetch_pc;


	// Instruction to be forwarded to the decode stage is one of the TRAP instructions,
	// NOP, or the actual instruction coming from memory
	assign data_out_to_cpu = force_interrupt ?  {10'b0111100100, d_irqnumber} : //TRAP d_irqnumber
							force_trap_1 ? 16'b0111100100000001 : //TRAP 1
							force_trap_2 ? 16'b0111100100000010 : //TRAP 2
							(flush_pipeline | load_nops) ? 16'h3000 : //NOP
							instruction;
	// Flush any pending reads when the FIFO is flushed
	assign flush_memory = flush_fifo | ~reset_n;
	// If the FIFO buffer is empty, the instruction being fetched from the instruction memory
	// is forwarded immediately to the decode stage. Otherwise, the instruction from FIFO is
	// forwarded. The decode stage is referred to as the CPU
	assign instruction = (is_empty) ? data_in_from_memory : data_from_fifo;
	assign memory_address_to_read = prefetch_pc;
	// Prefetch unit has valid data (instruction) ready if the FIFO buffer is not empty,
	// or the memory has the data ready.
	assign prefetch_unit_has_valid_data = ~is_empty | data_is_valid_from_memory;
	// Memory reads shouldn't be issued when the FIFO is being flushed, because the t

⌨️ 快捷键说明

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