OpenCores
URL https://opencores.org/ocsvn/openarty/openarty/trunk

Subversion Repositories openarty

[/] [openarty/] [trunk/] [rtl/] [cpu/] [ifastdec.v] - Rev 20

Go to most recent revision | Compare with Previous | Blame | View Log

///////////////////////////////////////////////////////////////////////////////
//
// Filename:	ifastdec.v
//
// Project:	Zip CPU -- a small, lightweight, RISC CPU soft core
//
// Purpose:	This RTL file specifies how instructions are to be decoded
//		into their underlying meanings.  It is different from the
//	standard idecode.v file in that this one takes two clocks, and is
//	pipelined.  This one is designed for a 5ns clock cycle, hence it is
//	a "fast" decoder--even though the old decoder took one cycle in 10ns.
//	From that standpoint, the two may well be ... comparable in speed.
//
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Technology, LLC
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// License:	GPL, v3, as defined and found on www.gnu.org,
//		http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////////
//
//
//
`define	CPU_CC_REG	4'he
`define	CPU_PC_REG	4'hf
//
`include "cpudefs.v"
//
//
//
module	ifastdec(i_clk, i_rst, i_ce, i_stalled,
		i_instruction, i_gie, i_pc, i_pf_valid,
			i_illegal,
		o_phase, o_illegal,
		o_pc, o_gie,
		o_R, o_A, o_B, o_I, o_zI,
		o_cond, o_wF,
		o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
		o_wR, o_rA, o_rB,
		o_early_branch, o_branch_pc, o_ljmp,
		o_pipe
		);
	parameter	ADDRESS_WIDTH=24, IMPLEMENT_MPY=1, EARLY_BRANCHING=1,
			IMPLEMENT_DIVIDE=1, IMPLEMENT_FPU=0, AW = ADDRESS_WIDTH;
	input			i_clk, i_rst, i_ce, i_stalled;
	input	[31:0]		i_instruction;
	input			i_gie;
	input	[(AW-1):0]	i_pc;
	input			i_pf_valid, i_illegal;
	output	reg		o_phase;
	output	reg		o_illegal;
	output	reg	[(AW-1):0]	o_pc;
	output	reg		o_gie;
	output	reg	[6:0]	o_R, o_A, o_B;
	output	reg	[31:0]	o_I;
	output	reg		o_zI;
	output	reg	[3:0]	o_cond;
	output	reg		o_wF;
	output	reg	[3:0]	o_op;
	output	reg		o_ALU, o_M, o_DV, o_FP, o_break;
	output	reg		o_lock;
	output	reg		o_wR, o_rA, o_rB;
	output	reg		o_early_branch;
	output	reg	[(AW-1):0]	o_branch_pc;
	output	reg		o_ljmp;
	output	reg		o_pipe;
 
 
	//////
	//
	//	Path 1: Full size instruction
	//
	//	Prefix: wf	(wire, full)
	//
	//////
 
	// The 5-bit opcode, as extracted
	wire	[4:0]	wf_op;
	// Instruction types
	wire		wf_ldi, wf_mov, wf_cmptst, wf_ldilo, wf_brev, wf_noop,
			wf_break, wf_lock,
			wf_ljmp, wf_ALU, wf_MEM, wf_DIV, wf_FPU;
	wire	[4:0]	wf_R, wf_A, wf_B;	// Instruction registers
	wire	[3:0]	wf_cond;
	wire		wf_wF; // Write flags?
	wire		wf_wR_n,	// Write destination register? or not?
			wf_rA, // Read register A?
			wf_rB;	// Read register B?
	wire	[22:0]	wf_pI; // Partial immediate ...
	wire		wf_Iz;
 
	assign	wf_op	= i_instruction[26:22];
	assign	wf_brev	= (wf_op      == 5'hc);
	assign	wf_mov	= (wf_op      == 5'h0f);
	assign	wf_ldi	= (wf_op[4:1] == 4'hb);
	assign	wf_cmptst=(wf_op[4:1] == 4'h8);
	assign	wf_ldilo= (wf_op[4:0] == 5'h9);
	assign	wf_noop	= (wf_op[4:0] == 5'h18)&&(wf_R[3:1] == 3'h7);
	assign	wf_break= (wf_op[4:0] == 5'h19)&&(wf_R[3:1] == 3'h7);
	assign	wf_lock	= (wf_op[4:0] == 5'h1a)&&(wf_R[3:1] == 3'h7);
	//
	assign	wf_R	= { (wf_mov)&&(i_gie)?i_instruction[18]:i_gie, (i_instruction[30:27]) };
	assign	wf_A	= { (wf_mov)&&(i_gie)?i_instruction[18]:i_gie, (i_instruction[30:27]) };
	assign	wf_B	= { (wf_mov)&&(i_gie)?i_instruction[13]:i_gie, (i_instruction[17:14]) };
	//
	assign	wf_ALU	= (~wf_op[4]);
	assign	wf_MEM	= ( wf_op[4:1] == 4'h9);
	assign	wf_DIV	= ( wf_op[4:1] == 4'ha);
	assign	wf_FPU	= ( wf_op[4:2] == 3'h7)&&(i_instruction[30:28]==3'h7);
	assign	wf_ljmp = (i_instruction == 32'h7c87c000);
 
	assign	wf_pI = (wf_ldi) ? { i_instruction[22:0] } // LDI
			:((wf_mov) ?{ {(23-13){i_instruction[12]}}, i_instruction[12:0] } // Move
			:((~i_instruction[18]) ? { {(23-18){i_instruction[17]}}, i_instruction[17:0] }
			: { {(23-14){i_instruction[13]}}, i_instruction[13:0] }
			));
	assign	wf_Iz= (wf_pI == 23'h00);
 
	// Will we be writing register R?
	assign	wf_wR_n   = ((wf_MEM)&&(wf_op[0])) // Store's dont write regs
				// Neither do NOOP, BREAK, or LOCKs
				||((wf_op[4:3]==2'b11)&&(wf_R[3:1]==3'h7))
				// nor CMPs and TSTs
				||(wf_cmptst);
	// Do we read register 'A'?
	assign	wf_rA = (wf_FPU)&&(wf_op[4:1]!=4'he) // FPU, but not CVT or INT
				||(wf_DIV)
				||(wf_ALU)&&(~wf_mov)
				||(wf_MEM)&&(wf_op[0])
				||(wf_cmptst);
		// Do we need to read register 'B'?
	assign	wf_rB = (wf_mov)||((i_instruction[18])&&(~wf_ldi));
 
	// What are the conditions for this instruction?  NOOP, BREAK, and LOCK
	// are also unconditional, but they'll just ignore this setting
	assign	wf_cond = (wf_ldi) ? 4'h8 // LDI is unconditional
			: { (i_instruction[21:19]==3'h0), i_instruction[21:19] };
	// How about the flags, will we be writing them?
	assign	wf_wF     = (wf_cmptst) // Compares always write flags
			||((wf_cond[3])&&(
				// FPU and DIV instructions always write flags
				(wf_FPU)||(wf_DIV)
				// So do ALU instructions, UNLESS the ALU 
				// instruction is a MOV, LDILO, or BREV, or
				// the results are being written into the PC
				// or CC register--those don't set flags
				||((wf_ALU)&&(~wf_mov)&&(~wf_ldilo)&&(~wf_brev)
					&&(i_instruction[30:28] != 3'h7))));
 
	reg	[3:0]	rf_op;
	reg		rf_break, rf_lock;
	reg	[4:0]	rf_R, rf_A, rf_B;
	reg		rf_ALU, rf_MEM, rf_DIV, rf_FPU, rf_ljmp;
	reg	[3:0]	rf_cond;
	reg		rf_rA, rf_rB, rf_wR, rf_wF;
 
	reg	[22:0]	rf_pI;
	reg		rf_Iz;
	wire	[31:0]	wf_I;
	assign	wf_I = { {(32-22){rf_pI[22]}}, rf_pI[21:0] };
 
	reg			rf_early_branch;
	reg	[(AW-1):0]	rf_branch_pc;
	always @(posedge i_clk)
	if (i_ce)
	begin
		rf_op <= wf_op[3:0];
		rf_break<= wf_break;
		rf_lock	<= wf_lock;
	//
		rf_R	<= (wf_R);
		rf_A	<= (wf_A);
		rf_B	<= (wf_B);
	//
		rf_ALU	<= (~wf_op[4]);
		rf_MEM	<= ( wf_op[4:1] == 4'h9);
		rf_DIV	<= ( wf_op[4:1] == 4'ha);
		rf_FPU	<= ( wf_op[4:2] == 3'h7)&&(i_instruction[30:28]==3'h7);
		rf_ljmp <= (i_instruction == 32'h7c87c000);
 
		rf_pI <= wf_pI;
		rf_Iz<= wf_Iz;
 
		// What are the conditions of this instruction?
		rf_cond <= wf_cond;
 
		// Do we read register 'A'?
		rf_rA <= wf_rA;
		// Do we need to read register 'B'?
		rf_rB <= wf_rB;
		// Will we be writing register 'R'?
		rf_wR <= ~wf_wR_n;
		// How about the flags, will we be writing those?
		rf_wF <= wf_wF;
 
		//
		rf_early_branch <=
			// PC is the result
			(wf_R[3:0]==4'hf)
			// Unconditional instruction
			&&(i_instruction[21:19]==3'h0)
			&&
				// Either an ADD #x,PC
				((wf_op == 5'h02)&&(~i_instruction[18])
				// Or a LOD #x,PC
				||(wf_ldi));
		rf_branch_pc <= (wf_ldi)?{{(AW-22){wf_pI[22]}},wf_pI[21:0]}
				:(i_pc + {{(AW-18){i_instruction[17]}},
					i_instruction[16:0]});
	end
 
	//////
	//
	//	Path 2: Half size instruction, high half
	//
	//	Prefix: wh	(wire, high-half)
	//
	//////
 
	// The 5-bit opcode, as extracted -- same as wf_
	// Instruction types -- same as wf_
	wire	[4:0]	wh_R, wh_A, wh_B;	// Instruction registers
	wire	[3:0]	wh_cond;
	wire		wh_wF; // Write flags?
	wire		wh_wR, wh_wR_n,	// Write destination register? or not?
			wh_rA, // Read register A?
			wh_rB;	// Read register B?
	wire	[4:0]	wh_pI; // Partial immediate ...
	wire		wh_Iz;
 
	assign	wh_R	= { i_gie, (i_instruction[30:27]) };
	assign	wh_A	= { i_gie, (i_instruction[30:27]) };
	assign	wh_B	= { i_gie, (i_instruction[17:14]) };
	//
 
	assign	wh_pI = (wf_ldi) ? { i_instruction[18:14] } // LDI
			:((~i_instruction[18])
				? { i_instruction[17], i_instruction[17:14] }
				: 5'h0);
	assign	wh_Iz= (wh_pI == 5'h0);
 
	// Will we be writing register R?
	assign	wh_wR_n   = ((wf_MEM)&&(wf_op[0])) // Store's dont write regs
				// Neither do NOOP, BREAK, or LOCKs
				||((wf_op[4:3]==2'b11)&&(wh_R[3:1]==3'h7))
				// nor CMPs and TSTs
				||(wf_cmptst);
 
	assign	wh_cond = (wf_ldi) ? 4'h8 // LDI is unconditional
			: { (i_instruction[20:19]==2'h0), 1'b0, i_instruction[20:19] };
	// How about the flags, will we be writing them?
	assign	wh_wF     = (wf_cmptst) // Compares always write flags
			||((wh_cond[3])&&(
				// FPU and DIV instructions always write flags
				(wf_FPU)||(wf_DIV)
				// So do ALU instructions, UNLESS the ALU 
				// instruction is a MOV, LDILO, or BREV, or
				// the results are being written into the PC
				// or CC register--those don't set flags
				||((wf_ALU)&&(~wf_mov)&&(~wf_ldilo)&&(~wf_brev)
					&&(i_instruction[30:28] != 3'h7))));
 
	reg	[3:0]	rh_op;
	reg		rh_break, rh_lock;
	reg	[4:0]	rh_R, rh_A, rh_B;
	reg		rh_ALU, rh_MEM, rh_DIV, rh_FPU;
	reg	[3:0]	rh_cond;
	reg		rh_rA, rh_rB, rh_wR, rh_wF;
	wire	[31:0]	wh_I;
	reg	[4:0]	rh_pI;
	reg		rh_Iz;
	assign	wh_I = { {(32-4){rh_pI[4]}}, rh_pI[3:0] };
	always @(posedge i_clk)
	if (i_ce)
	begin
		rh_op <= wf_op[3:0];
		rh_break<= wf_break;
		rh_lock	<= wf_lock;
	//
		rh_R	<= (wh_R);
		rh_A	<= (wh_A);
		rh_B	<= (wh_B);
	//
		rh_ALU	<= wf_ALU;
		rh_MEM	<= wf_MEM;
		rh_DIV	<= wf_DIV;
		rh_FPU	<= wf_FPU;
 
		rh_pI <= wh_pI;
		rh_Iz <= wh_Iz;
 
		// What are the conditions of this instruction?
		rh_cond <= wh_cond;
 
		// Do we read register 'A'?
		rh_rA <= (wf_FPU)&&(wf_op[4:1]!=4'he)
				||(wf_DIV)
				||(wf_ALU)&&(~wf_mov)
				||(wf_MEM)&&(wf_op[0])
				||(wf_cmptst);
		// Do we need to read register 'B'?
		rh_rB <= (i_instruction[18])&&(~wf_ldi);
		// Will we be writing register 'R'?
		rh_wR <= ~wh_wR_n;
		rh_wF <= wh_wF;
	end
 
 
	//////
	//
	//	Path 3: Half size instruction, low half
	//
	//////
 
	// The 5-bit opcode, as extracted
	wire	[4:0]	wl_op;
	// Instruction types
	wire		wl_ldi, wl_mov, wl_cmptst, wl_ldilo, wl_brev, wl_noop,
			wl_break, wl_lock,
			wl_ljmp, wl_ALU, wl_MEM, wl_DIV, wl_FPU;
	wire	[4:0]	wl_R, wl_A, wl_B;	// Instruction registers
	wire	[3:0]	wl_cond;
	wire		wl_wF; // Write flags?
	wire		wl_wR, wl_wR_n,	// Write destination register? or not?
			wl_rA, // Read register A?
			wl_rB;	// Read register B?
	wire	[4:0]	wl_pI; // Partial immediate ...
	wire		wl_Iz;
 
	assign	wl_op	= i_instruction[9:5];
	assign	wl_brev	= (wl_op      == 5'hc);
	assign	wl_mov	= (wl_op      == 5'h0f);
	assign	wl_ldi	= (wl_op[4:1] == 4'hb);
	assign	wl_cmptst=(wl_op[4:1] == 4'h8);
	assign	wl_ldilo= (wl_op[4:0] == 5'h9);
	assign	wl_noop	= (wl_op[4:0] == 5'h18)&&(wl_R[3:1] == 3'h7);
	assign	wl_break= (wl_op[4:0] == 5'h19)&&(wl_R[3:1] == 3'h7);
	assign	wl_lock	= (wl_op[4:0] == 5'h1a)&&(wl_R[3:1] == 3'h7);
	//
	assign	wl_R	= { i_gie, i_instruction[13:10] };
	assign	wl_A	= { i_gie, i_instruction[13:10] };
	assign	wl_B	= { i_gie, i_instruction[ 3: 0] };
	//
	assign	wl_ALU	= (~wl_op[4]);
	assign	wl_MEM	= ( wl_op[4:1] == 4'h9);
	assign	wl_DIV	= ( wl_op[4:1] == 4'ha);
	assign	wl_FPU	= ( wl_op[4:2] == 3'h7)&&(i_instruction[30:28]==3'h7);
	assign	wl_ljmp = ( i_instruction[21:19] == 3'h00) // 1111_10010_1_1111
				&&(i_instruction[13:0]==14'h3e5f);
 
	assign	wl_pI = (wl_ldi) ? { i_instruction[4:0] } // LDI
			:((~i_instruction[4])
				? { i_instruction[3], i_instruction[3:0] }
				: 5'h0);
	assign	wl_Iz= (wl_pI == 5'h0);
 
	// Will we be writing register R?
	assign	wl_wR_n   = ((wl_MEM)&&(wl_op[0])) // Store's dont write regs
				// Neither do NOOP, BREAK, or LOCKs
				||((wl_op[4:3]==2'b11)&&(wl_R[3:1]==3'h7))
				// nor CMPs and TSTs
				||(wl_cmptst);
 
	// What are the conditions for this instruction?  NOOP, BREAK, and LOCK
	// are also unconditional, but they'll just ignore this setting
	assign	wl_cond = (wl_ldi) ? 4'h8 // LDI is unconditional
			: { (i_instruction[20:19]==2'h0),
					1'b0, i_instruction[20:19] };
	// How about the flags, will we be writing them?
	assign	wl_wF     = (wl_cmptst) // Compares always write flags
			||((wl_cond[3])&&(
				// FPU and DIV instructions always write flags
				(wl_FPU)||(wl_DIV)
				// So do ALU instructions, UNLESS the ALU 
				// instruction is a MOV, LDILO, or BREV, or
				// the results are being written into the PC
				// or CC register--those don't set flags
				||((wl_ALU)&&(~wl_mov)&&(~wl_ldilo)&&(~wl_brev)
					&&(i_instruction[13:11] != 3'h7))));
 
	reg	[3:0]	rl_op;
	reg		rl_break, rl_lock;
	reg	[4:0]	rl_R, rl_A, rl_B;
	reg		rl_ALU, rl_MEM, rl_DIV, rl_FPU, rl_ljmp;
	reg	[3:0]	rl_cond;
	reg		rl_rA, rl_rB, rl_wR, rl_wF;
	wire	[31:0]	wl_I;
	reg	[4:0]	rl_pI;
	reg		rl_Iz;
	assign	wl_I = { {(32-4){rl_pI[4]}}, rl_pI[3:0] };
	always @(posedge i_clk)
	if (i_ce)
	begin
		rl_op <= wl_op[3:0];
		rl_break<= wl_break;
		rl_lock	<= wl_lock;
	//
		rl_R	<= (wl_R);
		rl_A	<= (wl_A);
		rl_B	<= (wl_B);
	//
		rl_ALU	<= (~wl_op[4]);
		rl_MEM	<= ( wl_op[4:1] == 4'h9);
		rl_DIV	<= ( wl_op[4:1] == 4'ha);
		rl_FPU	<= ( wl_op[4:2] == 3'h7)&&(i_instruction[30:28]==3'h7);
		rl_ljmp <= wl_ljmp;
 
		rl_pI <= wl_pI;
		rl_Iz<= wl_Iz;
 
		// What are the conditions of this instruction?
		rl_cond <= wl_cond;
 
		// Do we read register 'A'?
		rl_rA <= (wl_FPU)&&(wl_op[4:1]!=4'he)
				||(wl_DIV)
				||(wl_ALU)&&(~wf_mov)
				||(wl_MEM)&&(wl_op[0])
				||(wl_cmptst);
		// Do we need to read register 'B'?
		rl_rB <= (i_instruction[18])&&(~wl_ldi);
		// Will we be writing register 'R'?
		rl_wR <= ~wl_wR_n;
		// How about the flags?
		rl_wF <= wl_wF;
	end
 
	//////
	//
	//	Path 4: triplet instruction:	MOV A,B; OP C,B
	//		becomes 		OP C,A -> B
	//
	//////
	wire	w_triplet;
	reg	r_triplet;
	assign	w_triplet =
			// Must be a VLIW instruction
			(i_instruction[31])
			// First half must be a move
			&&(i_instruction[26:22] == 5'h0f)
			// Move destination must also be register A in 2nd Op
			&&(i_instruction[30:27]==i_instruction[13:10])
			// Only if this is unconditional, or share conditions
			&&((i_instruction[21])|(i_instruction[20:19]==2'h0))
			// Not if the destination is PC or CC regs
			&&(i_instruction[30:28]!=3'h7);
	always @(posedge i_clk)
		if (i_ce)
			r_triplet <= w_triplet;
 
	// Now, let's string our instruction(s) together to create a useful
	// decoded instruction
	reg	r_singlet, r_gie;
	reg	[(AW-1):0]	r_pc;
	always @(posedge i_clk)
	if (i_ce)
	begin
		r_gie <= i_gie;
		o_gie<= r_gie;
		r_singlet <= ~i_instruction[31];
		r_pc <= i_pc;
 
		if (r_triplet)
		begin
			o_phase <= 1'b0;
			o_pc <= r_pc + {{(AW-1){1'b0}}, 1'b1};
			o_lock <= 1'b0;
			o_break <= 1'b0;
			o_R<={(rl_R=={r_gie, 4'he }),(rl_R=={r_gie,4'hf}),rl_R};
			o_A<={(rh_B=={r_gie, 4'he }),(rh_B=={r_gie,4'hf}),rh_B};
			o_B<={(rl_B=={r_gie, 4'he }),(rl_B=={r_gie,4'hf}),rl_B};
			o_wR <= rl_wR;
			o_rA <= 1'b1;
			o_rB <= rl_rB;
			o_cond<= rh_cond;
			o_wF <= rl_wF;
			o_I  <= wl_I;
			o_zI <= rl_Iz;
			o_op <= rl_op;
			o_ALU<= rl_ALU;
			o_M<= rl_MEM;
			o_DV<= rl_DIV;
			o_FP <= rl_FPU;
			o_ljmp <= 1'b0;
			o_early_branch <= 1'b0;
			o_branch_pc <= 0;
			// o_pipe will never be true for a triplet
		end else if (r_singlet)
		begin
			o_phase <= 1'b0;
			o_pc <= r_pc + {{(AW-1){1'b0}}, 1'b1};
			o_R<={(rf_R=={r_gie, 4'he }),(rf_R=={r_gie,4'hf}),rf_R};
			o_A<={(rf_A=={r_gie, 4'he }),(rf_A=={r_gie,4'hf}),rf_A};
			o_B<={(rf_B=={r_gie, 4'he }),(rf_B=={r_gie,4'hf}),rf_B};
			o_break <= rf_break;
			o_lock <= rf_lock;
			o_wR <= rf_wR;
			o_rA <= rf_rA;
			o_rB <= rf_rB;
			o_cond<= rf_cond;
			o_wF <= rf_wF;
			o_I  <= wf_I;
			o_zI <= rf_Iz;
			o_op <= rf_op;
			o_ALU<= rf_ALU;
			o_M<= rf_MEM;
			o_DV<= rf_DIV;
			o_FP <= rf_FPU;
			o_ljmp <= rf_ljmp;
			o_early_branch <= (rf_ljmp);
			o_branch_pc <= i_instruction[(AW-1):0];
		end else if (~o_phase)
		begin
			o_phase <= 1'b1;
			o_pc <= r_pc;
			o_R<={(rh_R=={r_gie, 4'he }),(rh_R=={r_gie,4'hf}),rh_R};
			o_A<={(rh_A=={r_gie, 4'he }),(rh_A=={r_gie,4'hf}),rh_A};
			o_B<={(rh_B=={r_gie, 4'he }),(rh_B=={r_gie,4'hf}),rh_B};
			o_lock <= rh_lock;
			o_break <= rh_break;
			o_wR <= rh_wR;
			o_rA <= rh_rA;
			o_rB <= rh_rB;
			o_cond<= rh_cond;
			o_wF <= rh_wF;
			o_I  <= wh_I;
			o_zI <= rh_Iz;
			o_op <= rh_op;
			o_ALU<= rh_ALU;
			o_M<= rh_MEM;
			o_DV<= rh_DIV;
			o_FP <= rh_FPU;
			o_ljmp <= 1'b0; // Can't jump from high-half
			o_early_branch <= 1'b0;
			// o_branch_pc <= i_instruction;
		end else begin
			o_phase <= 1'b0;
			o_pc <= r_pc + {{(AW-1){1'b0}}, 1'b1};
			o_lock <= rl_lock;
			o_break <= rl_break;
			o_R<={(rl_R=={r_gie, 4'he }),(rl_R=={r_gie,4'hf}),rl_R};
			o_A<={(rl_A=={r_gie, 4'he }),(rl_A=={r_gie,4'hf}),rl_A};
			o_B<={(rl_B=={r_gie, 4'he }),(rl_B=={r_gie,4'hf}),rl_B};
			o_wR <= rl_wR;
			o_rA <= rl_rA;
			o_rB <= rl_rB;
			o_cond<= rl_cond;
			o_wF <= rl_wF;
			o_I  <= wl_I;
			o_zI <= rl_Iz;
			o_op <= rl_op;
			o_ALU<= rl_ALU;
			o_M<= rl_MEM;
			o_DV<= rl_DIV;
			o_FP <= rl_FPU;
			o_ljmp <= rl_ljmp;
			o_early_branch <= 1'b0;
			o_branch_pc <= i_instruction[(AW-1):0];
		end
		o_illegal <= 1'b0;
	end
 
	/*
	always @(posedge i_clk)
	begin
		pipe_M  <= { o_M, o_op[0] };
		pipe_I  <= o_I;
		pipe_pI  <= o_I+1;
		pipe_B <= o_B[3:0];
		pipe_rB<= o_rB;
		pipe_AB <= ({ o_A[6:5], o_B[6:5] } == 4'h00) // 12 inputs
				&&(o_A[3:0] != o_B[3:0]);
		pipe_gie<= o_gie;
 
		// 36 bits (18*2)
		match_sI <= (pipe_I == o_I);
		// 36 bits
		match_pI <= (pipe_pI == o_I);
		// 9 bits
		match_regs <= (pipe_M[1])&&(pipe_M == { o_M, o_op[0] })
				&&((~pipe_rB)||(pipe_B == o_B[3:0]));
		// 9 inputs
		match_cnd <= ((pipe_cnd == o_cond)||(o_cond[3]));
		// 5 inputs
		match_aux <= (pipe_gie == o_gie)&&(pipeAB)&&(pipe_rB==o_rB)
 
		o_pipe <= ((match_sI)||(match_pI))&&(match_regs)&&(match_cnd)
				&&(match_aux)&&(pipe_AB);
	end
	*/
 
	/*
	always @(posedge i_clk)
		if (i_rst)
			r_valid <= 1'b0;
		else if ((i_ce)&&(o_ljmp))
			r_valid <= 1'b0;
		else if ((i_ce)&&(i_pf_valid))
			r_valid <= 1'b1;
		else if (~i_stalled)
			r_valid <= 1'b0;
	*/
 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.